Newer
Older
Tomasz Wlostowski
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
----------------------------------------------------------------------------
---- ----
---- ----
---- This file is part of the srl_fifo project ----
---- http://www.opencores.org/cores/srl_fifo ----
---- ----
---- Description ----
---- Implementation of srl_fifo IP core according to ----
---- srl_fifo IP core specification document. ----
---- ----
---- To Do: ----
---- NA ----
---- ----
---- Author(s): ----
---- Andrew Mulcock, amulcock@opencores.org ----
---- ----
---- Modified for WR Project by Tomasz Wlostowski ----
----------------------------------------------------------------------------
---- ----
---- Copyright (C) 2008 Authors and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.NUMERIC_STD.all;
use work.genram_pkg.all;
entity generic_shiftreg_fifo is
generic (
Tomasz Wlostowski
committed
g_data_width : integer := 128;
g_size : integer := 32
Tomasz Wlostowski
committed
);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
Tomasz Wlostowski
committed
full_o : out std_logic;
almost_full_o : out std_logic;
q_valid_o : out std_logic
Tomasz Wlostowski
committed
);
end generic_shiftreg_fifo;
architecture rtl of generic_shiftreg_fifo is
Tomasz Wlostowski
committed
component gc_shiftreg
generic (
g_size : integer);
port (
clk_i : in std_logic;
en_i : in std_logic;
d_i : in std_logic;
q_o : out std_logic;
a_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0));
end component;
Tomasz Wlostowski
committed
signal pointer : integer range 0 to g_size-1 := 0;
signal srl_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0) := (others => '0');
signal pointer_zero : std_logic;
signal pointer_full : std_logic;
signal pointer_almost_full : std_logic;
signal empty : std_logic := '1';
signal valid_count : std_logic;
signal do_write : std_logic;
Tomasz Wlostowski
committed
begin
-- Valid write, high when valid to write data to the store.
Tomasz Wlostowski
committed
Tomasz Wlostowski
committed
do_write <= '1' when (rd_i = '1' and we_i = '1')
or (we_i = '1' and pointer_full = '0') else '0';
gen_sregs : for i in 0 to g_data_width-1 generate
U_SRLx : gc_shiftreg
Tomasz Wlostowski
committed
generic map (
g_size => g_size)
port map (
clk_i => clk_i,
en_i => do_write,
d_i => d_i(i),
q_o => q_o(i),
a_i => srl_addr);
end generate gen_sregs;
Tomasz Wlostowski
committed
Tomasz Wlostowski
committed
srl_addr <= std_logic_vector(to_unsigned(pointer, srl_addr'length));
Tomasz Wlostowski
committed
p_empty_logic : process(clk_i)
Tomasz Wlostowski
committed
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
empty <= '1';
elsif empty = '1' and we_i = '1' then
empty <= '0';
elsif pointer_zero = '1' and rd_i = '1' and we_i = '0' then
empty <= '1';
end if;
end if;
end process;
-- W R Action
-- 0 0 pointer <= pointer
-- 0 1 pointer <= pointer - 1 Read, but no write, so less data in counter
-- 1 0 pointer <= pointer + 1 Write, but no read, so more data in fifo
-- 1 1 pointer <= pointer Read and write, so same number of words in fifo
--
valid_count <= '1' when (
(we_i = '1' and rd_i = '0' and pointer_full = '0' and empty = '0')
or
(we_i = '0' and rd_i = '1' and pointer_zero = '0')
) else '0';
Tomasz Wlostowski
committed
p_gen_address : process(clk_i)
Tomasz Wlostowski
committed
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pointer <= 0;
elsif valid_count = '1' then
Tomasz Wlostowski
committed
if we_i = '1' then
pointer <= pointer + 1;
else
pointer <= pointer - 1;
end if;
end if;
end if;
end process;
-- Detect when pointer is zero and maximum
pointer_zero <= '1' when pointer = 0 else '0';
Tomasz Wlostowski
committed
pointer_full <= '1' when pointer = g_size - 1 else '0';
pointer_almost_full <= '1' when pointer_full = '1' or pointer = g_size -3 or pointer = g_size - 2 else '0';
Tomasz Wlostowski
committed
Tomasz Wlostowski
committed
-- assign internal signals to outputs
Tomasz Wlostowski
committed
full_o <= pointer_full;
almost_full_o <= pointer_almost_full;
q_valid_o <= not empty;