URL
https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk
Subversion Repositories riscv_vhdl
[/] [riscv_vhdl/] [trunk/] [rtl/] [gnsslib/] [sync/] [afifo.vhd] - Rev 5
Compare with Previous | Blame | View Log
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity afifo is generic ( abits : integer := 4; dbits : integer := 8 ); port ( i_nrst : in std_logic; -- Reading port. i_rclk : in std_logic; i_rd_ena : in std_logic; o_data : out std_logic_vector (dbits-1 downto 0); o_empty : out std_logic; o_valid : out std_logic; -- Writing port. i_wclk : in std_logic; i_wr_ena : in std_logic; i_data : in std_logic_vector (dbits-1 downto 0); o_full : out std_logic ); end entity; architecture rtl of afifo is ----/Internal connections & variables------ constant FIFO_DEPTH :integer := 2**abits; type RAM is array (integer range <>)of std_logic_vector (dbits-1 downto 0); signal Mem : RAM (0 to FIFO_DEPTH-1); signal pNextWordToWrite :std_logic_vector (abits-1 downto 0); signal pNextWordToRead :std_logic_vector (abits-1 downto 0); signal EqualAddresses :std_logic; signal NextWriteAddressEn :std_logic; signal NextReadAddressEn :std_logic; signal Set_Status :std_logic; signal Rst_Status :std_logic; signal Status :std_logic; signal PresetFull :std_logic; signal PresetEmpty :std_logic; signal empty,full :std_logic; signal r_stat :std_logic; component GrayCounter is generic ( generic_width : integer := 4 ); port ( --'Gray' code count output. i_nrst : in std_logic; -- Count reset. i_clk : in std_logic; -- Input clock i_ena : in std_logic; -- Count enable. o_cnt : out std_logic_vector (generic_width-1 downto 0) ); end component; begin proc_rclk0 : process (i_rclk) begin if (rising_edge(i_rclk)) then o_valid <= '0'; if (i_rd_ena = '1' and empty = '0') then o_data <= Mem(conv_integer(pNextWordToRead)); o_valid <= '1'; end if; end if; end process; --'Data_in' logic: proc_wclk0 : process (i_wclk) begin if (rising_edge(i_wclk)) then if (i_wr_ena = '1' and full = '0') then Mem(conv_integer(pNextWordToWrite)) <= i_data; end if; end if; end process; --Fifo addresses support logic: NextWriteAddressEn <= i_wr_ena and (not full); NextReadAddressEn <= i_rd_ena and (not empty); --Addreses (Gray counters) logic: GrayCounter_pWr : GrayCounter generic map ( generic_width => abits ) port map ( i_nrst => i_nrst, i_clk => i_wclk, i_ena => NextWriteAddressEn, o_cnt => pNextWordToWrite ); GrayCounter_pRd : GrayCounter generic map ( generic_width => abits ) port map ( i_nrst => i_nrst, i_clk => i_rclk, i_ena => NextReadAddressEn, o_cnt => pNextWordToRead ); --'EqualAddresses' logic: EqualAddresses <= '1' when (pNextWordToWrite = pNextWordToRead) else '0'; --'Quadrant selectors' logic: proc0 : process (pNextWordToWrite, pNextWordToRead) variable set_status_bit0 :std_logic; variable set_status_bit1 :std_logic; variable rst_status_bit0 :std_logic; variable rst_status_bit1 :std_logic; begin set_status_bit0 := pNextWordToWrite(abits-2) xnor pNextWordToRead(abits-1); set_status_bit1 := pNextWordToWrite(abits-1) xor pNextWordToRead(abits-2); Set_Status <= set_status_bit0 and set_status_bit1; rst_status_bit0 := pNextWordToWrite(abits-2) xor pNextWordToRead(abits-1); rst_status_bit1 := pNextWordToWrite(abits-1) xnor pNextWordToRead(abits-2); Rst_Status <= rst_status_bit0 and rst_status_bit1; end process; --'Status' latch logic: r_stat <= Rst_Status or (not i_nrst); latch0 : process (i_rclk, Set_Status, r_stat) begin--D Latch w/ Asynchronous Clear & Preset. if r_stat = '1' then Status <= '0'; elsif (Set_Status = '1') then Status <= '1'; --Going 'Full'. elsif rising_edge(i_rclk) then Status <= Status; end if; end process; --'Full_out' logic for the writing port: PresetFull <= Status and EqualAddresses; --'Full' Fifo. latch1 : process (i_wclk, PresetFull) begin --D Flip-Flop w/ Asynchronous Preset. if (PresetFull = '1') then full <= '1'; elsif (rising_edge(i_wclk)) then full <= '0'; end if; end process; o_full <= full; --'Empty_out' logic for the reading port: PresetEmpty <= not Status and EqualAddresses; --'Empty' Fifo. latch2 : process (i_rclk, PresetEmpty) begin --D Flip-Flop w/ Asynchronous Preset. if (PresetEmpty = '1') then empty <= '1'; elsif (rising_edge(i_rclk)) then empty <= '0'; end if; end process; o_empty <= empty; end architecture;