|
|
@ -37,39 +37,6 @@ end entity UartT; |
|
|
|
architecture sim of UartT is |
|
|
|
|
|
|
|
|
|
|
|
component UartTx is |
|
|
|
generic ( |
|
|
|
DATA_LENGTH : positive range 5 to 9 := 8; |
|
|
|
PARITY : boolean := false; |
|
|
|
CLK_DIV : natural := 10 |
|
|
|
); |
|
|
|
port ( |
|
|
|
reset_n_i : in std_logic; -- async reset |
|
|
|
clk_i : in std_logic; -- clock |
|
|
|
data_i : in std_logic_vector(DATA_LENGTH-1 downto 0); -- data input |
|
|
|
valid_i : in std_logic; -- input data valid |
|
|
|
accept_o : out std_logic; -- inpit data accepted |
|
|
|
tx_o : out std_logic -- uart tx data output |
|
|
|
); |
|
|
|
end component UartTx; |
|
|
|
|
|
|
|
component UartRx is |
|
|
|
generic ( |
|
|
|
DATA_LENGTH : positive range 5 to 9 := 8; |
|
|
|
PARITY : boolean := true; |
|
|
|
CLK_DIV : natural := 10 |
|
|
|
); |
|
|
|
port ( |
|
|
|
reset_n_i : in std_logic; -- async reset |
|
|
|
clk_i : in std_logic; -- clock |
|
|
|
data_o : out std_logic_vector(DATA_LENGTH-1 downto 0); -- data output |
|
|
|
error_o : out std_logic; -- rx error |
|
|
|
valid_o : out std_logic; -- output data valid |
|
|
|
accept_i : in std_logic; -- output data accepted |
|
|
|
rx_i : in std_logic -- uart rx input |
|
|
|
); |
|
|
|
end component UartRx; |
|
|
|
|
|
|
|
constant c_data_length : positive range 5 to 9 := 8; |
|
|
|
constant c_parity : boolean := true; |
|
|
|
constant c_clk_div : natural := 10; |
|
|
@ -88,12 +55,13 @@ architecture sim of UartT is |
|
|
|
signal s_tx_uart : std_logic := '1'; |
|
|
|
signal s_rx_uart : std_logic := '1'; |
|
|
|
|
|
|
|
signal s_error_inject : boolean := false; |
|
|
|
signal s_error_injected : boolean := false; |
|
|
|
type t_error is (NONE, DATA, STOP); |
|
|
|
signal s_error_inject : t_error := NONE; |
|
|
|
signal s_error_injected : t_error := NONE; |
|
|
|
|
|
|
|
shared variable sv_uart_err_coverage : CovPType; |
|
|
|
|
|
|
|
procedure injectError (signal inject : out boolean) is |
|
|
|
procedure injectError (signal inject : out t_error) is |
|
|
|
variable v_injected : boolean; |
|
|
|
variable v_random : RandomPType; |
|
|
|
begin |
|
|
@ -109,17 +77,22 @@ architecture sim of UartT is |
|
|
|
end loop; |
|
|
|
-- Possibly distort one of the data bits |
|
|
|
-- and update coverage object |
|
|
|
for i in 0 to c_data_length-1 loop |
|
|
|
for i in 0 to c_data_length loop |
|
|
|
if (not v_injected and v_random.DistValInt(((0, 9), (1, 1))) = 1) then |
|
|
|
v_injected := true; |
|
|
|
inject <= true; |
|
|
|
sv_uart_err_coverage.ICover(i); |
|
|
|
report "Injected transmit error on bit #" & to_string(i); |
|
|
|
if (i = c_data_length) then |
|
|
|
inject <= STOP; |
|
|
|
report "Injected transmit error on stop bit"; |
|
|
|
else |
|
|
|
inject <= DATA; |
|
|
|
report "Injected transmit error on data bit #" & to_string(i); |
|
|
|
end if; |
|
|
|
end if; |
|
|
|
for y in 0 to c_clk_div-1 loop |
|
|
|
wait until rising_edge(s_clk); |
|
|
|
end loop; |
|
|
|
inject <= false; |
|
|
|
inject <= NONE; |
|
|
|
end loop; |
|
|
|
end loop; |
|
|
|
wait; |
|
|
@ -129,7 +102,7 @@ architecture sim of UartT is |
|
|
|
begin |
|
|
|
|
|
|
|
|
|
|
|
Dut_UartTx : UartTx |
|
|
|
Dut_UartTx : entity work.UartTx |
|
|
|
generic map ( |
|
|
|
DATA_LENGTH => c_data_length, |
|
|
|
PARITY => c_parity, |
|
|
@ -146,12 +119,13 @@ begin |
|
|
|
|
|
|
|
|
|
|
|
-- Error injection based on random |
|
|
|
sv_uart_err_coverage.AddBins(GenBin(0, c_data_length-1)); |
|
|
|
sv_uart_err_coverage.AddBins("DATA_ERROR", GenBin(0, c_data_length-1)); |
|
|
|
sv_uart_err_coverage.AddBins("STOP_ERROR", GenBin(c_data_length)); |
|
|
|
injectError(s_error_inject); |
|
|
|
s_rx_uart <= s_tx_uart when not s_error_inject else not(s_tx_uart); |
|
|
|
s_rx_uart <= s_tx_uart when s_error_inject = NONE else not(s_tx_uart); |
|
|
|
|
|
|
|
|
|
|
|
Dut_UartRx : UartRx |
|
|
|
Dut_UartRx : entity work.UartRx |
|
|
|
generic map ( |
|
|
|
DATA_LENGTH => c_data_length, |
|
|
|
PARITY => c_parity, |
|
|
@ -173,13 +147,12 @@ begin |
|
|
|
|
|
|
|
|
|
|
|
-- Store if an error was injected in the current frame |
|
|
|
s_error_injected <= true when rising_edge(s_clk) and s_error_inject else |
|
|
|
false when s_tx_valid = '1'; |
|
|
|
s_error_injected <= s_error_inject when rising_edge(s_clk) and s_error_inject /= NONE else |
|
|
|
NONE when s_tx_valid = '1'; |
|
|
|
|
|
|
|
|
|
|
|
TestP : process is |
|
|
|
variable v_data : std_logic_vector(c_data_length-1 downto 0); |
|
|
|
variable v_error : boolean := false; |
|
|
|
variable v_random : RandomPType; |
|
|
|
begin |
|
|
|
v_random.InitSeed(v_random'instance_name); |
|
|
@ -197,10 +170,12 @@ begin |
|
|
|
wait until rising_edge(s_clk) and s_tx_accept = '1'; |
|
|
|
s_tx_valid <= '0'; |
|
|
|
wait until rising_edge(s_clk) and s_rx_valid = '1'; |
|
|
|
if s_error_injected then |
|
|
|
assert s_rx_data /= v_data |
|
|
|
report "Received data 0x" & to_hstring(s_rx_data) & ", expected 0x" & to_hstring(v_data) |
|
|
|
severity failure; |
|
|
|
if s_error_injected /= NONE then |
|
|
|
if s_error_injected = DATA then |
|
|
|
assert s_rx_data /= v_data |
|
|
|
report "Received data 0x" & to_hstring(s_rx_data) & ", expected 0x" & to_hstring(v_data) |
|
|
|
severity failure; |
|
|
|
end if; |
|
|
|
assert s_rx_error = '1' |
|
|
|
report "Received error 0b" & to_string(s_rx_error) & ", expected 0b1" |
|
|
|
severity failure; |
|
|
|