Skip to content

Commit

Permalink
Merge pull request #64 from umarcor/sim-uart
Browse files Browse the repository at this point in the history
[sim] split UART logging component, make self-checking
  • Loading branch information
stnolting authored Jun 10, 2021
2 parents 94f9aba + 07f9123 commit a795497
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 112 deletions.
133 changes: 21 additions & 112 deletions sim/neorv32_tb.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,10 @@ architecture neorv32_tb_rtl of neorv32_tb is
-- simulation uart0 receiver --
signal uart0_txd : std_ulogic; -- local loop-back
signal uart0_cts : std_ulogic; -- local loop-back
signal uart0_rx_sync : std_ulogic_vector(04 downto 0) := (others => '1');
signal uart0_rx_busy : std_ulogic := '0';
signal uart0_rx_sreg : std_ulogic_vector(08 downto 0) := (others => '0');
signal uart0_rx_baud_cnt : real;
signal uart0_rx_bitcnt : natural;

-- simulation uart1 receiver --
signal uart1_txd : std_ulogic; -- local loop-back
signal uart1_cts : std_ulogic; -- local loop-back
signal uart1_rx_sync : std_ulogic_vector(04 downto 0) := (others => '1');
signal uart1_rx_busy : std_ulogic := '0';
signal uart1_rx_sreg : std_ulogic_vector(08 downto 0) := (others => '0');
signal uart1_rx_baud_cnt : real;
signal uart1_rx_bitcnt : natural;

-- gpio --
signal gpio : std_ulogic_vector(31 downto 0);
Expand Down Expand Up @@ -177,6 +167,7 @@ architecture neorv32_tb_rtl of neorv32_tb is

begin


-- Clock/Reset Generator ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
clk_gen <= not clk_gen after (t_clock_c/2);
Expand Down Expand Up @@ -316,109 +307,27 @@ begin
twi_scl <= 'H';
twi_sda <= 'H';


-- Console UART0 Receiver -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
uart0_rx_console: process(clk_gen)
variable i : integer;
variable l : line;
uart_checkers : block is
begin
-- "UART" --
if rising_edge(clk_gen) then
-- synchronizer --
uart0_rx_sync <= uart0_rx_sync(3 downto 0) & uart0_txd;
-- arbiter --
if (uart0_rx_busy = '0') then -- idle
uart0_rx_busy <= '0';
uart0_rx_baud_cnt <= round(0.5 * uart0_baud_val_c);
uart0_rx_bitcnt <= 9;
if (uart0_rx_sync(4 downto 1) = "1100") then -- start bit? (falling edge)
uart0_rx_busy <= '1';
end if;
else
if (uart0_rx_baud_cnt <= 0.0) then
if (uart0_rx_bitcnt = 1) then
uart0_rx_baud_cnt <= round(0.5 * uart0_baud_val_c);
else
uart0_rx_baud_cnt <= round(uart0_baud_val_c);
end if;
if (uart0_rx_bitcnt = 0) then
uart0_rx_busy <= '0'; -- done
i := to_integer(unsigned(uart0_rx_sreg(8 downto 1)));

if (i < 32) or (i > 32+95) then -- printable char?
report "NEORV32_TB_UART0.TX: (" & integer'image(i) & ")"; -- print code
else
report "NEORV32_TB_UART0.TX: " & character'val(i); -- print ASCII
end if;

