Library of reusable VHDL components
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
5.7 KiB

  1. -- Copyright (c) 2014 - 2022 by Torsten Meissner
  2. --
  3. -- Licensed under the Apache License, Version 2.0 (the "License");
  4. -- you may not use this file except in compliance with the License.
  5. -- You may obtain a copy of the License at
  6. --
  7. -- https://www.apache.org/licenses/LICENSE-2.0
  8. --
  9. -- Unless required by applicable law or agreed to in writing, software
  10. -- distributed under the License is distributed on an "AS IS" BASIS,
  11. -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. -- See the License for the specific language governing permissions and
  13. -- limitations under the License.
  14. library ieee;
  15. use ieee.std_logic_1164.all;
  16. use ieee.numeric_std.all;
  17. library osvvm;
  18. use osvvm.RandomPkg.all;
  19. use osvvm.CoveragePkg.all;
  20. use std.env.all;
  21. entity UartT is
  22. end entity UartT;
  23. architecture sim of UartT is
  24. constant c_data_length : positive range 5 to 9 := 8;
  25. constant c_parity : boolean := true;
  26. constant c_clk_div : natural := 10;
  27. signal s_reset_n : std_logic := '0';
  28. signal s_clk : std_logic := '1';
  29. signal s_tx_data : std_logic_vector(c_data_length-1 downto 0);
  30. signal s_tx_valid : std_logic;
  31. signal s_tx_accept : std_logic;
  32. signal s_rx_data : std_logic_vector(c_data_length-1 downto 0);
  33. signal s_rx_error : std_logic;
  34. signal s_rx_valid : std_logic;
  35. signal s_rx_accept : std_logic;
  36. signal s_tx_uart : std_logic := '1';
  37. signal s_rx_uart : std_logic := '1';
  38. type t_error is (NONE, DATA, STOP);
  39. signal s_error_inject : t_error := NONE;
  40. signal s_error_injected : t_error := NONE;
  41. shared variable sv_uart_err_coverage : CovPType;
  42. procedure injectError (signal inject : out t_error) is
  43. variable v_injected : boolean;
  44. variable v_random : RandomPType;
  45. begin
  46. v_random.InitSeed(v_random'instance_name & to_string(now));
  47. loop
  48. -- Wait for new UART transmission
  49. v_injected := false;
  50. wait until s_tx_valid = '1' and s_tx_accept = '1';
  51. wait until falling_edge(s_tx_uart);
  52. -- Skip start bit
  53. for i in 0 to c_clk_div-1 loop
  54. wait until rising_edge(s_clk);
  55. end loop;
  56. -- Possibly distort one of the data bits
  57. -- and update coverage object
  58. for i in 0 to c_data_length loop
  59. if (not v_injected and v_random.DistValInt(((0, 9), (1, 1))) = 1) then
  60. v_injected := true;
  61. sv_uart_err_coverage.ICover(i);
  62. if (i = c_data_length) then
  63. inject <= STOP;
  64. report "Injected transmit error on stop bit";
  65. else
  66. inject <= DATA;
  67. report "Injected transmit error on data bit #" & to_string(i);
  68. end if;
  69. end if;
  70. for y in 0 to c_clk_div-1 loop
  71. wait until rising_edge(s_clk);
  72. end loop;
  73. inject <= NONE;
  74. end loop;
  75. end loop;
  76. wait;
  77. end procedure injectError;
  78. begin
  79. Dut_UartTx : entity work.UartTx
  80. generic map (
  81. DATA_LENGTH => c_data_length,
  82. PARITY => c_parity,
  83. CLK_DIV => c_clk_div
  84. )
  85. port map (
  86. reset_n_i => s_reset_n,
  87. clk_i => s_clk,
  88. data_i => s_tx_data,
  89. valid_i => s_tx_valid,
  90. accept_o => s_tx_accept,
  91. tx_o => s_tx_uart
  92. );
  93. -- Error injection based on random
  94. sv_uart_err_coverage.AddBins("DATA_ERROR", GenBin(0, c_data_length-1));
  95. sv_uart_err_coverage.AddBins("STOP_ERROR", GenBin(c_data_length));
  96. injectError(s_error_inject);
  97. s_rx_uart <= s_tx_uart when s_error_inject = NONE else not(s_tx_uart);
  98. Dut_UartRx : entity work.UartRx
  99. generic map (
  100. DATA_LENGTH => c_data_length,
  101. PARITY => c_parity,
  102. CLK_DIV => c_clk_div
  103. )
  104. port map (
  105. reset_n_i => s_reset_n,
  106. clk_i => s_clk,
  107. data_o => s_rx_data,
  108. error_o => s_rx_error,
  109. valid_o => s_rx_valid,
  110. accept_i => s_rx_accept,
  111. rx_i => s_rx_uart
  112. );
  113. s_clk <= not s_clk after 5 ns;
  114. s_reset_n <= '1' after 20 ns;
  115. -- Store if an error was injected in the current frame
  116. s_error_injected <= s_error_inject when rising_edge(s_clk) and s_error_inject /= NONE else
  117. NONE when s_tx_valid = '1';
  118. TestP : process is
  119. variable v_data : std_logic_vector(c_data_length-1 downto 0);
  120. variable v_random : RandomPType;
  121. begin
  122. v_random.InitSeed(v_random'instance_name);
  123. s_tx_valid <= '0';
  124. s_rx_accept <= '0';
  125. s_tx_data <= (others => '0');
  126. wait until s_reset_n = '1';
  127. for i in 0 to 2**c_data_length-1 loop
  128. wait until rising_edge(s_clk);
  129. s_tx_valid <= '1';
  130. s_rx_accept <= '1';
  131. v_data := v_random.RandSlv(8);
  132. s_tx_data <= v_data;
  133. report "Testcase #" & to_string(i) & ": Transmit 0x" & to_hstring(v_data);
  134. wait until rising_edge(s_clk) and s_tx_accept = '1';
  135. s_tx_valid <= '0';
  136. wait until rising_edge(s_clk) and s_rx_valid = '1';
  137. if s_error_injected /= NONE then
  138. if s_error_injected = DATA then
  139. assert s_rx_data /= v_data
  140. report "Received data 0x" & to_hstring(s_rx_data) & ", expected 0x" & to_hstring(v_data)
  141. severity failure;
  142. end if;
  143. assert s_rx_error = '1'
  144. report "Received error 0b" & to_string(s_rx_error) & ", expected 0b1"
  145. severity failure;
  146. else
  147. assert s_rx_data = v_data
  148. report "Received data 0x" & to_hstring(s_rx_data) & ", expected 0x" & to_hstring(v_data)
  149. severity failure;
  150. assert s_rx_error = '0'
  151. report "Received error 0b" & to_string(s_rx_error) & ", expected 0b0"
  152. severity failure;
  153. end if;
  154. end loop;
  155. wait for 10 us;
  156. sv_uart_err_coverage.SetMessage("UART bit error coverage");
  157. sv_uart_err_coverage.WriteBin;
  158. finish(0);
  159. end process TestP;
  160. end architecture sim;