Line 56... |
Line 56... |
// Normally AMBER_UART_BAUD is defined in the system_config_defines.v file.
|
// Normally AMBER_UART_BAUD is defined in the system_config_defines.v file.
|
`ifndef AMBER_UART_BAUD
|
`ifndef AMBER_UART_BAUD
|
`define AMBER_UART_BAUD 230400
|
`define AMBER_UART_BAUD 230400
|
`endif
|
`endif
|
|
|
module uart (
|
module uart #(
|
|
parameter WB_DWIDTH = 32,
|
|
parameter WB_SWIDTH = 4
|
|
)(
|
input i_clk,
|
input i_clk,
|
|
|
input [31:0] i_wb_adr,
|
input [31:0] i_wb_adr,
|
input [3:0] i_wb_sel,
|
input [WB_SWIDTH-1:0] i_wb_sel,
|
input i_wb_we,
|
input i_wb_we,
|
output [31:0] o_wb_dat,
|
output [WB_DWIDTH-1:0] o_wb_dat,
|
input [31:0] i_wb_dat,
|
input [WB_DWIDTH-1:0] i_wb_dat,
|
input i_wb_cyc,
|
input i_wb_cyc,
|
input i_wb_stb,
|
input i_wb_stb,
|
output o_wb_ack,
|
output o_wb_ack,
|
output o_wb_err,
|
output o_wb_err,
|
|
|
Line 204... |
Line 207... |
reg [7:0] uart_lcrm_reg = 'd0; // Line Control Middle Byte
|
reg [7:0] uart_lcrm_reg = 'd0; // Line Control Middle Byte
|
reg [7:0] uart_lcrl_reg = 'd0; // Line Control Low Byte
|
reg [7:0] uart_lcrl_reg = 'd0; // Line Control Low Byte
|
reg [7:0] uart_cr_reg = 'd0; // Control Register
|
reg [7:0] uart_cr_reg = 'd0; // Control Register
|
|
|
// Wishbone interface
|
// Wishbone interface
|
reg [31:0] wb_rdata = 'd0;
|
reg [31:0] wb_rdata32 = 'd0;
|
wire wb_start_write;
|
wire wb_start_write;
|
wire wb_start_read;
|
wire wb_start_read;
|
reg wb_start_read_d1 = 'd0;
|
reg wb_start_read_d1 = 'd0;
|
|
wire [31:0] wb_wdata32;
|
|
|
integer i;
|
integer i;
|
|
|
// ======================================================
|
// ======================================================
|
// Wishbone Interface
|
// Wishbone Interface
|
Line 223... |
Line 227... |
assign wb_start_read = i_wb_stb && !i_wb_we && !o_wb_ack;
|
assign wb_start_read = i_wb_stb && !i_wb_we && !o_wb_ack;
|
|
|
always @( posedge i_clk )
|
always @( posedge i_clk )
|
wb_start_read_d1 <= wb_start_read;
|
wb_start_read_d1 <= wb_start_read;
|
|
|
assign o_wb_dat = wb_rdata;
|
|
|
|
assign o_wb_err = 1'd0;
|
assign o_wb_err = 1'd0;
|
assign o_wb_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
|
assign o_wb_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
|
|
|
|
generate
|
|
if (WB_DWIDTH == 128)
|
|
begin : wb128
|
|
assign wb_wdata32 = i_wb_adr[3:2] == 2'd3 ? i_wb_dat[127:96] :
|
|
i_wb_adr[3:2] == 2'd2 ? i_wb_dat[ 95:64] :
|
|
i_wb_adr[3:2] == 2'd1 ? i_wb_dat[ 63:32] :
|
|
i_wb_dat[ 31: 0] ;
|
|
|
|
assign o_wb_dat = {4{wb_rdata32}};
|
|
end
|
|
else
|
|
begin : wb32
|
|
assign wb_wdata32 = i_wb_dat;
|
|
assign o_wb_dat = wb_rdata32;
|
|
end
|
|
endgenerate
|
|
|
|
|
// ======================================================
|
// ======================================================
|
// UART 0 Receive FIFO
|
// UART 0 Receive FIFO
|
// ======================================================
|
// ======================================================
|
|
|
Line 356... |
Line 375... |
if ( fifo_enable )
|
if ( fifo_enable )
|
begin
|
begin
|
// Push
|
// Push
|
if ( tx_fifo_push_not_full )
|
if ( tx_fifo_push_not_full )
|
begin
|
begin
|
tx_fifo[tx_fifo_wp[3:0]] <= i_wb_dat[7:0];
|
tx_fifo[tx_fifo_wp[3:0]] <= wb_wdata32[7:0];
|
tx_fifo_wp <= tx_fifo_wp + 1'd1;
|
tx_fifo_wp <= tx_fifo_wp + 1'd1;
|
end
|
end
|
|
|
|
|
// Pop
|
// Pop
|
Line 385... |
Line 404... |
tx_fifo_count <= 'd0;
|
tx_fifo_count <= 'd0;
|
|
|
// Push
|
// Push
|
if ( tx_fifo_push_not_full )
|
if ( tx_fifo_push_not_full )
|
begin
|
begin
|
tx_fifo[0] <= i_wb_dat[7:0];
|
tx_fifo[0] <= wb_wdata32[7:0];
|
tx_fifo_full_flag <= 1'd1;
|
tx_fifo_full_flag <= 1'd1;
|
end
|
end
|
// Pop
|
// Pop
|
else if ( tx_fifo_pop_not_empty )
|
else if ( tx_fifo_pop_not_empty )
|
tx_fifo_full_flag <= 1'd0;
|
tx_fifo_full_flag <= 1'd0;
|
Line 700... |
Line 719... |
// ========================================================
|
// ========================================================
|
always @( posedge i_clk )
|
always @( posedge i_clk )
|
if ( wb_start_write )
|
if ( wb_start_write )
|
case ( i_wb_adr[15:0] )
|
case ( i_wb_adr[15:0] )
|
// Receive status, (Write) Error Clear
|
// Receive status, (Write) Error Clear
|
AMBER_UART_RSR: uart_rsr_reg <= i_wb_dat[7:0];
|
AMBER_UART_RSR: uart_rsr_reg <= wb_wdata32[7:0];
|
// Line Control High Byte
|
// Line Control High Byte
|
AMBER_UART_LCRH: uart_lcrh_reg <= i_wb_dat[7:0];
|
AMBER_UART_LCRH: uart_lcrh_reg <= wb_wdata32[7:0];
|
// Line Control Middle Byte
|
// Line Control Middle Byte
|
AMBER_UART_LCRM: uart_lcrm_reg <= i_wb_dat[7:0];
|
AMBER_UART_LCRM: uart_lcrm_reg <= wb_wdata32[7:0];
|
// Line Control Low Byte
|
// Line Control Low Byte
|
AMBER_UART_LCRL: uart_lcrl_reg <= i_wb_dat[7:0];
|
AMBER_UART_LCRL: uart_lcrl_reg <= wb_wdata32[7:0];
|
// Control Register
|
// Control Register
|
AMBER_UART_CR: uart_cr_reg <= i_wb_dat[7:0];
|
AMBER_UART_CR: uart_cr_reg <= wb_wdata32[7:0];
|
endcase
|
endcase
|
|
|
|
|
// ========================================================
|
// ========================================================
|
// Register Reads
|
// Register Reads
|
// ========================================================
|
// ========================================================
|
always @( posedge i_clk )
|
always @( posedge i_clk )
|
if ( wb_start_read )
|
if ( wb_start_read )
|
case ( i_wb_adr[15:0] )
|
case ( i_wb_adr[15:0] )
|
|
|
AMBER_UART_CID0: wb_rdata <= 32'h0d;
|
AMBER_UART_CID0: wb_rdata32 <= 32'h0d;
|
AMBER_UART_CID1: wb_rdata <= 32'hf0;
|
AMBER_UART_CID1: wb_rdata32 <= 32'hf0;
|
AMBER_UART_CID2: wb_rdata <= 32'h05;
|
AMBER_UART_CID2: wb_rdata32 <= 32'h05;
|
AMBER_UART_CID3: wb_rdata <= 32'hb1;
|
AMBER_UART_CID3: wb_rdata32 <= 32'hb1;
|
AMBER_UART_PID0: wb_rdata <= 32'h10;
|
AMBER_UART_PID0: wb_rdata32 <= 32'h10;
|
AMBER_UART_PID1: wb_rdata <= 32'h10;
|
AMBER_UART_PID1: wb_rdata32 <= 32'h10;
|
AMBER_UART_PID2: wb_rdata <= 32'h04;
|
AMBER_UART_PID2: wb_rdata32 <= 32'h04;
|
AMBER_UART_PID3: wb_rdata <= 32'h00;
|
AMBER_UART_PID3: wb_rdata32 <= 32'h00;
|
|
|
AMBER_UART_DR: // Rx data
|
AMBER_UART_DR: // Rx data
|
if ( fifo_enable )
|
if ( fifo_enable )
|
wb_rdata <= {24'd0, rx_fifo[rx_fifo_rp[3:0]]};
|
wb_rdata32 <= {24'd0, rx_fifo[rx_fifo_rp[3:0]]};
|
else
|
else
|
wb_rdata <= {24'd0, rx_fifo[0]};
|
wb_rdata32 <= {24'd0, rx_fifo[0]};
|
|
|
AMBER_UART_RSR: wb_rdata <= uart_rsr_reg; // Receive status, (Write) Error Clear
|
AMBER_UART_RSR: wb_rdata32 <= uart_rsr_reg; // Receive status, (Write) Error Clear
|
AMBER_UART_LCRH: wb_rdata <= uart_lcrh_reg; // Line Control High Byte
|
AMBER_UART_LCRH: wb_rdata32 <= uart_lcrh_reg; // Line Control High Byte
|
AMBER_UART_LCRM: wb_rdata <= uart_lcrm_reg; // Line Control Middle Byte
|
AMBER_UART_LCRM: wb_rdata32 <= uart_lcrm_reg; // Line Control Middle Byte
|
AMBER_UART_LCRL: wb_rdata <= uart_lcrl_reg; // Line Control Low Byte
|
AMBER_UART_LCRL: wb_rdata32 <= uart_lcrl_reg; // Line Control Low Byte
|
AMBER_UART_CR: wb_rdata <= uart_cr_reg; // Control Register
|
AMBER_UART_CR: wb_rdata32 <= uart_cr_reg; // Control Register
|
|
|
// UART Tx/Rx Status
|
// UART Tx/Rx Status
|
AMBER_UART_FR: wb_rdata <= {tx_fifo_empty, // tx fifo empty
|
AMBER_UART_FR: wb_rdata32 <= {tx_fifo_empty, // tx fifo empty
|
rx_fifo_full, // rx fifo full
|
rx_fifo_full, // rx fifo full
|
tx_fifo_full, // tx fifo full
|
tx_fifo_full, // tx fifo full
|
rx_fifo_empty, // rx fifo empty
|
rx_fifo_empty, // rx fifo empty
|
!tx_fifo_empty, // uart busy
|
!tx_fifo_empty, // uart busy
|
1'd1, // !Data Carrier Detect
|
1'd1, // !Data Carrier Detect
|
1'd1, // !Data Set Ready
|
1'd1, // !Data Set Ready
|
!uart0_cts_n_d[3] // !Clear to Send
|
!uart0_cts_n_d[3] // !Clear to Send
|
}; // Flag Register
|
}; // Flag Register
|
|
|
// Interrupt Status
|
// Interrupt Status
|
AMBER_UART_IIR: wb_rdata <= {5'd0,
|
AMBER_UART_IIR: wb_rdata32 <= {5'd0,
|
1'd0, // RTIS - receive timeout interrupt
|
1'd0, // RTIS - receive timeout interrupt
|
tx_interrupt, // TIS - transmit interrupt status
|
tx_interrupt, // TIS - transmit interrupt status
|
rx_interrupt, // RIS - receive interrupt status
|
rx_interrupt, // RIS - receive interrupt status
|
1'd0 // Modem interrupt status
|
1'd0 // Modem interrupt status
|
}; // (Write) Clear Int
|
}; // (Write) Clear Int
|
|
|
default: wb_rdata <= 32'h00c0ffee;
|
default: wb_rdata32 <= 32'h00c0ffee;
|
|
|
endcase
|
endcase
|
|
|
|
|
|
|
Line 865... |
Line 884... |
if ( wb_read_ack || wb_start_write )
|
if ( wb_read_ack || wb_start_write )
|
begin
|
begin
|
`TB_DEBUG_MESSAGE
|
`TB_DEBUG_MESSAGE
|
|
|
if ( wb_start_write )
|
if ( wb_start_write )
|
$write("Write 0x%08x to ", i_wb_dat);
|
$write("Write 0x%08x to ", wb_wdata32);
|
else
|
else
|
$write("Read 0x%08x from ", o_wb_dat);
|
$write("Read 0x%08x from ", o_wb_dat);
|
|
|
case ( i_wb_adr[15:0] )
|
case ( i_wb_adr[15:0] )
|
AMBER_UART_PID0: $write("UART PID0 register");
|
AMBER_UART_PID0: $write("UART PID0 register");
|
Line 878... |
Line 897... |
AMBER_UART_PID3: $write("UART PID3 register");
|
AMBER_UART_PID3: $write("UART PID3 register");
|
AMBER_UART_CID0: $write("UART CID0 register");
|
AMBER_UART_CID0: $write("UART CID0 register");
|
AMBER_UART_CID1: $write("UART CID1 register");
|
AMBER_UART_CID1: $write("UART CID1 register");
|
AMBER_UART_CID2: $write("UART CID2 register");
|
AMBER_UART_CID2: $write("UART CID2 register");
|
AMBER_UART_CID3: $write("UART CID3 register");
|
AMBER_UART_CID3: $write("UART CID3 register");
|
AMBER_UART_DR: $write("UART Tx/Rx char %c", wb_start_write ? i_wb_dat[7:0] : o_wb_dat[7:0] );
|
AMBER_UART_DR: $write("UART Tx/Rx char %c", wb_start_write ? wb_wdata32[7:0] : o_wb_dat[7:0] );
|
AMBER_UART_RSR: $write("UART (Read) Receive status, (Write) Error Clear");
|
AMBER_UART_RSR: $write("UART (Read) Receive status, (Write) Error Clear");
|
AMBER_UART_LCRH: $write("UART Line Control High Byte");
|
AMBER_UART_LCRH: $write("UART Line Control High Byte");
|
AMBER_UART_LCRM: $write("UART Line Control Middle Byte");
|
AMBER_UART_LCRM: $write("UART Line Control Middle Byte");
|
AMBER_UART_LCRL: $write("UART Line Control Low Byte");
|
AMBER_UART_LCRL: $write("UART Line Control Low Byte");
|
AMBER_UART_CR: $write("UART Control Register");
|
AMBER_UART_CR: $write("UART Control Register");
|
Line 918... |
Line 937... |
end
|
end
|
|
|
if ( tx_fifo_push && tx_fifo_full )
|
if ( tx_fifo_push && tx_fifo_full )
|
begin
|
begin
|
`TB_WARNING_MESSAGE
|
`TB_WARNING_MESSAGE
|
$display("UART tx FIFO overflow - char = %c", i_wb_dat[7:0]);
|
$display("UART tx FIFO overflow - char = %c", wb_wdata32[7:0]);
|
end
|
end
|
end
|
end
|
|
|
|
|
// ========================================================
|
// ========================================================
|