Files
super6502/hw/efinix_fpga/ip/uart/uart.v
Byron Lathi 21e3a477c1 Update IP
2023-07-19 21:06:20 -07:00

1169 lines
35 KiB
Verilog

// =============================================================================
// Generated by efx_ipmgr
// Version: 2023.1.150
// IP Version: 5.0
// =============================================================================
////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2013-2023 Efinix Inc. All rights reserved.
//
// This document contains proprietary information which is
// protected by copyright. All rights are reserved. This notice
// refers to original work by Efinix, Inc. which may be derivitive
// of other work distributed under license of the authors. In the
// case of derivative work, nothing in this notice overrides the
// original author's license agreement. Where applicable, the
// original license agreement is included in it's original
// unmodified form immediately below this header.
//
// WARRANTY DISCLAIMER.
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
//
// LIMITATION OF LIABILITY.
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
// APPLY TO LICENSEE.
//
////////////////////////////////////////////////////////////////////////////////
`define IP_UUID _d1961caf8b8d4ca092806671a99095c2
`define IP_NAME_CONCAT(a,b) a``b
`define IP_MODULE_NAME(name) `IP_NAME_CONCAT(name,`IP_UUID)
module uart (
output tx_o,
input rx_i,
output tx_busy,
output [7:0] rx_data,
output rx_data_valid,
output rx_error,
output rx_parity_error,
output rx_busy,
output baud_x16_ce,
input clk,
input reset,
input [2:0] baud_rate,
input tx_en,
input [7:0] tx_data
);
`IP_MODULE_NAME(top_uart) #(
.BYTE (1),
.CLOCK_FREQ (50000000),
.BAUD (115200),
.ENABLE_PARITY (1'b0),
.FIX_BAUDRATE (1'b1),
.PARITY_MODE (1'b0),
.BOOTUP_CHECK (1'b1)
) u_top_uart(
.tx_o ( tx_o ),
.rx_i ( rx_i ),
.tx_busy ( tx_busy ),
.rx_data ( rx_data ),
.rx_data_valid ( rx_data_valid ),
.rx_error ( rx_error ),
.rx_parity_error ( rx_parity_error ),
.rx_busy ( rx_busy ),
.baud_x16_ce ( baud_x16_ce ),
.clk ( clk ),
.reset ( reset ),
.baud_rate ( baud_rate ),
.tx_en ( tx_en ),
.tx_data ( tx_data )
);
endmodule
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
//
// baud_generator.v
//
// Description:
// Baud Generator generates up to 115.2KHz baud rate.
// common Baud Rate - 4800/9600/19200/57600/115200Hz
//
// *******************************
// Revisions:
// 1.0 Initial rev
//
// *******************************
/////////////////////////////////////////////////////////////////////////////
`resetall
`timescale 1ns/10ps
module `IP_MODULE_NAME(baud_generator)
#(parameter CLOCK_FREQ = 50000000,
FIX_BAUDRATE = 1,
BAUD = 115200)
(
output wire baud_ce,
output wire baud_x16_ce,
//inputs
input clk,
input [2:0] baud_rate,
input reset
);
//Baud Rate Calculation
parameter BAUD_GEN_ACC_WIDTH = 16;
localparam [BAUD_GEN_ACC_WIDTH-1:0] BAUD_GEN_INC = CLOCK_FREQ/BAUD;
localparam [BAUD_GEN_ACC_WIDTH-1:0] BAUD_GEN_INC_X16 = (CLOCK_FREQ/BAUD) >> 4;
localparam BAUD_GEN_INC_0 = CLOCK_FREQ/115200;
localparam BAUD_GEN_INC_1 = CLOCK_FREQ/57600;
localparam BAUD_GEN_INC_2 = CLOCK_FREQ/38400;
localparam BAUD_GEN_INC_3 = CLOCK_FREQ/19200;
localparam BAUD_GEN_INC_4 = CLOCK_FREQ/9600;
localparam BAUD_GEN_INC_5 = CLOCK_FREQ/4800;
localparam BAUD_GEN_INC_6 = CLOCK_FREQ/2400;
localparam BAUD_GEN_INC_7 = CLOCK_FREQ/1200;
//internal registers
reg [BAUD_GEN_ACC_WIDTH:0] baud_cnt ;
reg [BAUD_GEN_ACC_WIDTH:0] baud_cnt_x16 ;
//Baud Rate <1%.
always @(posedge clk) begin
if (reset) begin
baud_cnt <= 'h0;
end
else begin
if(baud_ce) begin
baud_cnt <= 'h0;
end
else begin
baud_cnt <= baud_cnt[BAUD_GEN_ACC_WIDTH-1:0] + 1'b1;
end
end
end
always @(posedge clk) begin
if (reset) begin
baud_cnt_x16 <= 'h0;
end
else begin
if(baud_ce || baud_x16_ce) begin
baud_cnt_x16 <= 'h0;
end
else begin
baud_cnt_x16 <= baud_cnt_x16[BAUD_GEN_ACC_WIDTH-1:0] + 1'b1;
end
end
end
generate if (FIX_BAUDRATE) begin
assign baud_ce = (baud_cnt == BAUD_GEN_INC-1'b1);
assign baud_x16_ce = (baud_cnt_x16 == BAUD_GEN_INC_X16 - 1'b1);
end
else begin
assign baud_ce = (baud_rate == 1) ? (baud_cnt == BAUD_GEN_INC_1-1'b1) :
(baud_rate == 2) ? (baud_cnt == BAUD_GEN_INC_2-1'b1) :
(baud_rate == 3) ? (baud_cnt == BAUD_GEN_INC_3-1'b1) :
(baud_rate == 4) ? (baud_cnt == BAUD_GEN_INC_4-1'b1) :
(baud_rate == 5) ? (baud_cnt == BAUD_GEN_INC_5-1'b1) :
(baud_rate == 6) ? (baud_cnt == BAUD_GEN_INC_6-1'b1) :
(baud_rate == 7) ? (baud_cnt == BAUD_GEN_INC_7-1'b1) :
(baud_cnt == BAUD_GEN_INC_0-1'b1);
assign baud_x16_ce = (baud_rate == 1) ? (baud_cnt_x16 == (BAUD_GEN_INC_1 >> 4)-1'b1) :
(baud_rate == 2) ? (baud_cnt_x16 == (BAUD_GEN_INC_2 >> 4)-1'b1) :
(baud_rate == 3) ? (baud_cnt_x16 == (BAUD_GEN_INC_3 >> 4)-1'b1) :
(baud_rate == 4) ? (baud_cnt_x16 == (BAUD_GEN_INC_4 >> 4)-1'b1) :
(baud_rate == 5) ? (baud_cnt_x16 == (BAUD_GEN_INC_5 >> 4)-1'b1) :
(baud_rate == 6) ? (baud_cnt_x16 == (BAUD_GEN_INC_6 >> 4)-1'b1) :
(baud_rate == 7) ? (baud_cnt_x16 == (BAUD_GEN_INC_7 >> 4)-1'b1) :
(baud_cnt_x16 == (BAUD_GEN_INC_0 >> 4)-1'b1);
end
endgenerate
endmodule
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
//
// This document contains proprietary information which is
// protected by copyright. All rights are reserved. This notice
// refers to original work by Efinix, Inc. which may be derivitive
// of other work distributed under license of the authors. In the
// case of derivative work, nothing in this notice overrides the
// original author's license agreement. Where applicable, the
// original license agreement is included in it's original
// unmodified form immediately below this header.
//
// WARRANTY DISCLAIMER.
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
//
// LIMITATION OF LIABILITY.
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
// APPLY TO LICENSEE.
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
//
// receiver.v
//
// Description:
// process the RX data from UART Peripherals
//
// *******************************
// Revisions:
// 1.0 Initial rev
//
// *******************************
/////////////////////////////////////////////////////////////////////////////
`resetall
`timescale 1ns/10ps
module `IP_MODULE_NAME(receiver)
#( parameter PARITY_MODE = 0)
(
//outputs
output wire [7:0] data_1_byte, //One bye of data.
output reg valid, //Valid for data_1_byte.
output reg error, //Framing Error.
output reg parity_error, //Parity Error.
output reg rx_busy, //rx busy
//inputs
input clk, //System Clock.
input reset, //system reset.
input baud_x16_ce, //BaudX16 Enable Signal
input rx_i, //RX data from PC.
input en_parity //Enable Parity
);
//Parameters
localparam IDLE = 0,
START = 1,
DATA = 2,
STOP = 3,
ERROR = 4,
PARITY = 5;
localparam IDLE_ST = 6'b00_0001,
START_ST = 6'b00_0010,
DATA_ST = 6'b00_0100,
STOP_ST = 6'b00_1000,
ERROR_ST = 6'b01_0000,
PARITY_ST = 6'b10_0000;
//internal signals
reg rx_data0,rx_data1,rx_data2;
reg [5:0] present_state,next_state;
reg [3:0] count_x16;
wire start;
reg shift_en;
reg [15:0] shift_rx_data [7:0];
reg load_data;
reg [7:0] parallel_data;
reg count_en;
reg valid_en;
reg [7:0] count_8bit;
integer i;
reg [2:0] rx_data_sync;
reg parity_en;
reg [15:0] parity_data;
wire parity_bit;
wire expected_parity_bit;
//synchronize the rx_i.
always @(posedge clk)
if (reset)
rx_data_sync <= 3'b111;
else
rx_data_sync <= {rx_data_sync[1:0],rx_i};
//synchronize the incoming rx_i...
always @(posedge clk)
if (reset)
begin
rx_data0 <= 1'b1;
rx_data1 <= 1'b1;
rx_data2 <= 1'b1;
end
else if (baud_x16_ce)
begin
rx_data0 <= rx_data_sync[2];
rx_data1 <= rx_data0;
rx_data2 <= rx_data1;
end
assign start = !rx_data1 & rx_data2;
always @(posedge clk)
if (reset)
present_state <= 6'h1;
else if (baud_x16_ce)
present_state <= next_state;
//State Machine for Receiver to process the RXDATA and generate the parallel data...
always @(*)
begin
load_data = 0;
shift_en= 0;
valid_en = 0;
count_en = 0;
parity_en = 0;
case (present_state)
IDLE_ST: begin
if (start)
next_state = START_ST;
else
next_state = IDLE_ST;
end
START_ST: begin
count_en = 1'b1;
if (&count_x16)
next_state = DATA_ST;
else if (rx_data2)
next_state = ERROR_ST;
else
next_state = START_ST;
end
DATA_ST : begin
shift_en = 1'b1;
if (count_8bit[7] && &count_x16)
begin
load_data = 1'b1;
if (en_parity)
next_state = PARITY_ST;
else
next_state= STOP_ST;
end
else
begin
next_state = DATA_ST;
end
end
PARITY_ST : begin
count_en = 1'b1;
parity_en = 1'b1;
if (&count_x16)
begin
next_state = STOP_ST;
end
else
begin
next_state = PARITY_ST;
end
end
STOP_ST : begin
count_en=1'b1;
if (!rx_data1)
next_state = ERROR_ST;
else if (count_8bit[0] & &count_x16)
begin
valid_en = 1'b1;
if (start)
next_state = START_ST;
else
next_state = IDLE_ST;
end
else
begin
next_state = STOP_ST;
end
end // case: present_state[STOP]
ERROR_ST : begin
next_state = IDLE_ST;
end
default: next_state = IDLE_ST;
endcase // case(current_state)
end // always @ (*)
always @(posedge clk)
if (reset)
count_x16 <= 4'b0;
else if (baud_x16_ce)
begin
if (count_en | shift_en)
count_x16 <= count_x16 + 1;
else if (present_state[IDLE])
count_x16 <= 4'h0;
end
always @(posedge clk)
begin
if (reset)
count_8bit <= 8'h01;
else if (baud_x16_ce)
begin
if ( present_state[DATA] && &count_x16 )
count_8bit <= {count_8bit[6:0],count_8bit[7]};
else if (present_state[IDLE])
count_8bit <= 8'h01;
end
end // always @ (posedge clk)
always @(posedge clk)
if (reset | present_state[IDLE])
begin
for (i=0; i<8;i=i+1)
shift_rx_data[i] <= 16'h0;
end
else if (baud_x16_ce & shift_en)
case (1'b1)
count_8bit[0]:
shift_rx_data[0] <= shift_rx_data[0]<<1 | rx_data2;
count_8bit[1]:
shift_rx_data[1] <= shift_rx_data[1]<<1 | rx_data2;
count_8bit[2]:
shift_rx_data[2] <= shift_rx_data[2]<<1 | rx_data2;
count_8bit[3]:
shift_rx_data[3] <= shift_rx_data[3]<<1 | rx_data2;
count_8bit[4]:
shift_rx_data[4] <= shift_rx_data[4]<<1 | rx_data2;
count_8bit[5]:
shift_rx_data[5] <= shift_rx_data[5]<<1 | rx_data2;
count_8bit[6]:
shift_rx_data[6] <= shift_rx_data[6]<<1 | rx_data2;
count_8bit[7]:
shift_rx_data[7] <= shift_rx_data[7]<<1 | rx_data2;
endcase
always @(posedge clk)
if (reset)
begin
parallel_data <= 8'h0;
end
else if (load_data & baud_x16_ce)
parallel_data <= { &shift_rx_data[7][8:7], &shift_rx_data[6][8:7],
&shift_rx_data[5][8:7], &shift_rx_data[4][8:7],
&shift_rx_data[3][8:7], &shift_rx_data[2][8:7],
&shift_rx_data[1][8:7], &shift_rx_data[0][8:7]
};
assign data_1_byte = parallel_data;
always @(posedge clk)
if (reset )
valid <= 1'b0;
else if (baud_x16_ce) begin
if (valid_en)
valid <= 1'b1;
else
valid <= 1'b0;
end
always @(posedge clk)
if (reset | present_state[IDLE])
parity_data <= 16'h0;
else if (baud_x16_ce & parity_en)
parity_data <= parity_data<<1 | rx_data2;
assign parity_bit = &parity_data[8:7];
generate
if (PARITY_MODE==1)
assign expected_parity_bit = ~(^parallel_data);
else
assign expected_parity_bit = ^parallel_data;
endgenerate
//Update the parity status bit.
always @(posedge clk)
if (reset)
parity_error <= 1'b0;
else if (present_state[STOP])
parity_error <= (expected_parity_bit != parity_bit);
//Error in transmission...
//This is unused register in this design. I only need to use it
//during verification.
//TO-DO: You may add this feature to let firmware read the error.
always @(posedge clk)
if (reset)
error <= 1'b0;
else if (present_state[ERROR])
error <= 1'b1;
else if (present_state[STOP])
error <= 1'b0;
always @(posedge clk)
if (reset)
rx_busy <= 1'b0;
else if (present_state[IDLE])
rx_busy <= 1'b0;
else
rx_busy <= 1'b1;
endmodule // receiver
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
//
// This document contains proprietary information which is
// protected by copyright. All rights are reserved. This notice
// refers to original work by Efinix, Inc. which may be derivitive
// of other work distributed under license of the authors. In the
// case of derivative work, nothing in this notice overrides the
// original author's license agreement. Where applicable, the
// original license agreement is included in it's original
// unmodified form immediately below this header.
//
// WARRANTY DISCLAIMER.
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
//
// LIMITATION OF LIABILITY.
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
// APPLY TO LICENSEE.
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
//
// top_uart.v
//
// Description:
// UART Controller
//
// *******************************
// Revisions:
// 1.0 Initial rev
//
// *******************************
/////////////////////////////////////////////////////////////////////////////
`resetall
`timescale 1ns/10ps
//`include "uart_defines.v"
module `IP_MODULE_NAME(top_uart)(
tx_o,
rx_i,
tx_busy,
rx_data,
rx_data_valid,
rx_error,
rx_parity_error,
rx_busy,
baud_x16_ce,
clk,
reset,
tx_data,
baud_rate,
tx_en
);
parameter BYTE = 4;
parameter DATA_WIDTH = BYTE*8;
parameter CLOCK_FREQ = 50000000;
parameter FIX_BAUDRATE = 0;
parameter BAUD = 115200;
parameter ENABLE_PARITY = 0;
parameter PARITY_MODE = 0;
parameter BOOTUP_CHECK = 0;
////////////////////
//UART interface
output tx_o; //UART TX
input rx_i; //UART RX
////////////////////
//User Interface
//outputs
output tx_busy; //transmitting the tx data.
output [7:0] rx_data; //rx_data to user logic
output rx_data_valid; //valid flag for rx_data.
output rx_error; //a start bit, parity bit, or stop bit error was detected during the last received data.
output rx_parity_error; //Indicate receive data contain parity error.
output rx_busy; //Receiving the rx data.
output baud_x16_ce;
//inputs
input clk; //system clock
input reset; //active high reset
input [BYTE*8-1:0] tx_data; //Data to transmit.
input tx_en; //Latches tx_data and initiate transmit
input [2:0] baud_rate; //0-115200, 1-57600, 2-38400, 3-19200, 4-9600, 5-4800, 6-2400, 7-1200
//Internal Signals
wire baud_ce;
wire en_parity;
//UART Format
/* _______ ______ _______________
* IDLE \_Start_/ Bit0 -----Bit1 -> Bit 7(MSB)/PARITY \/STOP IDLE
* Refer to waveform above, the start is start bit (1'b0).
* Meanwhile, the stop is stop bit (1'b1)
*/
`IP_MODULE_NAME(baud_generator) #(.CLOCK_FREQ(CLOCK_FREQ),
.FIX_BAUDRATE(FIX_BAUDRATE),
.BAUD(BAUD)
)
u_baud_generator
(
// Outputs
.baud_ce (baud_ce),
.baud_x16_ce (baud_x16_ce),
// Inputs
.clk (clk),
.baud_rate (baud_rate),
.reset (reset));
`IP_MODULE_NAME(transmitter) #(
.ENABLE_PARITY(ENABLE_PARITY),
.PARITY_MODE(PARITY_MODE),
.DATA_WIDTH(DATA_WIDTH),
.BOOTUP_CHECK(BOOTUP_CHECK)
)
u_transmitter
(
// Outputs
.tx_o (tx_o),
.tx_busy (tx_busy),
// Inputs
.clk (clk),
.reset (reset),
.baud_ce (baud_ce),
.tx_data (tx_data[DATA_WIDTH-1:0]),
.tx_en (tx_en));
`IP_MODULE_NAME(receiver) #(
.PARITY_MODE(PARITY_MODE)
)
u_receiver
(
// Outputs
.data_1_byte (rx_data),
.valid (rx_data_valid),
.error (rx_error),
.parity_error (rx_parity_error),
.rx_busy (rx_busy),
// Inputs
.clk (clk),
.reset (reset),
.baud_x16_ce (baud_x16_ce),
.en_parity (en_parity),
.rx_i (rx_i));
assign en_parity = ENABLE_PARITY;
endmodule // top_uart
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
//
// This document contains proprietary information which is
// protected by copyright. All rights are reserved. This notice
// refers to original work by Efinix, Inc. which may be derivitive
// of other work distributed under license of the authors. In the
// case of derivative work, nothing in this notice overrides the
// original author's license agreement. Where applicable, the
// original license agreement is included in it's original
// unmodified form immediately below this header.
//
// WARRANTY DISCLAIMER.
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
//
// LIMITATION OF LIABILITY.
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
// APPLY TO LICENSEE.
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
//
// transmitter.v
//
// Description:
// Transmit the TX data to UART Peripheral
//
// *******************************
// Revisions:
// 1.0 Initial rev
//
// *******************************
/////////////////////////////////////////////////////////////////////////////
`resetall
`timescale 1ns/10ps
module `IP_MODULE_NAME(transmitter)
#(parameter ENABLE_PARITY = 0,
PARITY_MODE = 0,
DATA_WIDTH = 32,
BOOTUP_CHECK = 0)
(
//outputs
output wire tx_o, //TX data to UART peripheral.
output reg tx_busy, //tx busy flag.
//input
input clk, //system clock
input reset, //system reset.
input baud_ce, //baud tick
input [DATA_WIDTH-1:0] tx_data, //8-bit read data...
input tx_en //Valid read data...Ready to send it...
);
//ASCII
`define ASCII_0 8'h30
`define ASCII_1 8'h31
`define ASCII_2 8'h32
`define ASCII_3 8'h33
`define ASCII_4 8'h34
`define ASCII_5 8'h35
`define ASCII_6 8'h36
`define ASCII_7 8'h37
`define ASCII_8 8'h38
`define ASCII_9 8'h39
`define ASCII_a 8'h61
`define ASCII_b 8'h62
`define ASCII_c 8'h63
`define ASCII_d 8'h64
`define ASCII_e 8'h65
`define ASCII_f 8'h66
`define ASCII_A 8'h41
`define ASCII_B 8'h42
`define ASCII_C 8'h43
`define ASCII_D 8'h44
`define ASCII_E 8'h45
`define ASCII_F 8'h46
`define ASCII_O 8'h4F
`define ASCII_K 8'h4B
`define ASCII_LF 8'h0A
//START & STOP BIT
`define STOP_BIT 1'b1
`define START_BIT 1'b0
//internal signals.
reg [46:0] shift_tx_data;
wire [46:0] xmit_data_p, xmit_data;
reg tx_en0,tx_en1,tx_en2;
reg [5:0] tx_count;
wire ascii_k_parity;
wire ascii_o_parity;
always @(posedge clk)
if (reset)
begin
tx_en0 <= 1'b0;
tx_en1 <= 1'b0;
tx_en2 <= 1'b0;
end
else if (baud_ce)
begin
tx_en0 <= tx_en;
tx_en1 <= tx_en0;
tx_en2 <= tx_en1;
end
generate
if (PARITY_MODE==1) begin //odd
assign ascii_k_parity = ~(^(`ASCII_K));
assign ascii_o_parity = ~(^(`ASCII_O));
end
else begin //even
assign ascii_k_parity = ^(`ASCII_K);
assign ascii_o_parity = ^(`ASCII_O);
end
endgenerate
generate
if (DATA_WIDTH == 32)
if (PARITY_MODE==1) begin
assign xmit_data_p = {`STOP_BIT, ~(^tx_data[7:0]) , tx_data[7:0] , `START_BIT, 1'b1,
`STOP_BIT, ~(^tx_data[15:8]) , tx_data[15:8] , `START_BIT, 1'b1,
`STOP_BIT, ~(^tx_data[23:16]), tx_data[23:16] , `START_BIT, 1'b1,
`STOP_BIT, ~(^tx_data[31:24]), tx_data[31:24] , `START_BIT
};
end
else begin
assign xmit_data_p = {`STOP_BIT, ^tx_data[7:0] , tx_data[7:0] , `START_BIT, 1'b1,
`STOP_BIT, ^tx_data[15:8] , tx_data[15:8] , `START_BIT, 1'b1,
`STOP_BIT, ^tx_data[23:16], tx_data[23:16] , `START_BIT, 1'b1,
`STOP_BIT, ^tx_data[31:24], tx_data[31:24] , `START_BIT
};
end
else if (DATA_WIDTH == 24)
if (PARITY_MODE==1) begin
assign xmit_data_p = {11'h7ff,
`STOP_BIT, ~(^tx_data[7:0]), tx_data[7:0] , `START_BIT, 1'b1,
`STOP_BIT, ~(^tx_data[15:8]), tx_data[15:8] , `START_BIT, 1'b1,
`STOP_BIT, ~(^tx_data[23:16]), tx_data[23:16] , `START_BIT, 1'b1
};
end
else begin
assign xmit_data_p = {11'h7ff,
`STOP_BIT, ^tx_data[7:0] , tx_data[7:0] , `START_BIT, 1'b1,
`STOP_BIT, ^tx_data[15:8] , tx_data[15:8] , `START_BIT, 1'b1,
`STOP_BIT, ^tx_data[23:16], tx_data[23:16] , `START_BIT, 1'b1
};
end
else if (DATA_WIDTH == 16)
if (PARITY_MODE==1) begin
assign xmit_data_p = {23'h7f_ffff,
`STOP_BIT, ~(^tx_data[7:0]) , tx_data[7:0] , `START_BIT, 1'b1,
`STOP_BIT, ~(^tx_data[15:8]) , tx_data[15:8] , `START_BIT, 1'b1
};
end
else begin
assign xmit_data_p = {23'h7f_ffff,
`STOP_BIT, ^tx_data[7:0] , tx_data[7:0] , `START_BIT, 1'b1,
`STOP_BIT, ^tx_data[15:8] , tx_data[15:8] , `START_BIT, 1'b1
};
end
else if (DATA_WIDTH == 8)
if (PARITY_MODE==1) begin
assign xmit_data_p = {35'h7_ffff_ffff,
`STOP_BIT, ~(^tx_data[7:0]) , tx_data[7:0] , `START_BIT, 1'b1
};
end
else begin
assign xmit_data_p = {35'h7_ffff_ffff,
`STOP_BIT, ^tx_data[7:0] , tx_data[7:0] , `START_BIT, 1'b1
};
end
else
if (PARITY_MODE==1) begin
assign xmit_data_p = {35'h7_ffff_ffff,
`STOP_BIT, ~(^tx_data[7:0]) , tx_data[7:0] , `START_BIT, 1'b1
};
end
else begin
assign xmit_data_p = {35'h7_ffff_ffff,
`STOP_BIT, ^tx_data[7:0] , tx_data[7:0] , `START_BIT, 1'b1
};
end
endgenerate
generate
if (DATA_WIDTH == 32)
assign xmit_data = { 4'hf,
`STOP_BIT, tx_data[7:0] , `START_BIT, 1'b1,
`STOP_BIT, tx_data[15:8] , `START_BIT, 1'b1,
`STOP_BIT, tx_data[23:16] , `START_BIT, 1'b1,
`STOP_BIT, tx_data[31:24] , `START_BIT
};
else if (DATA_WIDTH == 24)
assign xmit_data = { 14'h3fff,
`STOP_BIT, tx_data[7:0] , `START_BIT, 1'b1,
`STOP_BIT, tx_data[15:8] , `START_BIT, 1'b1,
`STOP_BIT, tx_data[23:16] , `START_BIT, 1'b1
};
else if (DATA_WIDTH == 16)
assign xmit_data = { 25'h1ff_ffff,
`STOP_BIT, tx_data[7:0] , `START_BIT, 1'b1,
`STOP_BIT, tx_data[15:8] , `START_BIT, 1'b1
};
else if (DATA_WIDTH == 8)
assign xmit_data = { 36'hf_ffff_ffff,
`STOP_BIT, tx_data[7:0] , `START_BIT, 1'b1
};
else
assign xmit_data = { 36'hf_ffff_ffff,
`STOP_BIT, tx_data[7:0] , `START_BIT, 1'b1
};
endgenerate
generate
if (BOOTUP_CHECK) begin
if (ENABLE_PARITY) begin
//Generates OK flag after reset.
always @(posedge clk)
if (reset)
shift_tx_data <= { 12'hfff,
`STOP_BIT, ascii_k_parity, `ASCII_K, `START_BIT,
4'hf,
`STOP_BIT, ascii_o_parity, `ASCII_O, `START_BIT,
8'hff, 1'b1
};
else if (baud_ce)
begin
if (tx_en1 & !tx_en2)
shift_tx_data <= xmit_data_p;
else
shift_tx_data <= {1'b1, shift_tx_data[DATA_WIDTH-1+15:1] } ;
end
end // if (ENABLE_PARITY)
else begin
//Generates OK flag after reset.
always @(posedge clk)
if (reset)
shift_tx_data <= { 1'b1, 8'hff, 1'b1,
`STOP_BIT, `ASCII_K, `START_BIT,
8'hff,
`STOP_BIT, `ASCII_O, `START_BIT,
8'hff, 1'b1
};
else if (baud_ce)
begin
if (tx_en1 & !tx_en2)
shift_tx_data <= xmit_data;
else
shift_tx_data <= {1'b1, shift_tx_data[DATA_WIDTH-1+15:1] } ;
end
end // else: !if(ENABLE_PARITY)
end // if (BOOTUP_CHECK)
else begin
if (ENABLE_PARITY) begin
//Generates OK flag after reset.
always @(posedge clk)
if (reset)
shift_tx_data <= {47{1'b1}};
else if (baud_ce)
begin
if (tx_en1 & !tx_en2)
shift_tx_data <= xmit_data_p;
else
shift_tx_data <= {1'b1, shift_tx_data[DATA_WIDTH-1+15:1] } ;
end
end // if (ENABLE_PARITY)
else begin
//Generates OK flag after reset.
always @(posedge clk)
if (reset)
shift_tx_data <= {47{1'b1}};
else if (baud_ce)
begin
if (tx_en1 & !tx_en2)
shift_tx_data <= xmit_data;
else
shift_tx_data <= {1'b1, shift_tx_data[DATA_WIDTH-1+15:1] } ;
end
end // else: !if(ENABLE_PARITY)
end // else: !if(BOOTUP_CHECK)
endgenerate
always @(posedge clk)
if (reset)
tx_count <= 6'd0;
else if (baud_ce)
if (tx_en1 & !tx_en2)
tx_count <= 6'd0;
else if (tx_count < (DATA_WIDTH+11 + 1) )
tx_count <= tx_count + 1;
always @(posedge clk)
if (reset)
tx_busy <= 1'b0;
else if (baud_ce)
if (tx_en1 & !tx_en2)
tx_busy <= 1'b1;
else if (tx_count == (DATA_WIDTH+11 ) )
tx_busy <= 1'b0;
assign tx_o = shift_tx_data[0];
endmodule // transmitter
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2013-2019 Efinix Inc. All rights reserved.
//
// This document contains proprietary information which is
// protected by copyright. All rights are reserved. This notice
// refers to original work by Efinix, Inc. which may be derivitive
// of other work distributed under license of the authors. In the
// case of derivative work, nothing in this notice overrides the
// original author's license agreement. Where applicable, the
// original license agreement is included in it's original
// unmodified form immediately below this header.
//
// WARRANTY DISCLAIMER.
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
//
// LIMITATION OF LIABILITY.
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
// APPLY TO LICENSEE.
//
/////////////////////////////////////////////////////////////////////////////
`undef IP_UUID
`undef IP_NAME_CONCAT
`undef IP_MODULE_NAME