async_8n1_tx_tb.vhd 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. constant freq : integer := 50; -- MHz
  46. constant period : time := 1000 / freq * 1 ns;
  47. constant half_period : time := period / 2;
  48. signal num_rising_edges : integer := 0;
  49. constant simulation_periods : integer := 5155*21;
  50. signal clock : std_logic := '0';
  51. signal enable : std_logic;
  52. signal reset : std_logic;
  53. signal prescaled_clk_en : std_logic;
  54. constant prescaler_value : integer := 5154;
  55. constant prescaler_num_bits : integer := integer(ceil(log2(real(prescaler_value))));
  56. signal running : boolean := true;
  57. signal tx1 : std_logic;
  58. signal rdy1 : std_logic;
  59. signal tx2 : std_logic;
  60. signal rdy2 : std_logic;
  61. signal wr : std_logic;
  62. signal tx_char : unsigned (7 downto 0);
  63. begin
  64. running <= true,
  65. false after simulation_periods * period;
  66. reset <= '0',
  67. '1' after 2 * period,
  68. '0' after 3 * period;
  69. enable <= '0',
  70. '1' after 5 * period;
  71. wr <= '0',
  72. '1' after 10 * period,
  73. '1' after 11 * period;
  74. --tx_char <= to_unsigned(character'pos('a'), 8);
  75. tx_char <= x"aa",
  76. x"55" after 50 * period,
  77. x"00" after 100 * period,
  78. x"ff" after 150 * period,
  79. x"aa" after 200 * period;
  80. i_prescaler : generic_prescaler
  81. generic map(
  82. prescaler_bits => prescaler_num_bits
  83. )
  84. port map(
  85. clk => clock,
  86. rst => reset,
  87. en => enable,
  88. load => '1',
  89. prescaler_value => to_unsigned(prescaler_value, prescaler_num_bits),
  90. en_out => prescaled_clk_en
  91. );
  92. DUT1 : async_8n1_tx
  93. port map(
  94. clk => clock,
  95. rst => reset,
  96. en => prescaled_clk_en,
  97. wr => wr,
  98. data_in => tx_char,
  99. rdy => rdy1,
  100. data_out => tx1
  101. );
  102. DUT2 : async_8n1_tx_v2
  103. port map(
  104. clk => clock,
  105. rst => reset,
  106. en => prescaled_clk_en,
  107. wr => wr,
  108. data_in => tx_char,
  109. rdy => rdy2,
  110. data_out => tx2
  111. );
  112. -- clock process
  113. process is
  114. begin
  115. if running then
  116. wait for half_period;
  117. clock <= not clock;
  118. else
  119. report "End of simulation!";
  120. wait;
  121. end if;
  122. end process;
  123. -- Rising edge counter
  124. process(clock) is
  125. begin
  126. if rising_edge(clock) then
  127. if reset = '1' then
  128. num_rising_edges <= 0;
  129. elsif enable = '1' then
  130. num_rising_edges <= num_rising_edges+1;
  131. else
  132. -- Explicit no change
  133. num_rising_edges <= num_rising_edges;
  134. end if;
  135. end if;
  136. end process;
  137. -- Automated checks
  138. process(clock) is
  139. begin
  140. if rising_edge(clock)
  141. and num_rising_edges > 1 then
  142. assert not (num_rising_edges mod prescaler_value = 0 and prescaled_clk_en /= '1') report "Prescaler not working!" severity error;
  143. assert tx1 = tx2 report "Transciever tx disagreement" severity error;
  144. assert rdy1 = rdy2 report "Transciever rdy disagreement" severity error;
  145. end if;
  146. end process;
  147. end architecture;