---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 05/24/2022 12:45:28 PM -- Design Name: -- Module Name: UART_Tb - Behavioral -- Project Name: -- Target Devices: -- Tool Versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity UART_Tb is end UART_Tb; architecture UART_Tb_arch of UART_Tb is procedure SendViaUART(constant byte : in std_logic_vector(7 downto 0); constant dt : in time; signal stream : out std_logic) is begin -- Start Bit stream <= '0'; -- Wait for dt wait for dt; -- Send byte for i in 0 to byte'length - 1 loop -- LSB first stream <= byte(i); wait for dt; end loop; -- Stop Bit stream <= '1'; end procedure; component uart_rx generic ( clk_cycles_per_bit : integer ); port ( clk : in std_logic; rst : in std_logic; rx_port : in std_logic; rx_rdy : out std_logic := '0'; rx_ack : in std_logic; rx_data : out std_logic_vector(7 downto 0) ); end component; component uart_tx generic ( clk_cycles_per_bit : integer ); port ( clk : in std_logic; rst : in std_logic; tx_ack : in std_logic; tx_data : in std_logic_vector(7 downto 0); tx_rdy : out std_logic := '1'; tx_port : out std_logic := '1' ); end component; -- Constants constant clk_freq : integer := 10_000_000; -- 10 MHz constant baudrate : integer := 115_200; -- 115200 baud rate (uart) constant clk_period : time := 100 ns; constant freq : integer := clk_freq / baudrate; -- Clk freq / uart baud rate constant dt : time := 8.6805556 us; -- 1 / baud rate -- Signals signal clk: std_logic; signal rst : std_logic; -- Rx signal s_rx_port : std_logic; signal s_rx_rdy : std_logic; signal s_rx_ack : std_logic; signal s_rx_data : std_logic_vector(7 downto 0); -- Tx signal s_tx_port : std_logic; signal s_tx_ack : std_logic; signal s_tx_rdy : std_logic := '1'; signal s_tx_data : std_logic_vector(7 downto 0); -- Intern signals type fsm_states is (s_Idle, s_Decode, s_Send, s_CleanUp); signal state : fsm_states := s_Idle; signal s_buffer : std_logic_vector(7 downto 0); -- buffers incoming bytes signal s_output : std_logic_vector(7 downto 0); -- buffers outgoing bytes begin dut_rx : uart_rx generic map ( clk_cycles_per_bit => freq ) port map ( clk => clk, rst => rst, rx_port => s_rx_port, rx_rdy => s_rx_rdy, rx_ack => s_rx_ack, rx_data => s_rx_data ); dut_tx : uart_tx generic map ( clk_cycles_per_bit => freq ) port map ( clk => clk, rst => rst, tx_port => s_tx_port, tx_ack => s_tx_ack, tx_rdy => s_tx_rdy, tx_data => s_tx_data ); fsm : process(clk) begin if rising_edge(clk) then if rst = '1' then -- Synchronous reset. else case state is when s_Idle => if s_rx_rdy = '1' then s_buffer <= s_rx_data; s_rx_ack <= '1'; state <= s_Decode; end if; when s_Decode => s_rx_ack <= '0'; if s_buffer(7) = '1' then -- Command if s_buffer(6) = '1' then -- Cmd1 s_output <= x"01"; else -- Cmd2 s_output <= x"00"; end if; else -- Data s_output <= s_buffer; end if; state <= s_Send; when s_Send => if s_tx_rdy = '1' then s_tx_data <= s_output; s_tx_ack <= '1'; state <= s_CleanUp; end if; when s_CleanUp => s_tx_ack <= '0'; state <= s_Idle; end case; end if; end if; end process fsm; stimulus : process begin -- initial values s_rx_port <= '1'; rst <= '0'; wait for 20 us; -- Send first byte SendViaUART(x"55", dt, s_rx_port); -- Command s_rx_port <= '1'; wait for 20 us; -- Send second byte SendViaUART(x"ff", dt, s_rx_port); -- Command s_rx_port <= '1'; wait for 20 us; -- Send third byte SendViaUART(x"00", dt, s_rx_port); -- Data s_rx_port <= '1'; wait for 60 us; end process stimulus; clocking : process begin while true loop clk <= '0', '1' after clk_period / 2; wait for clk_period; end loop; end process clocking; end UART_Tb_arch;