| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.numeric_std.all;
- use IEEE.math_real.all;
- entity async_8n1_tx_tb is
- end entity;
- architecture beh of async_8n1_tx_tb is
- component generic_prescaler is
- generic (
- prescaler_bits : integer := 13
- );
- port(
- clk : in std_logic;
- rst : in std_logic;
- en : in std_logic;
- load : in std_logic;
- prescaler_value : in unsigned (prescaler_bits - 1 downto 0);
- en_out : out std_logic
- );
- end component;
-
- component async_8n1_tx is
- port
- (
- clk : in std_logic;
- rst : in std_logic;
- en : in std_logic;
- wr : in std_logic;
- data_in : in unsigned (7 downto 0);
- rdy : out std_logic;
- data_out : out std_logic
- );
- end component;
-
- component async_8n1_tx_v2 is
- port
- (
- clk : in std_logic;
- rst : in std_logic;
- en : in std_logic;
- wr : in std_logic;
- data_in : in unsigned (7 downto 0);
- rdy : out std_logic;
- data_out : out std_logic
- );
- end component;
- component async_8n1_rx is
- port
- (
- clk : in std_logic;
- rst : in std_logic;
- en : in std_logic;
- read : in std_logic;
- data_in : in std_logic;
- data_available : out std_logic;
- frame_error : out std_logic;
- overflow_error : out std_logic;
- data_out : out unsigned (7 downto 0)
- );
- end component;
-
- constant freq : integer := 50; -- MHz
- constant period : time := 1000 / freq * 1 ns;
- constant half_period : time := period / 2;
- signal num_rising_edges : integer := 0;
-
- constant simulation_periods : integer := 5155*121;
- signal clock : std_logic := '0';
- signal enable : std_logic;
- signal reset : std_logic;
- signal prescaled_clk_en : std_logic;
-
- constant prescaler_value : integer := 5154;
- constant prescaler_num_bits : integer := integer(ceil(log2(real(prescaler_value))));
- signal running : boolean := true;
-
- signal tx1 : std_logic;
- signal rdy1 : std_logic;
-
- signal tx2 : std_logic;
- signal rdy2 : std_logic;
- signal rx_available : std_logic;
- signal rx_read : std_logic := '0';
-
- signal wr : std_logic;
- signal tx_char : unsigned (7 downto 0);
- signal rx_char : unsigned (7 downto 0);
- type hex_arr is array (0 to 3) of unsigned(7 downto 0);
- signal tx_char_buffer : hex_arr := (x"aa", x"55", x"00", x"ff");
-
- begin
- running <= true,
- false after simulation_periods * period;
-
- reset <= '0',
- '1' after 2 * period,
- '0' after 3 * period;
-
- enable <= '0',
- '1' after 5 * period;
- wr <= '0',
- '1' after 10 * period,
- '1' after 11 * period;
-
- --tx_char <= to_unsigned(character'pos('a'), 8);
- --tx_char <= x"aa",
- -- x"55" after 50 * prescaler_value * period,
- -- x"00" after 100 * prescaler_value * period,
- -- x"ff" after 150 * prescaler_value * period,
- -- x"aa" after 200 * prescaler_value * period;
- i_prescaler : generic_prescaler
- generic map(
- prescaler_bits => prescaler_num_bits
- )
- port map(
- clk => clock,
- rst => reset,
- en => enable,
- load => '1',
- prescaler_value => to_unsigned(prescaler_value, prescaler_num_bits),
- en_out => prescaled_clk_en
- );
-
- DUT1 : async_8n1_tx
- port map(
- clk => clock,
- rst => reset,
- en => prescaled_clk_en,
- wr => wr,
- data_in => tx_char,
- rdy => rdy1,
- data_out => tx1
- );
-
- DUT2 : async_8n1_tx_v2
- port map(
- clk => clock,
- rst => reset,
- en => prescaled_clk_en,
- wr => wr,
- data_in => tx_char,
- rdy => rdy2,
- data_out => tx2
- );
-
- DUT3 : async_8n1_rx
- port map(
- clk => clock,
- rst => reset,
- en => prescaled_clk_en,
- read => rx_read,
- data_in => tx2,
- data_available => rx_available,
- frame_error => open,
- overflow_error => open,
- data_out => rx_char
- );
- -- clock process
- process is
- begin
- if running then
- wait for half_period;
- clock <= not clock;
- else
- report "End of simulation!";
- wait;
- end if;
- end process;
- process(tx_char) is
- begin
- --wait for half_period;
- --report time'image(period);
- report "Tx-char: " & integer'image(to_integer(tx_char));
- --wait;
- end process;
-
- -- simulate a read operation after every received byte
- process is
- begin
- wait until rx_available = '1';
- wait for prescaler_value * period;
- rx_read <= '1';
- wait until rx_available = '0';
- wait for prescaler_value * period;
- rx_read <= '0';
- end process;
- -- Loop through the tx char buffer everythime a transceiver is ready
- process is
- begin
- for i in tx_char_buffer'range loop
- wait until rdy1 = '1';
- tx_char <= tx_char_buffer(i);
- wait until rdy1 = '0';
- end loop;
- end process;
-
- -- Rising edge counter
- process(clock) is
- begin
- if rising_edge(clock) then
- if reset = '1' then
- num_rising_edges <= 0;
- elsif enable = '1' then
- num_rising_edges <= num_rising_edges+1;
- else
- -- Explicit no change
- num_rising_edges <= num_rising_edges;
- end if;
- end if;
- end process;
- -- Automated checks
- process(clock) is
- begin
- if rising_edge(clock)
- and num_rising_edges > 1 then
- assert not (num_rising_edges mod prescaler_value = 0 and prescaled_clk_en /= '1') report "Prescaler not working!" severity error;
-
- assert tx1 = tx2 report "Transciever tx disagreement" severity error;
- assert rdy1 = rdy2 report "Transciever rdy disagreement" severity error;
- end if;
- end process;
- end architecture;
|