Commit c68481b6 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

wb_uart: temporary fix for eRTM UART FIFO issue causing RX data loss. VUART…

wb_uart: temporary fix for eRTM UART FIFO issue causing RX data loss. VUART likely not working. FIX BEFORE MERGING!
parent 526683f6
......@@ -119,9 +119,24 @@ architecture arch of wb_simple_uart is
signal phys_rx_data, phys_tx_data : std_logic_vector(7 downto 0);
type t_tx_fifo_state is (IDLE, TRANSMIT_PENDING);
type t_rx_fifo_state is (IDLE, RX_READ, RX_WAIT_ACK );
signal tx_fifo_state : t_tx_fifo_state;
signal rx_fifo_state : t_rx_fifo_state;
signal rx_fifo_rdata : std_logic_vector(7 downto 0);
signal rx_fifo_wdata : std_logic_vector(7 downto 0);
function f_to_sl( x : boolean ) return std_logic is
begin
if(x) then
return '1';
else
return '0';
end if;
end f_to_sl;
begin -- arch
gen_check_generics : if (not g_WITH_PHYSICAL_UART and not g_WITH_VIRTUAL_UART) generate
......@@ -218,34 +233,39 @@ begin -- arch
baud8_tick_i => baud_tick8,
rxd_i => uart_rxd_i,
rx_ready_o => phys_rx_ready,
rx_error_o => open,
rx_error_o => open, -- fixme: support RX error detection
rx_data_o => phys_rx_data);
end generate gen_phys_uart;
gen_phys_fifos : if g_WITH_PHYSICAL_UART_FIFO generate
rx_fifo_wr <= not rx_fifo_full and phys_rx_ready;
tx_fifo_wr <= not tx_fifo_full and regs_out.tdr_tx_data_wr_o;
tx_fifo_wr <= not tx_fifo_full and ( regs_out.tdr_tx_data_wr_o or
( f_to_sl(g_WITH_VIRTUAL_UART) and regs_out.host_tdr_data_wr_o ) );
tx_fifo_reset_n <= rst_n_i and not regs_out.cr_tx_fifo_purge_o;
rx_fifo_reset_n <= rst_n_i and not regs_out.cr_rx_fifo_purge_o;
rx_fifo_rd <= not rx_fifo_empty and rdr_rack;
-- RX FIFO write data: Physical UART takes the priority over VUART. Note these
-- are not meant to be used simultaneously.
rx_fifo_wdata <= phys_rx_data when phys_rx_ready = '1' else regs_out.host_tdr_data_o;
U_UART_RX_FIFO : generic_sync_fifo
generic map (
g_DATA_WIDTH => 8,
g_SIZE => g_RX_FIFO_SIZE,
g_WITH_COUNT => true,
g_SHOW_AHEAD => true
g_SHOW_AHEAD => false
)
port map (
rst_n_i => rx_fifo_reset_n,
clk_i => clk_sys_i,
d_i => phys_rx_data,
d_i => rx_fifo_wdata,
we_i => rx_fifo_wr,
q_o => regs_in.rdr_rx_data_i,
rd_i => rdr_rack,
q_o => rx_fifo_rdata,
rd_i => rx_fifo_rd,
empty_o => rx_fifo_empty,
full_o => rx_fifo_full,
count_o => rx_fifo_count);
......@@ -270,8 +290,6 @@ begin -- arch
regs_in.sr_rx_fifo_supported_i <= '1';
regs_in.sr_tx_fifo_supported_i <= '1';
regs_in.sr_rx_fifo_valid_i <= not rx_fifo_empty;
regs_in.sr_rx_rdy_i <= not rx_fifo_empty;
regs_in.sr_rx_fifo_overflow_i <= rx_fifo_overflow;
regs_in.sr_tx_fifo_full_i <= tx_fifo_full;
regs_in.sr_tx_fifo_empty_i <= tx_fifo_empty;
......@@ -288,7 +306,11 @@ begin -- arch
if rx_fifo_reset_n = '0' then
rx_fifo_overflow <= '0';
else
if regs_out.cr_rx_fifo_purge_o = '1' then
rx_fifo_overflow <= '0';
elsif rx_fifo_full = '1' then
rx_fifo_overflow <= '1';
end if;
end if;
end if;
end process;
......@@ -319,6 +341,46 @@ begin -- arch
end if;
end process;
p_rx_fifo_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rx_fifo_reset_n = '0' then
rx_fifo_state <= IDLE;
regs_in.sr_rx_fifo_valid_i <= '0';
regs_in.sr_rx_rdy_i <= '0';
else
case rx_fifo_state is
when IDLE =>
regs_in.sr_rx_fifo_valid_i <= '0';
regs_in.sr_rx_rdy_i <= '0';
if rx_fifo_rd = '1' then
rx_fifo_state <= RX_READ;
end if;
when RX_READ =>
regs_in.rdr_rx_data_i <= rx_fifo_rdata;
regs_in.sr_rx_fifo_valid_i <= '1';
regs_in.sr_rx_rdy_i <= '1';
rx_fifo_state <= RX_WAIT_ACK;
when RX_WAIT_ACK =>
if( rdr_rack = '1' ) then
regs_in.sr_rx_fifo_valid_i <= '0';
regs_in.sr_rx_rdy_i <= '0';
rx_fifo_state <= IDLE;
end if;
end case;
end if;
end if;
end process;
rx_fifo_rd <= '1' when rx_fifo_state = IDLE and rx_fifo_empty = '0' else '0';
regs_in.sr_tx_busy_i <= tx_fifo_full;
end generate gen_phys_fifos;
......
......@@ -9,16 +9,12 @@ virtual class CWishboneAccessor extends CBusAccessor;
protected wb_cycle_type_t m_cycle_type;
function new();
$display("NEW");
m_cycle_type = CLASSIC;
m_default_xfer_size = 4;
endfunction // new
virtual task automatic set_mode(wb_cycle_type_t mode);
m_cycle_type = mode;
$display("SET MODE %d", mode );
endtask // set_mode
......@@ -69,7 +65,6 @@ virtual class CWishboneAccessor extends CBusAccessor;
cycle.data.push_back(xfer);
end
// $display("DS: %d", cycle.data.size());
put(cycle);
get(cycle);
......@@ -83,7 +78,6 @@ virtual class CWishboneAccessor extends CBusAccessor;
int i;
cycle.ctype = m_cycle_type;
$display("CYCLE CTYPE %d %d", cycle.ctype, m_cycle_type );
cycle.rw = 1'b0;
......
......@@ -67,6 +67,9 @@ class WBUartDriver extends IBusDevice;
uint32_t rv;
read32( `ADDR_UART_SR, rv );
$display("uart_init SR %b", rv);
write32(`ADDR_UART_BCR, calc_baudrate( baudrate, clock_freq) );
......@@ -203,8 +206,8 @@ module main;
.slave_i (Host1.out),
.slave_o (Host1.in),
.uart_txd_o(txd),
.uart_rxd_i(rxd)
.uart_txd_o(loop),
.uart_rxd_i(loop)
);
......@@ -241,7 +244,7 @@ module main;
.rst_n_i (rst_n));
const int n_tx_bytes = 1024;
initial begin
......@@ -249,12 +252,13 @@ module main;
automatic CWishboneAccessor acc1 = Host1.get_accessor();
automatic WBUartDriver drv_fifo = new( acc1, 0 );
automatic CWishboneAccessor acc2 = Host2.get_accessor();
automatic WBUartDriver drv_no_fifo = new( acc2, 0 );
// automatic CWishboneAccessor acc2 = Host2.get_accessor();
// automatic WBUartDriver drv_no_fifo = new( acc2, 0 );
automatic int i;
acc1.set_mode(PIPELINED);
acc2.set_mode(PIPELINED);
//acc2.set_mode(PIPELINED);
#100ns;
......@@ -265,16 +269,16 @@ module main;
@(posedge clk_62m5);
drv_fifo.init(9216000, 62500000, 0);
drv_no_fifo.init(9216000, 62500000, 0);
drv_fifo.init(9216000, 62500000, 1);
// drv_no_fifo.init(9216000, 62500000, 0);
#1us;
for(i=0;i<100;i++)
for(i=0;i<n_tx_bytes;i++)
begin
drv_no_fifo.send(i);
// drv_no_fifo.send(i);
drv_fifo.send(i);
drv_no_fifo.update();
// drv_no_fifo.update();
drv_fifo.update();
end
......@@ -283,8 +287,8 @@ module main;
// $display("%d %d", drv_fifo.tx_idle(), drv_no_fifo.tx_idle() );
drv_fifo.update();
drv_no_fifo.update();
if( drv_fifo.tx_idle() && drv_no_fifo.tx_idle() )
// drv_no_fifo.update();
if( drv_fifo.tx_idle() /* && drv_no_fifo.tx_idle() */ )
break;
end
......@@ -293,7 +297,9 @@ module main;
for(i=0;i<500;i++)
begin
drv_fifo.update();
drv_no_fifo.update();
#1us;
// drv_no_fifo.update();
end
......@@ -301,12 +307,14 @@ module main;
for(i=0;i<100;i++)
begin
automatic int rx = drv_no_fifo.recv();
if( rx != i )
$error("NoFifo err %x vs %x", i, rx );
rx = drv_fifo.recv();
if( rx != i )
$error("Fifo err %x vs %x", i, rx );
// automatic int rx = drv_no_fifo.recv();
// if( rx != i )
// $error("NoFifo err %x vs %x", i, rx );
automatic int rx = drv_fifo.recv();
$display("Fifo %02x vs %02x %s", i, rx, (i == rx) ? "OK" : "ERROR" );
if( i != rx )
$error("");
end
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment