---------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------
|
-- Copyright (c) 2013 VariStream
|
-- --
|
-- Author : Yu Peng
|
-- Copyright (C) 2013 Author and VariStream Studio --
|
|
-- Author : Yu Peng --
|
|
-- --
|
|
-- 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 --
|
|
-- --
|
|
-------------------------------------------------------------------
|
-- Description:
|
-- Description:
|
-- Implement BRAM according to gADDRESS_WIDTH and gDATA_WIDTH
|
-- Implement BRAM according to gADDRESS_WIDTH and gDATA_WIDTH
|
-- Maxim number of data word is (2**gADDRESS_WIDTH - 1)
|
-- Maxim number of data word is (2**gADDRESS_WIDTH - 1)
|
---------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------
|
|
|
LIBRARY ieee;
|
LIBRARY ieee;
|
USE ieee.std_logic_1164.all;
|
USE ieee.std_logic_1164.all;
|
USE ieee.std_logic_unsigned.all;
|
USE ieee.std_logic_unsigned.all;
|
USE ieee.std_logic_arith.all;
|
USE ieee.std_logic_arith.all;
|
--use synplify.attributes.all;
|
--use synplify.attributes.all;
|
|
|
entity sync_fifo_infer is
|
entity sync_fifo_infer is
|
generic (
|
generic (
|
gADDRESS_WIDTH : integer range 4 to (integer'HIGH) := 8;
|
gADDRESS_WIDTH : integer range 4 to (integer'HIGH) := 8;
|
gDATA_WIDTH : integer := 32;
|
gDATA_WIDTH : integer := 32;
|
gDYNAMIC_PROG_FULL_TH : boolean := false;
|
gDYNAMIC_PROG_FULL_TH : boolean := false;
|
gDYNAMIC_PROG_EMPTY_TH : boolean := false;
|
gDYNAMIC_PROG_EMPTY_TH : boolean := false;
|
gOUTPUT_PIPELINE_NUM : integer range 1 to (integer'HIGH) := 1
|
gOUTPUT_PIPELINE_NUM : integer range 1 to (integer'HIGH) := 1
|
);
|
);
|
port(
|
port(
|
iClk : in std_logic := '0';
|
iClk : in std_logic := '0';
|
iReset_sync : in std_logic := '0';
|
iReset_sync : in std_logic := '0';
|
|
|
ivProgFullTh : in std_logic_vector(gADDRESS_WIDTH-1 downto 0) := conv_std_logic_vector(2**gADDRESS_WIDTH-3, gADDRESS_WIDTH);
|
ivProgFullTh : in std_logic_vector(gADDRESS_WIDTH-1 downto 0) := conv_std_logic_vector(2**gADDRESS_WIDTH-3, gADDRESS_WIDTH);
|
ivProgEmptyTh : in std_logic_vector(gADDRESS_WIDTH-1 downto 0) := conv_std_logic_vector(2, gADDRESS_WIDTH);
|
ivProgEmptyTh : in std_logic_vector(gADDRESS_WIDTH-1 downto 0) := conv_std_logic_vector(2, gADDRESS_WIDTH);
|
|
|
iWrEn : in std_logic := '0';
|
iWrEn : in std_logic := '0';
|
iRdEn : in std_logic := '0';
|
iRdEn : in std_logic := '0';
|
ivDataIn : in std_logic_vector(gDATA_WIDTH-1 downto 0) := (others=>'0');
|
ivDataIn : in std_logic_vector(gDATA_WIDTH-1 downto 0) := (others=>'0');
|
ovDataOut : out std_logic_vector(gDATA_WIDTH-1 downto 0) := (others=>'0');
|
ovDataOut : out std_logic_vector(gDATA_WIDTH-1 downto 0) := (others=>'0');
|
oDataOutValid : out std_logic := '0';
|
oDataOutValid : out std_logic := '0';
|
|
|
oFull : out std_logic := '0';
|
oFull : out std_logic := '0';
|
oEmpty : out std_logic := '1';
|
oEmpty : out std_logic := '1';
|
oAlmostFull : out std_logic := '0';
|
oAlmostFull : out std_logic := '0';
|
oAlmostEmpty : out std_logic := '1';
|
oAlmostEmpty : out std_logic := '1';
|
oProgFull : out std_logic := '0';
|
oProgFull : out std_logic := '0';
|
oProgEmpty : out std_logic := '1';
|
oProgEmpty : out std_logic := '1';
|
|
|
oOverflow : out std_logic := '0';
|
oOverflow : out std_logic := '0';
|
oUnderflow : out std_logic := '0'
|
oUnderflow : out std_logic := '0'
|
);
|
);
|
end sync_fifo_infer;
|
end sync_fifo_infer;
|
|
|
ARCHITECTURE behavioral OF sync_fifo_infer IS
|
ARCHITECTURE behavioral OF sync_fifo_infer IS
|
|
|
component sdpram_infer_read_first_outreg is
|
component sdpram_infer_read_first_outreg is
|
generic (
|
generic (
|
gADDRESS_WIDTH : integer := 5;
|
gADDRESS_WIDTH : integer := 5;
|
gDATA_WIDTH : integer := 24
|
gDATA_WIDTH : integer := 24
|
);
|
);
|
port (
|
port (
|
iClk : in std_logic;
|
iClk : in std_logic;
|
iReset_sync : in std_logic;
|
iReset_sync : in std_logic;
|
iWe : in std_logic;
|
iWe : in std_logic;
|
ivWrAddr : in std_logic_vector(gADDRESS_WIDTH-1 downto 0);
|
ivWrAddr : in std_logic_vector(gADDRESS_WIDTH-1 downto 0);
|
ivRdAddr : in std_logic_vector(gADDRESS_WIDTH-1 downto 0);
|
ivRdAddr : in std_logic_vector(gADDRESS_WIDTH-1 downto 0);
|
ivDataIn : in std_logic_vector(gDATA_WIDTH-1 downto 0);
|
ivDataIn : in std_logic_vector(gDATA_WIDTH-1 downto 0);
|
ovDataOut : out std_logic_vector(gDATA_WIDTH-1 downto 0)
|
ovDataOut : out std_logic_vector(gDATA_WIDTH-1 downto 0)
|
);
|
);
|
end component;
|
end component;
|
|
|
component sdpram_infer_read_first_outreset is
|
component sdpram_infer_read_first_outreset is
|
generic (
|
generic (
|
gADDRESS_WIDTH : integer := 5;
|
gADDRESS_WIDTH : integer := 5;
|
gDATA_WIDTH : integer := 24
|
gDATA_WIDTH : integer := 24
|
);
|
);
|
port (
|
port (
|
iClk : in std_logic;
|
iClk : in std_logic;
|
iReset_sync : in std_logic;
|
iReset_sync : in std_logic;
|
iWe : in std_logic;
|
iWe : in std_logic;
|
ivWrAddr : in std_logic_vector(gADDRESS_WIDTH-1 downto 0);
|
ivWrAddr : in std_logic_vector(gADDRESS_WIDTH-1 downto 0);
|
ivRdAddr : in std_logic_vector(gADDRESS_WIDTH-1 downto 0);
|
ivRdAddr : in std_logic_vector(gADDRESS_WIDTH-1 downto 0);
|
ivDataIn : in std_logic_vector(gDATA_WIDTH-1 downto 0);
|
ivDataIn : in std_logic_vector(gDATA_WIDTH-1 downto 0);
|
ovDataOut : out std_logic_vector(gDATA_WIDTH-1 downto 0)
|
ovDataOut : out std_logic_vector(gDATA_WIDTH-1 downto 0)
|
);
|
);
|
end component;
|
end component;
|
|
|
component pipelines_without_reset IS
|
component pipelines_without_reset IS
|
GENERIC (gBUS_WIDTH : integer := 1; gNB_PIPELINES: integer range 1 to 255 := 2);
|
GENERIC (gBUS_WIDTH : integer := 1; gNB_PIPELINES: integer range 1 to 255 := 2);
|
PORT(
|
PORT(
|
iClk : IN STD_LOGIC;
|
iClk : IN STD_LOGIC;
|
iInput : IN STD_LOGIC;
|
iInput : IN STD_LOGIC;
|
ivInput : IN STD_LOGIC_VECTOR(gBUS_WIDTH-1 downto 0);
|
ivInput : IN STD_LOGIC_VECTOR(gBUS_WIDTH-1 downto 0);
|
oDelayed_output : OUT STD_LOGIC;
|
oDelayed_output : OUT STD_LOGIC;
|
ovDelayed_output : OUT STD_LOGIC_VECTOR(gBUS_WIDTH-1 downto 0)
|
ovDelayed_output : OUT STD_LOGIC_VECTOR(gBUS_WIDTH-1 downto 0)
|
);
|
);
|
END component;
|
END component;
|
|
|
signal svWriteAddr : std_logic_vector(gADDRESS_WIDTH-1 downto 0) := (others=>'0');
|
signal svWriteAddr : std_logic_vector(gADDRESS_WIDTH-1 downto 0) := (others=>'0');
|
signal svReadAddr : std_logic_vector(gADDRESS_WIDTH-1 downto 0) := (others=>'0');
|
signal svReadAddr : std_logic_vector(gADDRESS_WIDTH-1 downto 0) := (others=>'0');
|
signal sEffectiveWrEn : std_logic := '0';
|
signal sEffectiveWrEn : std_logic := '0';
|
signal sEffectiveRdEn : std_logic := '0';
|
signal sEffectiveRdEn : std_logic := '0';
|
signal svFifoCount : std_logic_vector(gADDRESS_WIDTH-1 downto 0) := (others=>'0');
|
signal svFifoCount : std_logic_vector(gADDRESS_WIDTH-1 downto 0) := (others=>'0');
|
signal svProgFullThM1 : std_logic_vector(gADDRESS_WIDTH-1 downto 0) := conv_std_logic_vector(2**gADDRESS_WIDTH-4, gADDRESS_WIDTH);
|
signal svProgFullThM1 : std_logic_vector(gADDRESS_WIDTH-1 downto 0) := conv_std_logic_vector(2**gADDRESS_WIDTH-4, gADDRESS_WIDTH);
|
signal svProgEmptyThP1 : std_logic_vector(gADDRESS_WIDTH-1 downto 0) := conv_std_logic_vector(3, gADDRESS_WIDTH);
|
signal svProgEmptyThP1 : std_logic_vector(gADDRESS_WIDTH-1 downto 0) := conv_std_logic_vector(3, gADDRESS_WIDTH);
|
signal sFifoFull : std_logic := '0';
|
signal sFifoFull : std_logic := '0';
|
signal sFifoEmpty : std_logic := '1';
|
signal sFifoEmpty : std_logic := '1';
|
signal sAlmostFull : std_logic := '0';
|
signal sAlmostFull : std_logic := '0';
|
signal sAlmostEmpty : std_logic := '1';
|
signal sAlmostEmpty : std_logic := '1';
|
signal sProgFull : std_logic := '0';
|
signal sProgFull : std_logic := '0';
|
signal sProgEmpty : std_logic := '1';
|
signal sProgEmpty : std_logic := '1';
|
signal sFifoOverflow : std_logic := '0';
|
signal sFifoOverflow : std_logic := '0';
|
signal sFifoUnderflow : std_logic := '0';
|
signal sFifoUnderflow : std_logic := '0';
|
|
|
signal svMemDataOut : std_logic_vector(gDATA_WIDTH-1 downto 0) := (others=>'0');
|
signal svMemDataOut : std_logic_vector(gDATA_WIDTH-1 downto 0) := (others=>'0');
|
signal sMemDataOutValid : std_logic := '0';
|
signal sMemDataOutValid : std_logic := '0';
|
signal svPipeDataOut : std_logic_vector(gDATA_WIDTH-1 downto 0) := (others=>'0');
|
signal svPipeDataOut : std_logic_vector(gDATA_WIDTH-1 downto 0) := (others=>'0');
|
signal sPipeDataOutValid: std_logic := '0';
|
signal sPipeDataOutValid: std_logic := '0';
|
|
|
|
|
BEGIN
|
BEGIN
|
sdpram_gen_1: if gOUTPUT_PIPELINE_NUM = 1 generate
|
sdpram_gen_1: if gOUTPUT_PIPELINE_NUM = 1 generate
|
sdpram_inst: sdpram_infer_read_first_outreset
|
sdpram_inst: sdpram_infer_read_first_outreset
|
generic map(
|
generic map(
|
gADDRESS_WIDTH => gADDRESS_WIDTH,
|
gADDRESS_WIDTH => gADDRESS_WIDTH,
|
gDATA_WIDTH => gDATA_WIDTH
|
gDATA_WIDTH => gDATA_WIDTH
|
)
|
)
|
port map(
|
port map(
|
iClk => iClk,
|
iClk => iClk,
|
iReset_sync => iReset_sync,
|
iReset_sync => iReset_sync,
|
iWe => iWrEn,
|
iWe => iWrEn,
|
ivWrAddr => svWriteAddr,
|
ivWrAddr => svWriteAddr,
|
ivRdAddr => svReadAddr,
|
ivRdAddr => svReadAddr,
|
ivDataIn => ivDataIn,
|
ivDataIn => ivDataIn,
|
ovDataOut => svMemDataOut
|
ovDataOut => svMemDataOut
|
);
|
);
|
|
|
process(iClk)
|
process(iClk)
|
begin
|
begin
|
if rising_edge(iClk) then
|
if rising_edge(iClk) then
|
if iReset_sync = '1' then
|
if iReset_sync = '1' then
|
sMemDataOutValid <= '0';
|
sMemDataOutValid <= '0';
|
else
|
else
|
sMemDataOutValid <= iRdEn;
|
sMemDataOutValid <= iRdEn;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
end generate;
|
end generate;
|
|
|
sdpram_gen_others: if gOUTPUT_PIPELINE_NUM > 1 generate
|
sdpram_gen_others: if gOUTPUT_PIPELINE_NUM > 1 generate
|
sdpram_inst: sdpram_infer_read_first_outreg
|
sdpram_inst: sdpram_infer_read_first_outreg
|
generic map(
|
generic map(
|
gADDRESS_WIDTH => gADDRESS_WIDTH,
|
gADDRESS_WIDTH => gADDRESS_WIDTH,
|
gDATA_WIDTH => gDATA_WIDTH
|
gDATA_WIDTH => gDATA_WIDTH
|
)
|
)
|
port map(
|
port map(
|
iClk => iClk,
|
iClk => iClk,
|
iReset_sync => iReset_sync,
|
iReset_sync => iReset_sync,
|
iWe => iWrEn,
|
iWe => iWrEn,
|
ivWrAddr => svWriteAddr,
|
ivWrAddr => svWriteAddr,
|
ivRdAddr => svReadAddr,
|
ivRdAddr => svReadAddr,
|
ivDataIn => ivDataIn,
|
ivDataIn => ivDataIn,
|
ovDataOut => svMemDataOut
|
ovDataOut => svMemDataOut
|
);
|
);
|
|
|
process(iClk)
|
process(iClk)
|
begin
|
begin
|
if rising_edge(iClk) then
|
if rising_edge(iClk) then
|
sMemDataOutValid <= iRdEn;
|
sMemDataOutValid <= iRdEn;
|
end if;
|
end if;
|
end process;
|
end process;
|
end generate;
|
end generate;
|
|
|
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
-- Generate the write and read pointers
|
-- Generate the write and read pointers
|
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
process(iClk)
|
process(iClk)
|
begin
|
begin
|
if rising_edge(iClk) then
|
if rising_edge(iClk) then
|
if iReset_sync = '1' then
|
if iReset_sync = '1' then
|
svWriteAddr <= (others=>'0');
|
svWriteAddr <= (others=>'0');
|
elsif sEffectiveWrEn = '1' then
|
elsif sEffectiveWrEn = '1' then
|
svWriteAddr <= svWriteAddr + '1';
|
svWriteAddr <= svWriteAddr + '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
process(iClk)
|
process(iClk)
|
begin
|
begin
|
if rising_edge(iClk) then
|
if rising_edge(iClk) then
|
if iReset_sync = '1' then
|
if iReset_sync = '1' then
|
svReadAddr <= (others=>'0');
|
svReadAddr <= (others=>'0');
|
elsif sEffectiveRdEn = '1' then
|
elsif sEffectiveRdEn = '1' then
|
svReadAddr <= svReadAddr + '1';
|
svReadAddr <= svReadAddr + '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
-- Generate Fifo Flags
|
-- Generate Fifo Flags
|
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
sEffectiveWrEn <= iWrEn and (not sFifoFull);
|
sEffectiveWrEn <= iWrEn and (not sFifoFull);
|
sEffectiveRdEn <= iRdEn and (not sFifoEmpty);
|
sEffectiveRdEn <= iRdEn and (not sFifoEmpty);
|
|
|
ProgFullThM1_gen_dynamic : if gDYNAMIC_PROG_FULL_TH = true generate
|
ProgFullThM1_gen_dynamic : if gDYNAMIC_PROG_FULL_TH = true generate
|
process (iClk)
|
process (iClk)
|
begin
|
begin
|
if rising_edge(iClk) then
|
if rising_edge(iClk) then
|
svProgFullThM1 <= ivProgFullTh - '1';
|
svProgFullThM1 <= ivProgFullTh - '1';
|
end if;
|
end if;
|
end process;
|
end process;
|
end generate;
|
end generate;
|
|
|
ProgFullThM1_gen_static : if gDYNAMIC_PROG_FULL_TH = false generate
|
ProgFullThM1_gen_static : if gDYNAMIC_PROG_FULL_TH = false generate
|
svProgFullThM1 <= ivProgFullTh - '1';
|
svProgFullThM1 <= ivProgFullTh - '1';
|
end generate;
|
end generate;
|
|
|
ProgEmptyThM1_gen_dynamic : if gDYNAMIC_PROG_EMPTY_TH = true generate
|
ProgEmptyThM1_gen_dynamic : if gDYNAMIC_PROG_EMPTY_TH = true generate
|
process (iClk)
|
process (iClk)
|
begin
|
begin
|
if rising_edge(iClk) then
|
if rising_edge(iClk) then
|
svProgEmptyThP1 <= ivProgEmptyTh + '1';
|
svProgEmptyThP1 <= ivProgEmptyTh + '1';
|
end if;
|
end if;
|
end process;
|
end process;
|
end generate;
|
end generate;
|
|
|
ProgEmptyThM1_gen_static : if gDYNAMIC_PROG_EMPTY_TH = false generate
|
ProgEmptyThM1_gen_static : if gDYNAMIC_PROG_EMPTY_TH = false generate
|
svProgEmptyThP1 <= ivProgEmptyTh + '1';
|
svProgEmptyThP1 <= ivProgEmptyTh + '1';
|
end generate;
|
end generate;
|
|
|
process (iClk)
|
process (iClk)
|
begin
|
begin
|
if rising_edge(iClk) then
|
if rising_edge(iClk) then
|
if (iReset_sync = '1') then
|
if (iReset_sync = '1') then
|
svFifoCount <= (others => '0');
|
svFifoCount <= (others => '0');
|
sFifoFull <= '0';
|
sFifoFull <= '0';
|
sFifoEmpty <= '1';
|
sFifoEmpty <= '1';
|
sAlmostFull <= '0';
|
sAlmostFull <= '0';
|
sAlmostEmpty <= '1';
|
sAlmostEmpty <= '1';
|
sProgFull <= '0';
|
sProgFull <= '0';
|
sProgEmpty <= '1';
|
sProgEmpty <= '1';
|
|
|
sFifoOverflow <= '0';
|
sFifoOverflow <= '0';
|
sFifoUnderflow <= '0';
|
sFifoUnderflow <= '0';
|
else
|
else
|
-- Fifo count when it is read or written
|
-- Fifo count when it is read or written
|
if (sEffectiveWrEn = '1') and (sEffectiveRdEn = '0') then
|
if (sEffectiveWrEn = '1') and (sEffectiveRdEn = '0') then
|
svFifoCount <= svFifoCount + '1';
|
svFifoCount <= svFifoCount + '1';
|
elsif (sEffectiveWrEn = '0') and (sEffectiveRdEn = '1') then
|
elsif (sEffectiveWrEn = '0') and (sEffectiveRdEn = '1') then
|
svFifoCount <= svFifoCount - '1';
|
svFifoCount <= svFifoCount - '1';
|
end if;
|
end if;
|
|
|
if svFifoCount = conv_std_logic_vector((2**gADDRESS_WIDTH)-2, gADDRESS_WIDTH) then
|
if svFifoCount = conv_std_logic_vector((2**gADDRESS_WIDTH)-2, gADDRESS_WIDTH) then
|
if (iWrEn = '1') and (iRdEn = '0') then
|
if (iWrEn = '1') and (iRdEn = '0') then
|
sFifoFull <= '1';
|
sFifoFull <= '1';
|
else
|
else
|
sFifoFull <= '0';
|
sFifoFull <= '0';
|
end if;
|
end if;
|
elsif svFifoCount = conv_std_logic_vector((2**gADDRESS_WIDTH)-1, gADDRESS_WIDTH) then
|
elsif svFifoCount = conv_std_logic_vector((2**gADDRESS_WIDTH)-1, gADDRESS_WIDTH) then
|
if iRdEn = '1' then
|
if iRdEn = '1' then
|
sFifoFull <= '0';
|
sFifoFull <= '0';
|
else
|
else
|
sFifoFull <= '1';
|
sFifoFull <= '1';
|
end if;
|
end if;
|
else
|
else
|
sFifoFull <= '0';
|
sFifoFull <= '0';
|
end if;
|
end if;
|
|
|
if svFifoCount = conv_std_logic_vector(1, gADDRESS_WIDTH) then
|
if svFifoCount = conv_std_logic_vector(1, gADDRESS_WIDTH) then
|
if (iWrEn = '0') and (iRdEn = '1') then
|
if (iWrEn = '0') and (iRdEn = '1') then
|
sFifoEmpty <= '1';
|
sFifoEmpty <= '1';
|
else
|
else
|
sFifoEmpty <= '0';
|
sFifoEmpty <= '0';
|
end if;
|
end if;
|
elsif svFifoCount = conv_std_logic_vector(0, gADDRESS_WIDTH) then
|
elsif svFifoCount = conv_std_logic_vector(0, gADDRESS_WIDTH) then
|
if (iWrEn = '1') then
|
if (iWrEn = '1') then
|
sFifoEmpty <= '0';
|
sFifoEmpty <= '0';
|
else
|
else
|
sFifoEmpty <= '1';
|
sFifoEmpty <= '1';
|
end if;
|
end if;
|
else
|
else
|
sFifoEmpty <= '0';
|
sFifoEmpty <= '0';
|
end if;
|
end if;
|
|
|
if svFifoCount = conv_std_logic_vector((2**gADDRESS_WIDTH)-3, gADDRESS_WIDTH) then
|
if svFifoCount = conv_std_logic_vector((2**gADDRESS_WIDTH)-3, gADDRESS_WIDTH) then
|
if (iWrEn = '1') and (iRdEn = '0') then
|
if (iWrEn = '1') and (iRdEn = '0') then
|
sAlmostFull <= '1';
|
sAlmostFull <= '1';
|
else
|
else
|
sAlmostFull <= '0';
|
sAlmostFull <= '0';
|
end if;
|
end if;
|
elsif svFifoCount = conv_std_logic_vector((2**gADDRESS_WIDTH)-2, gADDRESS_WIDTH) then
|
elsif svFifoCount = conv_std_logic_vector((2**gADDRESS_WIDTH)-2, gADDRESS_WIDTH) then
|
if (iWrEn = '0') and (iRdEn = '1') then
|
if (iWrEn = '0') and (iRdEn = '1') then
|
sAlmostFull <= '0';
|
sAlmostFull <= '0';
|
else
|
else
|
sAlmostFull <= '1';
|
sAlmostFull <= '1';
|
end if;
|
end if;
|
elsif svFifoCount = conv_std_logic_vector((2**gADDRESS_WIDTH)-1, gADDRESS_WIDTH) then
|
elsif svFifoCount = conv_std_logic_vector((2**gADDRESS_WIDTH)-1, gADDRESS_WIDTH) then
|
sAlmostFull <= '1';
|
sAlmostFull <= '1';
|
else
|
else
|
sAlmostFull <= '0';
|
sAlmostFull <= '0';
|
end if;
|
end if;
|
|
|
if svFifoCount = conv_std_logic_vector(2, gADDRESS_WIDTH) then
|
if svFifoCount = conv_std_logic_vector(2, gADDRESS_WIDTH) then
|
if (iWrEn = '0') and (iRdEn = '1') then
|
if (iWrEn = '0') and (iRdEn = '1') then
|
sAlmostEmpty <= '1';
|
sAlmostEmpty <= '1';
|
else
|
else
|
sAlmostEmpty <= '0';
|
sAlmostEmpty <= '0';
|
end if;
|
end if;
|
elsif svFifoCount = conv_std_logic_vector(1, gADDRESS_WIDTH) then
|
elsif svFifoCount = conv_std_logic_vector(1, gADDRESS_WIDTH) then
|
if (iWrEn = '1') and (iRdEn = '0') then
|
if (iWrEn = '1') and (iRdEn = '0') then
|
sAlmostEmpty <= '0';
|
sAlmostEmpty <= '0';
|
else
|
else
|
sAlmostEmpty <= '1';
|
sAlmostEmpty <= '1';
|
end if;
|
end if;
|
elsif svFifoCount = conv_std_logic_vector(0, gADDRESS_WIDTH) then
|
elsif svFifoCount = conv_std_logic_vector(0, gADDRESS_WIDTH) then
|
sAlmostEmpty <= '1';
|
sAlmostEmpty <= '1';
|
else
|
else
|
sAlmostEmpty <= '0';
|
sAlmostEmpty <= '0';
|
end if;
|
end if;
|
|
|
if svFifoCount = svProgFullThM1 then
|
if svFifoCount = svProgFullThM1 then
|
if (iWrEn = '1') and (iRdEn = '0') then
|
if (iWrEn = '1') and (iRdEn = '0') then
|
sProgFull <= '1';
|
sProgFull <= '1';
|
else
|
else
|
sProgFull <= '0';
|
sProgFull <= '0';
|
end if;
|
end if;
|
elsif svFifoCount = ivProgFullTh then
|
elsif svFifoCount = ivProgFullTh then
|
if (iWrEn = '0') and (iRdEn = '1') then
|
if (iWrEn = '0') and (iRdEn = '1') then
|
sProgFull <= '0';
|
sProgFull <= '0';
|
else
|
else
|
sProgFull <= '1';
|
sProgFull <= '1';
|
end if;
|
end if;
|
elsif svFifoCount > ivProgFullTh then
|
elsif svFifoCount > ivProgFullTh then
|
sProgFull <= '1';
|
sProgFull <= '1';
|
else
|
else
|
sProgFull <= '0';
|
sProgFull <= '0';
|
end if;
|
end if;
|
|
|
if svFifoCount = svProgEmptyThP1 then
|
if svFifoCount = svProgEmptyThP1 then
|
if (iWrEn = '0') and (iRdEn = '1') then
|
if (iWrEn = '0') and (iRdEn = '1') then
|
sProgEmpty <= '1';
|
sProgEmpty <= '1';
|
else
|
else
|
sProgEmpty <= '0';
|
sProgEmpty <= '0';
|
end if;
|
end if;
|
elsif svFifoCount = ivProgEmptyTh then
|
elsif svFifoCount = ivProgEmptyTh then
|
if (iWrEn = '1') and (iRdEn = '0') then
|
if (iWrEn = '1') and (iRdEn = '0') then
|
sProgEmpty <= '0';
|
sProgEmpty <= '0';
|
else
|
else
|
sProgEmpty <= '1';
|
sProgEmpty <= '1';
|
end if;
|
end if;
|
elsif svFifoCount < ivProgEmptyTh then
|
elsif svFifoCount < ivProgEmptyTh then
|
sProgEmpty <= '1';
|
sProgEmpty <= '1';
|
else
|
else
|
sProgEmpty <= '0';
|
sProgEmpty <= '0';
|
end if;
|
end if;
|
--------------------------------
|
--------------------------------
|
-- Generate the error flag
|
-- Generate the error flag
|
-------------------------------
|
-------------------------------
|
if sFifoFull = '1' and iWrEn = '1' then
|
if sFifoFull = '1' and iWrEn = '1' then
|
sFifoOverflow <= '1';
|
sFifoOverflow <= '1';
|
end if;
|
end if;
|
|
|
if sFifoEmpty = '1' and iRdEn = '1' then
|
if sFifoEmpty = '1' and iRdEn = '1' then
|
sFifoUnderflow <= '1';
|
sFifoUnderflow <= '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
oFull <= sFifoFull;
|
oFull <= sFifoFull;
|
oEmpty <= sFifoEmpty;
|
oEmpty <= sFifoEmpty;
|
oAlmostFull <= sAlmostFull;
|
oAlmostFull <= sAlmostFull;
|
oAlmostEmpty <= sAlmostEmpty;
|
oAlmostEmpty <= sAlmostEmpty;
|
oProgFull <= sProgFull;
|
oProgFull <= sProgFull;
|
oProgEmpty <= sProgEmpty;
|
oProgEmpty <= sProgEmpty;
|
oOverflow <= sFifoOverflow;
|
oOverflow <= sFifoOverflow;
|
oUnderflow <= sFifoUnderflow;
|
oUnderflow <= sFifoUnderflow;
|
|
|
-------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------
|
-- This section generates the code for the output pipelines
|
-- This section generates the code for the output pipelines
|
-------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------
|
OutputPipeline_gen_1: if gOUTPUT_PIPELINE_NUM = 1 generate
|
OutputPipeline_gen_1: if gOUTPUT_PIPELINE_NUM = 1 generate
|
ovDataOut <= svMemDataOut;
|
ovDataOut <= svMemDataOut;
|
oDataOutValid <= sMemDataOutValid;
|
oDataOutValid <= sMemDataOutValid;
|
end generate;
|
end generate;
|
|
|
OutputPipeline_gen_2: if gOUTPUT_PIPELINE_NUM = 2 generate
|
OutputPipeline_gen_2: if gOUTPUT_PIPELINE_NUM = 2 generate
|
process (iClk)
|
process (iClk)
|
begin
|
begin
|
if rising_edge(iClk) then
|
if rising_edge(iClk) then
|
if (iReset_sync = '1') then
|
if (iReset_sync = '1') then
|
ovDataOut <= (others=>'0');
|
ovDataOut <= (others=>'0');
|
oDataOutValid <= '0';
|
oDataOutValid <= '0';
|
else
|
else
|
ovDataOut <= svMemDataOut;
|
ovDataOut <= svMemDataOut;
|
oDataOutValid <= sMemDataOutValid;
|
oDataOutValid <= sMemDataOutValid;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
end generate;
|
end generate;
|
|
|
OutputPipeline_gen_others: if gOUTPUT_PIPELINE_NUM > 2 generate
|
OutputPipeline_gen_others: if gOUTPUT_PIPELINE_NUM > 2 generate
|
pipelines_without_reset_inst_output: pipelines_without_reset
|
pipelines_without_reset_inst_output: pipelines_without_reset
|
GENERIC map(
|
GENERIC map(
|
gBUS_WIDTH => gDATA_WIDTH,
|
gBUS_WIDTH => gDATA_WIDTH,
|
gNB_PIPELINES => (gOUTPUT_PIPELINE_NUM-1)
|
gNB_PIPELINES => (gOUTPUT_PIPELINE_NUM-1)
|
)
|
)
|
PORT map(
|
PORT map(
|
iClk => iClk,
|
iClk => iClk,
|
iInput => sMemDataOutValid,
|
iInput => sMemDataOutValid,
|
ivInput => svMemDataOut,
|
ivInput => svMemDataOut,
|
oDelayed_output => sPipeDataOutValid,
|
oDelayed_output => sPipeDataOutValid,
|
ovDelayed_output => svPipeDataOut
|
ovDelayed_output => svPipeDataOut
|
);
|
);
|
|
|
process (iClk)
|
process (iClk)
|
begin
|
begin
|
if rising_edge(iClk) then
|
if rising_edge(iClk) then
|
if (iReset_sync = '1') then
|
if (iReset_sync = '1') then
|
ovDataOut <= (others=>'0');
|
ovDataOut <= (others=>'0');
|
oDataOutValid <= '0';
|
oDataOutValid <= '0';
|
else
|
else
|
ovDataOut <= svPipeDataOut;
|
ovDataOut <= svPipeDataOut;
|
oDataOutValid <= sPipeDataOutValid;
|
oDataOutValid <= sPipeDataOutValid;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
end generate;
|
end generate;
|
|
|
END behavioral;
|
END behavioral;
|
|
|
|
|
|
|
|
|