---------------------------------------------------------------------------- -- fifo_uart.vhd -- FIFO Wrapper for UART -- Version 1.0 -- -- Copyright (C) 2015 H.Poetzl -- -- This program is free software: you can redistribute it and/or -- modify it under the terms of the GNU General Public License -- as published by the Free Software Foundation, either version -- 2 of the License, or (at your option) any later version. -- ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.ALL; use IEEE.numeric_std.ALL; library unisim; use unisim.VCOMPONENTS.ALL; library unimacro; use unimacro.VCOMPONENTS.ALL; use work.vivado_pkg.ALL; -- Vivado Attributes use work.fifo_pkg.ALL; -- FIFO Functions entity fifo_uart is generic ( DATA_BITS : natural := 8; STOP_BITS : natural := 1; PARITY_BITS : natural := 0; SAMPLE_COUNT : natural := 5 ); port ( uart_clk : in std_logic; uart_rx : in std_logic; uart_tx : out std_logic; -- fifo_clk : in std_logic; reset : in std_logic; debug : out std_logic_vector (17 downto 0); -- rx_data : out std_logic_vector (7 downto 0); rx_empty : out std_logic; rx_ren : in std_logic; -- tx_data : in std_logic_vector (7 downto 0); tx_full : out std_logic; tx_wen : in std_logic ); end entity fifo_uart; architecture RTL of fifo_uart is -------------------------------------------------------------------- -- UART Signals -------------------------------------------------------------------- signal uart_rxf : std_logic; signal uart_rdata : std_logic_vector (7 downto 0); signal uart_rparity : std_logic; signal uart_rvalid : std_logic; signal uart_ridle : std_logic; signal uart_wdata : std_logic_vector (7 downto 0); signal uart_wparity : std_logic; signal uart_wvalid : std_logic; signal uart_widle : std_logic; -------------------------------------------------------------------- -- FIFO Signals -------------------------------------------------------------------- constant DATA_CWIDTH : natural := cwidth_f(8, "18Kb"); signal rx_fifo_usage : std_logic_vector (DATA_CWIDTH - 1 downto 0); signal rx_fifo_in : std_logic_vector (7 downto 0); signal rx_fifo_out : std_logic_vector (7 downto 0); signal rx_fifo_wen : std_logic; signal rx_fifo_ren : std_logic; signal rx_fifo_rst : std_logic; signal rx_fifo_rdcount : std_logic_vector (DATA_CWIDTH - 1 downto 0); signal rx_fifo_wrcount : std_logic_vector (DATA_CWIDTH - 1 downto 0); signal rx_fifo_empty : std_logic; signal rx_fifo_full : std_logic; signal tx_fifo_usage : std_logic_vector (DATA_CWIDTH - 1 downto 0); signal tx_fifo_in : std_logic_vector (7 downto 0); signal tx_fifo_out : std_logic_vector (7 downto 0); signal tx_fifo_wen : std_logic; signal tx_fifo_ren : std_logic; signal tx_fifo_rst : std_logic; signal tx_fifo_rdcount : std_logic_vector (DATA_CWIDTH - 1 downto 0); signal tx_fifo_wrcount : std_logic_vector (DATA_CWIDTH - 1 downto 0); signal tx_fifo_empty : std_logic; signal tx_fifo_full : std_logic; begin -------------------------------------------------------------------- -- UART Receiver -------------------------------------------------------------------- filter_inst : entity work.uart_filter generic map ( SAMPLE_COUNT => SAMPLE_COUNT ) port map ( clk => uart_clk, -- ser_in => uart_rx, -- ser_out => uart_rxf ); uart_rx_inst : entity work.uart_rx generic map ( DATA_BITS => 8, STOP_BITS => 1, PARITY_BITS => 0, SAMPLE_COUNT => 5 ) port map ( clk => uart_clk, -- ser => uart_rxf, idle => uart_ridle, state => debug(9 downto 7), -- data => uart_rdata, valid => uart_rvalid, parity => uart_rparity ); debug(5) <= uart_rvalid; debug(6) <= uart_ridle; -------------------------------------------------------------------- -- UART Transmitter -------------------------------------------------------------------- uart_tx_inst : entity work.uart_tx generic map ( DATA_BITS => 8, STOP_BITS => 1, PARITY_BITS => 0, SAMPLE_COUNT => 5 ) port map ( clk => uart_clk, -- data => uart_wdata, valid => uart_wvalid, -- ser => uart_tx, idle => uart_widle, state => debug(4 downto 2)); debug(0) <= uart_wvalid; debug(1) <= uart_widle; -------------------------------------------------------------------- -- UART FIFOs -------------------------------------------------------------------- rx_fifo_usage <= std_logic_vector(abs( signed(rx_fifo_rdcount) - signed(rx_fifo_wrcount))); tx_fifo_usage <= std_logic_vector(abs( signed(tx_fifo_rdcount) - signed(tx_fifo_wrcount))); -- uart_clk_proc : process (uart_clk) -- begin -- if rising_edge(uart_clk) then rx_fifo_in <= uart_rdata; rx_fifo_wen <= (not rx_fifo_full) and uart_rvalid; uart_wdata <= tx_fifo_out; /* uart_wvalid <= (not tx_fifo_empty) and uart_widle; */ uart_wvalid <= not tx_fifo_empty; tx_fifo_ren <= (not tx_fifo_empty) and uart_widle; -- end if; -- end process; -- fifo_clk_proc : process (fifo_clk) -- begin -- if rising_edge(fifo_clk) then rx_data <= rx_fifo_out; rx_fifo_ren <= rx_ren; rx_empty <= rx_fifo_empty; tx_fifo_in <= tx_data; tx_fifo_wen <= (not tx_fifo_full) and tx_wen; tx_full <= tx_fifo_full; -- end if; -- end process; rx_FIFO_inst : FIFO_DUALCLOCK_MACRO generic map ( DEVICE => "7SERIES", DATA_WIDTH => 8, FIFO_SIZE => "18Kb", FIRST_WORD_FALL_THROUGH => TRUE ) port map ( DI => rx_fifo_in, WRCLK => uart_clk, WREN => rx_fifo_wen, WRCOUNT => rx_fifo_wrcount, -- DO => rx_fifo_out, RDCLK => fifo_clk, RDEN => rx_fifo_ren, RDCOUNT => rx_fifo_rdcount, -- EMPTY => rx_fifo_empty, FULL => rx_fifo_full, RST => reset ); debug(13 downto 10) <= rx_fifo_ren & rx_fifo_wen & rx_fifo_empty & rx_fifo_full; tx_FIFO_inst : FIFO_DUALCLOCK_MACRO generic map ( DEVICE => "7SERIES", DATA_WIDTH => 8, FIFO_SIZE => "18Kb", FIRST_WORD_FALL_THROUGH => TRUE ) port map ( DI => tx_fifo_in, WRCLK => fifo_clk, WREN => tx_fifo_wen, WRCOUNT => tx_fifo_wrcount, -- DO => tx_fifo_out, RDCLK => uart_clk, RDEN => tx_fifo_ren, RDCOUNT => tx_fifo_rdcount, -- EMPTY => tx_fifo_empty, FULL => tx_fifo_full, RST => reset ); debug(17 downto 14) <= tx_fifo_ren & tx_fifo_wen & tx_fifo_empty & tx_fifo_full; end RTL;