diff options
Diffstat (limited to 'testsuite/gna/bug18810/DMEM.vhd')
-rw-r--r-- | testsuite/gna/bug18810/DMEM.vhd | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/testsuite/gna/bug18810/DMEM.vhd b/testsuite/gna/bug18810/DMEM.vhd new file mode 100644 index 000000000..4eb5fe2fc --- /dev/null +++ b/testsuite/gna/bug18810/DMEM.vhd @@ -0,0 +1,243 @@ +-- NOTE: http://www.eecg.toronto.edu/~steffan/papers/laforest_fpga10.pdf + +library ieee; +use ieee.std_logic_1164.all; + +package DMEM_PRIM_PKG is + + component DMEM_PRIM is + generic ( + log2A : integer range 0 to integer'high := 4; + DW : integer range 1 to integer'high := 8; + ZERO : boolean := false + ); + port ( + iWCLK : in std_logic; + iWE : in std_logic; + iWA : in integer range 0 to 2**log2A-1; + iWD : in std_logic_vector(DW-1 downto 0); + + iRA0 : in integer range 0 to 2**log2A-1; + iRA1 : in integer range 0 to 2**log2A-1; + iRA2 : in integer range 0 to 2**log2A-1; + oRD0 : out std_logic_vector(DW-1 downto 0); + oRD1 : out std_logic_vector(DW-1 downto 0); + oRD2 : out std_logic_vector(DW-1 downto 0) + ); + end component DMEM_PRIM; + + constant cDMEM_PRIM_W_LATENCY : integer := 1; + constant cDMEM_PRIM_R0_LATENCY : integer := 0; + constant cDMEM_PRIM_R1_LATENCY : integer := 0; + constant cDMEM_PRIM_R2_LATENCY : integer := 0; + +end package DMEM_PRIM_PKG; + +package body DMEM_PRIM_PKG is + + -- NOTE: This body should keep to be empty to stub. + +end package body DMEM_PRIM_PKG; + +library ieee; +use ieee.std_logic_1164.all; + +entity DMEM_PRIM is + generic ( + log2A : integer range 0 to integer'high := 4; + DW : integer range 1 to integer'high := 8; + ZERO : boolean := false + ); + port ( + iWCLK : in std_logic; + iWE : in std_logic; + iWA : in integer range 0 to 2**log2A-1; + iWD : in std_logic_vector(DW-1 downto 0); + + iRA0 : in integer range 0 to 2**log2A-1; + iRA1 : in integer range 0 to 2**log2A-1; + iRA2 : in integer range 0 to 2**log2A-1; + oRD0 : out std_logic_vector(DW-1 downto 0); + oRD1 : out std_logic_vector(DW-1 downto 0); + oRD2 : out std_logic_vector(DW-1 downto 0) + ); +begin +end entity DMEM_PRIM; + +architecture RTL of DMEM_PRIM is + + type tDMEM_PRIM is array (0 to 2**log2A-1) of std_logic_vector(DW-1 downto 0); + signal aDMEM_PRIM0 : tDMEM_PRIM := (0 to 2**log2A-1 => (DW-1 downto 0 => '0')); + signal aDMEM_PRIM1 : tDMEM_PRIM := (0 to 2**log2A-1 => (DW-1 downto 0 => '0')); + signal aDMEM_PRIM2 : tDMEM_PRIM := (0 to 2**log2A-1 => (DW-1 downto 0 => '0')); + +begin + + P_DMEM_PRIM : process (iWCLK) + begin + if (rising_edge(iWCLK)) then + if (iWE = '1') then + aDMEM_PRIM0(iWA) <= iWD; + aDMEM_PRIM1(iWA) <= iWD; + aDMEM_PRIM2(iWA) <= iWD; + end if; + end if; + end process P_DMEM_PRIM; + + oRD0 <= (DW-1 downto 0 => '0') when (ZERO = true and iRA0 = 0) else aDMEM_PRIM0(iRA0); + oRD1 <= (DW-1 downto 0 => '0') when (ZERO = true and iRA1 = 0) else aDMEM_PRIM1(iRA1); + oRD2 <= (DW-1 downto 0 => '0') when (ZERO = true and iRA2 = 0) else aDMEM_PRIM2(iRA2); + +end architecture RTL; + +library ieee; +use ieee.std_logic_1164.all; +use work.DMEM_PRIM_PKG.all; + +package DMEM_PKG is + + component DMEM is + generic ( + log2DADDR : integer range 0 to integer'high := 4; + DW : integer range 1 to integer'high := 8; + ZERO : boolean := false + ); + port ( + iDCLK : in std_logic; + iDWE : in std_logic; + iDADDR : in integer range 0 to 2**log2DADDR-1; + iDDATA : in std_logic_vector(DW-1 downto 0); + oDDATA : out std_logic_vector(DW-1 downto 0); + + iCLK : in std_logic; + iAADDR : in integer range 0 to 2**log2DADDR-1; + oADATA : out std_logic_vector(DW-1 downto 0); + iBWE : in std_logic; + iBADDR : in integer range 0 to 2**log2DADDR-1; + iBDATA : in std_logic_vector(DW-1 downto 0); + oBDATA : out std_logic_vector(DW-1 downto 0) + ); + end component DMEM; + + constant cDMEM_DW_LATENCY : integer := cDMEM_PRIM_W_LATENCY; + constant cDMEM_DR_LATENCY : integer := cDMEM_PRIM_R0_LATENCY; + constant cDMEM_AR_LATENCY : integer := cDMEM_PRIM_R1_LATENCY; + constant cDMEM_BW_LATENCY : integer := cDMEM_PRIM_W_LATENCY; + constant cDMEM_BR_LATENCY : integer := cDMEM_PRIM_R2_LATENCY; + +end package DMEM_PKG; + +package body DMEM_PKG is + + -- NOTE: This body should keep to be empty to stub. + +end package body DMEM_PKG; + +library ieee; +use ieee.std_logic_1164.all; +use work.DMEM_PRIM_PKG.all; + +entity DMEM is + generic ( + log2DADDR : integer range 0 to integer'high := 4; + DW : integer range 1 to integer'high := 8; + ZERO : boolean := false + ); + port ( + iDCLK : in std_logic; + iDWE : in std_logic; + iDADDR : in integer range 0 to 2**log2DADDR-1; + iDDATA : in std_logic_vector(DW-1 downto 0); + oDDATA : out std_logic_vector(DW-1 downto 0); + + iCLK : in std_logic; + iAADDR : in integer range 0 to 2**log2DADDR-1; + oADATA : out std_logic_vector(DW-1 downto 0); + iBWE : in std_logic; + iBADDR : in integer range 0 to 2**log2DADDR-1; + iBDATA : in std_logic_vector(DW-1 downto 0); + oBDATA : out std_logic_vector(DW-1 downto 0) + ); +begin +end entity DMEM; + +architecture RTL of DMEM is + + -- FIXME: ISE 13.2 does not support "protected"... :( + type tBANK is (BANK_D, BANK_B); + type tLVT is array (0 to 2**log2DADDR-1) of tBANK; + shared variable aLVT : tLVT := (0 to 2**log2DADDR-1 => BANK_D); + + signal sDMEM_PRIM_D_oDDATA : std_logic_vector(DW-1 downto 0); + signal sDMEM_PRIM_D_oADATA : std_logic_vector(DW-1 downto 0); + signal sDMEM_PRIM_D_oBDATA : std_logic_vector(DW-1 downto 0); + + signal sDMEM_PRIM_B_oDDATA : std_logic_vector(DW-1 downto 0); + signal sDMEM_PRIM_B_oADATA : std_logic_vector(DW-1 downto 0); + signal sDMEM_PRIM_B_oBDATA : std_logic_vector(DW-1 downto 0); + +begin + + P_LVT_D : process (iDCLK) + begin + if (rising_edge(iDCLK)) then + if (iDWE = '1') then + aLVT(iDADDR) := BANK_D; + end if; + end if; + end process P_LVT_D; + + P_LVT_B : process (iCLK) + begin + if (rising_edge(iCLK)) then + if (iBWE = '1') then + aLVT(iBADDR) := BANK_B; + end if; + end if; + end process P_LVT_B; + + U_DMEM_PRIM_D : DMEM_PRIM + generic map ( + log2A => log2DADDR, + DW => DW, + ZERO => ZERO + ) + port map ( + iWCLK => iDCLK, + iWE => iDWE, + iWA => iDADDR, + iWD => iDDATA, + + iRA0 => iDADDR, + iRA1 => iAADDR, + iRA2 => iBADDR, + oRD0 => sDMEM_PRIM_D_oDDATA, + oRD1 => sDMEM_PRIM_D_oADATA, + oRD2 => sDMEM_PRIM_D_oBDATA + ); + + U_DMEM_PRIM_B : DMEM_PRIM + generic map ( + log2A => log2DADDR, + DW => DW, + ZERO => ZERO + ) + port map ( + iWCLK => iCLK, + iWE => iBWE, + iWA => iBADDR, + iWD => iBDATA, + + iRA0 => iDADDR, + iRA1 => iAADDR, + iRA2 => iBADDR, + oRD0 => sDMEM_PRIM_B_oDDATA, + oRD1 => sDMEM_PRIM_B_oADATA, + oRD2 => sDMEM_PRIM_B_oBDATA + ); + + oDDATA <= sDMEM_PRIM_D_oDDATA when (aLVT(iDADDR) = BANK_D) else sDMEM_PRIM_B_oDDATA; + oADATA <= sDMEM_PRIM_D_oADATA when (aLVT(iAADDR) = BANK_D) else sDMEM_PRIM_B_oADATA; + oBDATA <= sDMEM_PRIM_D_oBDATA when (aLVT(iBADDR) = BANK_D) else sDMEM_PRIM_B_oBDATA; + +end architecture RTL; |