Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make uart_rx a VUnit verification component. Step 4. #90

Merged
merged 1 commit into from
Jun 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 11 additions & 22 deletions sim/neorv32_tb.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ architecture neorv32_tb_rtl of neorv32_tb is

constant uart0_rx_logger : logger_t := get_logger("UART0.RX");
constant uart1_rx_logger : logger_t := get_logger("UART1.RX");
constant uart0_actor : actor_t := new_actor;
constant uart1_actor : actor_t := new_actor;
constant uart0_rx_handle : uart_rx_t := new_uart_rx(uart0_baud_val_c, uart0_rx_logger);
constant uart1_rx_handle : uart_rx_t := new_uart_rx(uart1_baud_val_c, uart1_rx_logger);

begin
test_runner : process
Expand All @@ -166,26 +166,21 @@ begin
show(uart0_rx_logger, display_handler, pass);
show(uart1_rx_logger, display_handler, pass);

-- Sending messages with the expected data to receive takes no simulation
-- time, only data cycles.
msg := new_msg(check_uart_msg);
if ci_mode then
push(msg, nul & nul);
check_uart(net, uart0_rx_handle, nul & nul);
else
push(msg, "Blinking LED demo program" & cr & lf);
check_uart(net, uart0_rx_handle, "Blinking LED demo program" & cr & lf);
end if;
send(net, uart0_actor, msg);

msg := new_msg(check_uart_msg);
if ci_mode then
push(msg, nul & nul & "0/45" & cr & lf);
send(net, uart1_actor, msg);
-- No need to send the full expectation in one big chunk
check_uart(net, uart1_rx_handle, nul & nul);
check_uart(net, uart1_rx_handle, "0/45" & cr & lf);
end if;


-- Wait until all expected data has been received
wait_until_idle(net, uart0_actor);
wait_until_idle(net, uart1_actor);
wait_until_idle(net, get_actor(uart0_rx_handle));
wait_until_idle(net, get_actor(uart1_rx_handle));

-- Wait a bit more if some extra unexpected data is produced. If so,
-- uart_rx will fail
Expand Down Expand Up @@ -347,19 +342,13 @@ begin
uart_checkers : block is
begin
uart0_checker: entity work.uart_rx
generic map (
actor => uart0_actor,
logger => uart0_rx_logger,
uart_baud_val_c => uart0_baud_val_c)
generic map (uart0_rx_handle)
port map (
clk => clk_gen,
uart_txd => uart0_txd);

uart1_checker: entity work.uart_rx
generic map (
actor => uart1_actor,
logger => uart1_rx_logger,
uart_baud_val_c => uart1_baud_val_c)
generic map (uart1_rx_handle)
port map (
clk => clk_gen,
uart_txd => uart1_txd);
Expand Down
18 changes: 7 additions & 11 deletions sim/uart_rx.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ context vunit_lib.vc_context;
use work.uart_rx_pkg.all;

entity uart_rx is
generic (
actor : actor_t;
logger : logger_t;
uart_baud_val_c : real);

generic (handle : uart_rx_t);
port (
clk : in std_ulogic;
uart_txd : in std_ulogic
Expand All @@ -31,8 +27,8 @@ architecture a of uart_rx is
signal uart_rx_baud_cnt : real;
signal uart_rx_bitcnt : natural;

file file_uart_tx_out : text open write_mode is "neorv32.testbench_" & get_name(logger) & ".out";
constant checker : checker_t := new_checker(logger);
file file_uart_tx_out : text open write_mode is "neorv32.testbench_" & get_name(handle.p_logger) & ".out";
constant checker : checker_t := new_checker(handle.p_logger);
constant character_queue : queue_t := new_queue;

begin
Expand All @@ -47,7 +43,7 @@ begin
end loop;
end procedure put_characters_in_queue;
begin
receive(net, actor, request_msg);
receive(net, handle.p_actor, request_msg);
msg_type := message_type(request_msg);

-- Standard handling of standard wait_for_time messages = wait for the given time
Expand Down Expand Up @@ -82,17 +78,17 @@ begin
-- 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_baud_cnt <= round(0.5 * handle.p_baud_val);
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);
uart_rx_baud_cnt <= round(0.5 * handle.p_baud_val);
else
uart_rx_baud_cnt <= round(uart_baud_val_c);
uart_rx_baud_cnt <= round(handle.p_baud_val);
end if;
if (uart_rx_bitcnt = 0) then
uart_rx_busy <= '0'; -- done
Expand Down
40 changes: 37 additions & 3 deletions sim/uart_rx_pkg.vhd
Original file line number Diff line number Diff line change
@@ -1,25 +1,59 @@
library vunit_lib;
context vunit_lib.vunit_context;
context vunit_lib.com_context;

package uart_rx_pkg is
constant check_uart_msg : msg_type_t := new_msg_type("check_uart");

type uart_rx_t is record
p_baud_val : real;
p_logger : logger_t;
p_actor : actor_t;
end record;

impure function new_uart_rx(
baud_val : real;
logger : logger_t := null_logger;
actor : actor_t := null_actor) return uart_rx_t;

function get_actor(handle : uart_rx_t) return actor_t;

procedure check_uart(
signal net : inout network_t;
constant actor : in actor_t;
constant handle : in uart_rx_t;
constant data : in string);
end package uart_rx_pkg;

package body uart_rx_pkg is
constant uart_rx_logger : logger_t := get_logger("neorv32_lib:uart_rx_pkg");

impure function new_uart_rx(
baud_val : real;
logger : logger_t := null_logger;
actor : actor_t := null_actor) return uart_rx_t is
variable result : uart_rx_t;
begin
result.p_baud_val := baud_val;
result.p_logger := logger when logger /= null_logger else uart_rx_logger;
result.p_actor := actor when actor /= null_actor else new_actor;

return result;
end;

function get_actor(handle : uart_rx_t) return actor_t is
begin
return handle.p_actor;
end;

procedure check_uart(
signal net : inout network_t;
constant actor : in actor_t;
constant handle : in uart_rx_t;
constant data : in string) is
variable msg : msg_t;
begin
msg := new_msg(check_uart_msg);
push(msg, data);
send(net, actor, msg);
send(net, handle.p_actor, msg);
end;

end package body uart_rx_pkg;