library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.vhdl_verification.all; entity tb_uart_emu is end tb_uart_emu; architecture tb_uart_emu_arch of tb_uart_emu is constant OUTPUT_FILE : string := "uart.log"; constant VERBOSE : boolean := false; constant DATA_BITS : integer := 8; constant PARITY : string := "none"; constant BIT_DURATION : time := 104.16 us; constant STOP_BITS : integer := 1; --Inputs signal uart_input : std_logic; -- Clock period and signal definition constant clk_period : time := 10 ns; signal clk : std_logic := '0'; -- Component declaration for the uart transmitter component fsm_uart_tx is generic ( BIT_LENGTH : integer := 2000; PARITY : string := "none"; --! Can be either "even", "odd", or "none" STOP_BITS : integer := 1 --! Can be either 1 or 2 ); port ( clk : in STD_LOGIC; rst : in STD_LOGIC; data : in STD_LOGIC_VECTOR (7 downto 0); empty : in STD_LOGIC; rd_en : out STD_LOGIC; TX : out STD_LOGIC ); end component; -- Signals and constants for uart transmitter constant BIT_LENGTH : integer := 10416; signal rst : std_logic := '0'; signal data : std_logic_vector (7 downto 0); signal empty : std_logic := '1'; signal rd_en : std_logic; -- Simulation control constant MAX_CYCLES : integer := 11 * 12 * 10416 + 100; -- 11 chars of 10-12 bits, each one lasting for 10416 cycles, plus some extra cycles just in case signal num_cycles : integer := 0; begin -- Instantiate the Unit Under Test (UUT) uut : uart_emu generic map ( OUTPUT_FILE => OUTPUT_FILE, VERBOSE => VERBOSE, DATA_BITS => DATA_BITS, PARITY => PARITY, BIT_DURATION => BIT_DURATION, STOP_BITS => STOP_BITS ) port map ( uart_input => uart_input ); -- To test our uart receiver, let's reuse a synthesizable uart transmitter -- With a 100 MHz clock, 9600 baud (104.16 usec per bit) are 10416 cycles per -- bit uart_tx_inst: fsm_uart_tx generic map ( BIT_LENGTH => BIT_LENGTH, PARITY => PARITY, STOP_BITS => STOP_BITS ) port map ( clk => clk, rst => rst, data => data, empty => empty, rd_en => rd_en, TX => uart_input ); -- To stop the simulation without a failure message, -- stop the clock when we reach the desired number of cycles clk_process : process begin if(num_cycles < MAX_CYCLES) then clk <= '0'; wait for clk_period/2; clk <= '1'; wait for clk_period/2; num_cycles <= num_cycles + 1; else report "Ending simulation"; wait; end if; end process; -- Stimulus process. Since we are not instancing any fifos, sort of emulate -- their behavior, by changing data each time the uart transmitter sets rd_en -- to '1' stim_proc : process begin rst <= '1'; empty <= '1'; wait for clk_period*2; rst <= '0'; wait for clk_period; empty <= '0'; wait until rd_en = '1'; --wait for clk_period; data <= x"48"; -- H wait until rd_en = '1'; --wait for clk_period; data <= x"6F"; -- o wait until rd_en = '1'; --wait for clk_period; data <= x"6C"; -- l wait until rd_en = '1'; --wait for clk_period; data <= x"61"; -- a wait until rd_en = '1'; --wait for clk_period; data <= x"0A"; -- \n wait until rd_en = '1'; --wait for clk_period; data <= x"4D"; -- M wait until rd_en = '1'; --wait for clk_period; data <= x"75"; -- u wait until rd_en = '1'; --wait for clk_period; data <= x"6E"; -- n wait until rd_en = '1'; --wait for clk_period; data <= x"64"; -- d wait until rd_en = '1'; --wait for clk_period; data <= x"6F"; -- o wait until rd_en = '1'; --wait for clk_period; data <= x"0A"; -- \n -- After last data, wait one clock cycle and signal that we have no more data to send -- (we're empty) wait for clk_period; empty <= '1'; wait; end process; end tb_uart_emu_arch;