async_8n1_tx_tb.vhd 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. use IEEE.math_real.all;
  5. entity async_8n1_tx_tb is
  6. end entity;
  7. architecture beh of async_8n1_tx_tb is
  8. component generic_prescaler is
  9. generic (
  10. prescaler_bits : integer := 13
  11. );
  12. port(
  13. clk : in std_logic;
  14. rst : in std_logic;
  15. en : in std_logic;
  16. load : in std_logic;
  17. prescaler_value : in unsigned (prescaler_bits - 1 downto 0);
  18. en_out : out std_logic
  19. );
  20. end component;
  21. component async_8n1_tx is
  22. port
  23. (
  24. clk : in std_logic;
  25. rst : in std_logic;
  26. en : in std_logic;
  27. wr : in std_logic;
  28. data_in : in unsigned (7 downto 0);
  29. rdy : out std_logic;
  30. data_out : out std_logic
  31. );
  32. end component;
  33. component async_8n1_tx_v2 is
  34. port
  35. (
  36. clk : in std_logic;
  37. rst : in std_logic;
  38. en : in std_logic;
  39. wr : in std_logic;
  40. data_in : in unsigned (7 downto 0);
  41. rdy : out std_logic;
  42. data_out : out std_logic
  43. );
  44. end component;
  45. component async_8n1_rx is
  46. port
  47. (
  48. clk : in std_logic;
  49. rst : in std_logic;
  50. en : in std_logic;
  51. read : in std_logic;
  52. data_in : in std_logic;
  53. data_available : out std_logic;
  54. frame_error : out std_logic;
  55. overflow_error : out std_logic;
  56. data_out : out unsigned (7 downto 0)
  57. );
  58. end component;
  59. constant freq : integer := 50; -- MHz
  60. constant period : time := 1000 / freq * 1 ns;
  61. constant half_period : time := period / 2;
  62. signal num_rising_edges : integer := 0;
  63. constant simulation_periods : integer := 5155*121;
  64. signal clock : std_logic := '0';
  65. signal enable : std_logic;
  66. signal reset : std_logic;
  67. signal prescaled_clk_en : std_logic;
  68. constant prescaler_value : integer := 5154;
  69. constant prescaler_num_bits : integer := integer(ceil(log2(real(prescaler_value))));
  70. signal running : boolean := true;
  71. signal tx1 : std_logic;
  72. signal rdy1 : std_logic;
  73. signal tx2 : std_logic;
  74. signal rdy2 : std_logic;
  75. signal rx_available : std_logic;
  76. signal rx_read : std_logic := '0';
  77. signal wr : std_logic;
  78. signal tx_char : unsigned (7 downto 0);
  79. signal rx_char : unsigned (7 downto 0);
  80. type hex_arr is array (0 to 3) of unsigned(7 downto 0);
  81. signal tx_char_buffer : hex_arr := (x"aa", x"55", x"00", x"ff");
  82. begin
  83. running <= true,
  84. false after simulation_periods * period;
  85. reset <= '0',
  86. '1' after 2 * period,
  87. '0' after 3 * period;
  88. enable <= '0',
  89. '1' after 5 * period;
  90. wr <= '0',
  91. '1' after 10 * period,
  92. '1' after 11 * period;
  93. --tx_char <= to_unsigned(character'pos('a'), 8);
  94. --tx_char <= x"aa",
  95. -- x"55" after 50 * prescaler_value * period,
  96. -- x"00" after 100 * prescaler_value * period,
  97. -- x"ff" after 150 * prescaler_value * period,
  98. -- x"aa" after 200 * prescaler_value * period;
  99. i_prescaler : generic_prescaler
  100. generic map(
  101. prescaler_bits => prescaler_num_bits
  102. )
  103. port map(
  104. clk => clock,
  105. rst => reset,
  106. en => enable,
  107. load => '1',
  108. prescaler_value => to_unsigned(prescaler_value, prescaler_num_bits),
  109. en_out => prescaled_clk_en
  110. );
  111. DUT1 : async_8n1_tx
  112. port map(
  113. clk => clock,
  114. rst => reset,
  115. en => prescaled_clk_en,
  116. wr => wr,
  117. data_in => tx_char,
  118. rdy => rdy1,
  119. data_out => tx1
  120. );
  121. DUT2 : async_8n1_tx_v2
  122. port map(
  123. clk => clock,
  124. rst => reset,
  125. en => prescaled_clk_en,
  126. wr => wr,
  127. data_in => tx_char,
  128. rdy => rdy2,
  129. data_out => tx2
  130. );
  131. DUT3 : async_8n1_rx
  132. port map(
  133. clk => clock,
  134. rst => reset,
  135. en => prescaled_clk_en,
  136. read => rx_read,
  137. data_in => tx2,
  138. data_available => rx_available,
  139. frame_error => open,
  140. overflow_error => open,
  141. data_out => rx_char
  142. );
  143. -- clock process
  144. process is
  145. begin
  146. if running then
  147. wait for half_period;
  148. clock <= not clock;
  149. else
  150. report "End of simulation!";
  151. wait;
  152. end if;
  153. end process;
  154. process(tx_char) is
  155. begin
  156. --wait for half_period;
  157. --report time'image(period);
  158. report "Tx-char: " & integer'image(to_integer(tx_char));
  159. --wait;
  160. end process;
  161. -- simulate a read operation after every received byte
  162. process is
  163. begin
  164. wait until rx_available = '1';
  165. wait for prescaler_value * period;
  166. rx_read <= '1';
  167. wait until rx_available = '0';
  168. wait for prescaler_value * period;
  169. rx_read <= '0';
  170. end process;
  171. -- Loop through the tx char buffer everythime a transceiver is ready
  172. process is
  173. begin
  174. for i in tx_char_buffer'range loop
  175. wait until rdy1 = '1';
  176. tx_char <= tx_char_buffer(i);
  177. wait until rdy1 = '0';
  178. end loop;
  179. end process;
  180. -- Rising edge counter
  181. process(clock) is
  182. begin
  183. if rising_edge(clock) then
  184. if reset = '1' then
  185. num_rising_edges <= 0;
  186. elsif enable = '1' then
  187. num_rising_edges <= num_rising_edges+1;
  188. else
  189. -- Explicit no change
  190. num_rising_edges <= num_rising_edges;
  191. end if;
  192. end if;
  193. end process;
  194. -- Automated checks
  195. process(clock) is
  196. begin
  197. if rising_edge(clock)
  198. and num_rising_edges > 1 then
  199. assert not (num_rising_edges mod prescaler_value = 0 and prescaled_clk_en /= '1') report "Prescaler not working!" severity error;
  200. assert tx1 = tx2 report "Transciever tx disagreement" severity error;
  201. assert rdy1 = rdy2 report "Transciever rdy disagreement" severity error;
  202. end if;
  203. end process;
  204. end architecture;