if (i = 10) then -- Linux line break
writeline(file_uart0_tx_out, l);
elsif (i /= 13) then -- Remove additional carriage return
write(l, character'val(i));
end if;
else
uart0_rx_sreg <= uart0_rx_sync(4) & uart0_rx_sreg(8 downto 1);
uart0_rx_bitcnt <= uart0_rx_bitcnt - 1;
end if;
else
uart0_rx_baud_cnt <= uart0_rx_baud_cnt - 1.0;
end if;
end if;
end if;
end process uart0_rx_console;


-- Console UART1 Receiver -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
uart1_rx_console: process(clk_gen)
variable i : integer;
variable l : line;
begin
-- "UART" --
if rising_edge(clk_gen) then
-- synchronizer --
uart1_rx_sync <= uart1_rx_sync(3 downto 0) & uart1_txd;
-- arbiter --
if (uart1_rx_busy = '0') then -- idle
uart1_rx_busy <= '0';
uart1_rx_baud_cnt <= round(0.5 * uart1_baud_val_c);
uart1_rx_bitcnt <= 9;
if (uart1_rx_sync(4 downto 1) = "1100") then -- start bit? (falling edge)
uart1_rx_busy <= '1';
end if;
else
if (uart1_rx_baud_cnt <= 0.0) then
if (uart1_rx_bitcnt = 1) then
uart1_rx_baud_cnt <= round(0.5 * uart1_baud_val_c);
else
uart1_rx_baud_cnt <= round(uart1_baud_val_c);
end if;
if (uart1_rx_bitcnt = 0) then
uart1_rx_busy <= '0'; -- done
i := to_integer(unsigned(uart1_rx_sreg(8 downto 1)));

if (i < 32) or (i > 32+95) then -- printable char?
report "NEORV32_TB_UART1.TX: (" & integer'image(i) & ")"; -- print code
else
report "NEORV32_TB_UART1.TX: " & character'val(i); -- print ASCII
end if;

if (i = 10) then -- Linux line break
writeline(file_uart1_tx_out, l);
elsif (i /= 13) then -- Remove additional carriage return
write(l, character'val(i));
end if;
else
uart1_rx_sreg <= uart1_rx_sync(4) & uart1_rx_sreg(8 downto 1);
uart1_rx_bitcnt <= uart1_rx_bitcnt - 1;
end if;
else
uart1_rx_baud_cnt <= uart1_rx_baud_cnt - 1.0;
end if;
end if;
end if;
end process uart1_rx_console;
uart0_checker: entity work.uart_rx
generic map (
name => "uart0",
expected => nul & nul & cr & lf & "<< PROCESSOR CHECK >>" & cr & lf & "build: ",
uart_baud_val_c => uart0_baud_val_c)
port map (
clk => clk_gen,
uart_txd => uart0_txd);


uart1_checker: entity work.uart_rx
generic map (
name => "uart1",
expected => nul & nul & etx,
uart_baud_val_c => uart1_baud_val_c)
port map (
clk => clk_gen,
uart_txd => uart1_txd);
end block;


-- Wishbone Fabric ------------------------------------------------------------------------
Expand Down
89 changes: 89 additions & 0 deletions sim/uart_rx.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;

use std.textio.all;

entity uart_rx is
generic (
name : string;
expected : string;
uart_baud_val_c : real);

port (
clk : in std_ulogic;
uart_txd : in std_ulogic
);
end entity;

architecture a of uart_rx is
signal uart_rx_sync : std_ulogic_vector(04 downto 0) := (others => '1');
signal uart_rx_busy : std_ulogic := '0';
signal uart_rx_sreg : std_ulogic_vector(08 downto 0) := (others => '0');
signal uart_rx_baud_cnt : real;
signal uart_rx_bitcnt : natural;

file file_uart_tx_out : text open write_mode is "neorv32.testbench_" & name & ".out";

begin
uart_rx_console : process(clk)
variable i : integer;
variable l : line;
variable expected_idx : positive := 1;
begin
-- "UART" --
if rising_edge(clk) then
-- synchronizer --
uart_rx_sync <= uart_rx_sync(3 downto 0) & uart_txd;
-- arbiter --
if (uart_rx_busy = '0') then -- idle
uart_rx_busy <= '0';
uart_rx_baud_cnt <= round(0.5 * uart_baud_val_c);
uart_rx_bitcnt <= 9;
if (uart_rx_sync(4 downto 1) = "1100") then -- start bit? (falling edge)
uart_rx_busy <= '1';
end if;
else
if (uart_rx_baud_cnt <= 0.0) then
if (uart_rx_bitcnt = 1) then
uart_rx_baud_cnt <= round(0.5 * uart_baud_val_c);
else
uart_rx_baud_cnt <= round(uart_baud_val_c);
end if;
if (uart_rx_bitcnt = 0) then
uart_rx_busy <= '0'; -- done
i := to_integer(unsigned(uart_rx_sreg(8 downto 1)));

if (expected_idx < expected'length) or
((expected_idx = expected'length) and (expected(expected'length) /= etx)) then
assert character'val(i) = expected(expected_idx)
report "Got " & character'val(i) & ", expected " & expected(expected_idx);
else
assert expected(expected'length) /= etx report "Extra characters received";
end if;

expected_idx := expected_idx + 1;

if (i < 32) or (i > 32+95) then -- printable char?
report name & ".tx: (" & integer'image(i) & ")"; -- print code
else
report name & ".tx: " & character'val(i); -- print ASCII
end if;

if (i = 10) then -- Linux line break
writeline(file_uart_tx_out, l);
elsif (i /= 13) then -- Remove additional carriage return
write(l, character'val(i));
end if;
else
uart_rx_sreg <= uart_rx_sync(4) & uart_rx_sreg(8 downto 1);
uart_rx_bitcnt <= uart_rx_bitcnt - 1;
end if;
else
uart_rx_baud_cnt <= uart_rx_baud_cnt - 1.0;
end if;
end if;
end if;
end process uart_rx_console;
end architecture;

0 comments on commit a795497

Please sign in to comment.