---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 11:02:29 01/25/2013 -- Design Name: -- Module Name: ddr_wportA - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.std_logic_misc.all; use work.amc13_pack.all; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; Library UNIMACRO; use UNIMACRO.vcomponents.all; entity ddr_wportA is Port ( sysclk : in STD_LOGIC; memclk : in STD_LOGIC; fifo_rst : in STD_LOGIC; fifo_en : in STD_LOGIC; resetSys : in STD_LOGIC; resetMem : in STD_LOGIC; run : in STD_LOGIC; din : in STD_LOGIC_VECTOR (64 downto 0); din_we : in STD_LOGIC; port_rdy : out STD_LOGIC; -- port ready to accept a new event WrtMonBufDone : out STD_LOGIC; buf_full : out STD_LOGIC; event_addr : in STD_LOGIC_VECTOR (16 downto 0); addr_we : in STD_LOGIC; rqst : out STD_LOGIC; -- request to output data ack : in STD_LOGIC; -- permission to output data app_wdf_rdy : in STD_LOGIC; app_rdy : in STD_LOGIC; app_en : out STD_LOGIC; app_wdf_wren : out STD_LOGIC; app_addr : out STD_LOGIC_VECTOR (23 downto 0) := (others => '0'); -- starting address of write burst(1Kbytes or until end of event) dout : out STD_LOGIC_VECTOR (255 downto 0) := (others => '0'); debug : out STD_LOGIC_VECTOR (63 downto 0) ); end ddr_wportA; architecture Behavioral of ddr_wportA is COMPONENT RAM32x6D PORT( wclk : IN std_logic; rclk : IN std_logic; di : IN std_logic_vector(5 downto 0); we : IN std_logic; wa : IN std_logic_vector(4 downto 0); ra : IN std_logic_vector(4 downto 0); ceReg : IN std_logic; do : OUT std_logic_vector(5 downto 0) ); END COMPONENT; --signal addr_queue_a : std_logic_vector(3 downto 0) := (others => '0'); signal AddrQueue_di : std_logic_vector(17 downto 0) := (others => '0'); signal AddrQueue_do : std_logic_vector(17 downto 0) := (others => '0'); signal AddrQueue_wa : std_logic_vector(4 downto 0) := (others => '0'); signal AddrQueue_ra : std_logic_vector(4 downto 0) := (others => '0'); signal AddrQueue_wa0SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal AddrQueue_wa1SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal AddrQueue_ra0SyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal AddrQueue_ra1SyncRegs : std_logic_vector(3 downto 0) := (others => '0'); --signal addr_queue_full : std_logic := '0'; signal en_din : std_logic := '0'; signal rqst_i : std_logic := '0'; --signal got_eoe : std_logic := '0'; --signal got_eoeMem : std_logic := '0'; --signal got_eoeSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); --signal EventDoneSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); --signal en_dinSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal EventDone : std_logic := '0'; signal EventDone_dl : std_logic := '0'; signal EventDataDone : std_logic := '0'; signal FIFO_re : std_logic := '1'; signal FIFO_empty : std_logic := '1'; signal FIFO_AlmostEmpty : std_logic := '1'; signal FIFO_sel : std_logic_vector(1 downto 0) := (others => '0'); signal FIFO_we : std_logic_vector(3 downto 0) := (others => '0'); signal FIFO_DI : std_logic_vector(64 downto 0) := (others => '0'); signal FIFO_DO : std_logic_vector(256 downto 0) := (others => '0'); signal WRCOUNT : array4x9; signal RDCOUNT : array4x9; signal dout_wc : std_logic_vector(4 downto 0) := (others => '0'); signal wc_left : std_logic_vector(4 downto 0) := (others => '0'); signal en_app_en : std_logic := '0'; signal app_wdf_accept : std_logic := '0'; signal app_addr_i : std_logic_vector(10 downto 0) := (others => '0'); signal space_dl : std_logic_vector(4 downto 0) := (others => '0'); begin --debug(10 downto 0) <= buf_wap; --debug(15 downto 11) <= dout_wc; --debug(21 downto 16) <= wc_left; --debug(22) <= en_app_en; --debug(23) <= EventDone; --debug(24) <= EventDataDone; --debug(25) <= got_eoe; --debug(26) <= en_din; --debug(27) <= buf_do_vld; --debug(28) <= dout_vld; --debug(29) <= rqst_i; --debug(30) <= buf_re; --debug(31) <= '0'; --debug(42 downto 32) <= buf_ra; --debug(43) <= '0'; --debug(47 downto 44) <= buf_we; --debug(60 downto 48) <= buf_wa; debug(8) <= en_din; debug(7 downto 0) <= AddrQueue_wa(1 downto 0) & AddrQueue_ra1SyncRegs(2) & AddrQueue_ra0SyncRegs(2) & AddrQueue_ra(1 downto 0) & AddrQueue_wa1SyncRegs(2) & AddrQueue_wa0SyncRegs(2); debug(63 downto 9) <= (others => '0'); rqst <= rqst_i or en_app_en; app_wdf_wren <= ack and rqst_i; app_en <= ack and en_app_en; app_addr <= AddrQueue_do(16 downto 4) & app_addr_i; --port_rdy <= not en_din and not addr_queue_full; --g_addr_queue: for i in 0 to 12 generate -- i_addr_queue : SRL16E -- port map ( -- Q => app_addr(i+11), -- SRL data output -- A0 => addr_queue_a(0), -- Select[0] input -- A1 => addr_queue_a(1), -- Select[1] input -- A2 => addr_queue_a(2), -- Select[2] input -- A3 => addr_queue_a(3), -- Select[3] input -- CE => addr_we, -- Clock enable input -- CLK => sysclk, -- Clock input -- D => event_addr(i+4) -- SRL data input -- ); --end generate; --process(sysclk) --begin -- if(sysclk'event and sysclk = '1')then -- if(resetSys = '1')then -- EventDoneSyncRegs <= (others => '0'); -- else -- EventDoneSyncRegs <= EventDoneSyncRegs(2 downto 0) & EventDone; -- end if; -- end if; --end process; --process(sysclk,run) --begin -- if(run = '0')then -- en_din <= '0'; -- got_eoe <= '0'; -- addr_queue_a <= (others => '1'); -- addr_queue_full <= '0'; -- elsif(sysclk'event and sysclk = '1')then -- if(fifo_en = '0' or (din(64) = '1' and din_we = '1'))then -- en_din <= '0'; -- elsif(addr_we = '1')then -- en_din <= '1'; -- end if; -- if(resetSys = '1' or en_din = '0')then -- got_eoe <= '0'; -- elsif(din(64) = '1' and din_we = '1')then -- got_eoe <= '1'; -- end if; -- if(resetSys = '1')then -- addr_queue_a <= (others => '1'); -- elsif(addr_we = '1' and EventDoneSyncRegs(3 downto 2) /= "01")then -- addr_queue_a <= addr_queue_a + 1; -- elsif(addr_we = '0' and EventDoneSyncRegs(3 downto 2) = "01")then -- addr_queue_a <= addr_queue_a - 1; -- end if; -- if(addr_queue_a(3 downto 1) = "110")then -- addr_queue_full <= '1'; -- else -- addr_queue_full <= '0'; -- end if; -- end if; --end process; g_AddrQueue : for i in 0 to 2 generate i_AddrQueue: RAM32x6D PORT MAP( wclk => sysclk, rclk => memclk, di => AddrQueue_di(i*6+5 downto i*6), we => addr_we, wa => AddrQueue_wa, ra => AddrQueue_ra, ceReg => '1', do => AddrQueue_do(i*6+5 downto i*6) ); end generate; AddrQueue_di <= '0' & event_addr; process(sysclk) variable dist : std_logic_vector(3 downto 0); begin dist := AddrQueue_wa(1 downto 0) & AddrQueue_ra1SyncRegs(2) & AddrQueue_ra0SyncRegs(2); if(sysclk'event and sysclk = '1')then if(fifo_en = '0' or (din(64) = '1' and din_we = '1'))then en_din <= '0'; elsif(addr_we = '1')then en_din <= '1'; end if; if(fifo_en = '0')then AddrQueue_wa <= (others => '0'); elsif(en_din = '1' and din(64) = '1' and din_we = '1')then AddrQueue_wa(1) <= AddrQueue_wa(0); AddrQueue_wa(0) <= not AddrQueue_wa(1); end if; if(fifo_en = '0')then AddrQueue_ra0SyncRegs <= (others => '0'); AddrQueue_ra1SyncRegs <= (others => '0'); else AddrQueue_ra0SyncRegs <= AddrQueue_ra0SyncRegs(2 downto 0) & AddrQueue_ra(0); AddrQueue_ra1SyncRegs <= AddrQueue_ra1SyncRegs(2 downto 0) & AddrQueue_ra(1); end if; space_dl <= space_dl(3 downto 0) & AddrQueue_do(16); if(space_dl(4) = '1' or (AddrQueue_ra1SyncRegs(3) = AddrQueue_ra1SyncRegs(2) and AddrQueue_ra0SyncRegs(3) = AddrQueue_ra0SyncRegs(2)))then WrtMonBufDone <= '0'; else WrtMonBufDone <= '1'; end if; if(en_din = '1')then port_rdy <= '0'; else case dist is when x"1" | x"7" | x"8" | x"e" => port_rdy <= '0'; when others => port_rdy <= '1'; end case; end if; FIFO_DI <= din; if(resetSys = '1' or en_din = '0')then FIFO_sel <= (others => '0'); elsif(din_we = '1')then FIFO_sel <= FIFO_sel + 1; end if; FIFO_we(0) <= en_din and din_we and not FIFO_sel(1) and not FIFO_sel(0); FIFO_we(1) <= en_din and din_we and not FIFO_sel(1) and (din(64) or FIFO_sel(0)); FIFO_we(2) <= en_din and din_we and ((din(64) and not FIFO_sel(1)) or (FIFO_sel(1) and not FIFO_sel(0))); FIFO_we(3) <= en_din and din_we and (din(64) or (FIFO_sel(1) and FIFO_sel(0))); end if; end process; g_FIFO: for i in 0 to 2 generate i_FIFO : FIFO_DUALCLOCK_MACRO generic map ( DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES" ALMOST_FULL_OFFSET => X"0080", -- Sets almost full threshold ALMOST_EMPTY_OFFSET => X"0080", -- Sets the almost empty threshold DATA_WIDTH => 64, -- Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb") FIFO_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb" FIRST_WORD_FALL_THROUGH => TRUE) -- Sets the FIFO FWFT to TRUE or FALSE port map ( ALMOSTEMPTY => open, -- 1-bit output almost empty ALMOSTFULL => open, -- 1-bit output almost full DO => FIFO_DO(i*64+63 downto i*64), -- Output data, width defined by DATA_WIDTH parameter EMPTY => open, -- 1-bit output empty FULL => open, -- 1-bit output full RDCOUNT => RDCOUNT(i), -- Output read count, width determined by FIFO depth RDERR => open, -- 1-bit output read error WRCOUNT => WRCOUNT(i), -- Output write count, width determined by FIFO depth WRERR => open, -- 1-bit output write error DI => FIFO_DI(63 downto 0), -- Input data, width defined by DATA_WIDTH parameter RDCLK => memclk, -- 1-bit input read clock RDEN => FIFO_re, -- 1-bit input read enable RST => fifo_rst, -- 1-bit input reset WRCLK => sysclk, -- 1-bit input write clock WREN => FIFO_we(i) -- 1-bit input write enable ); end generate; i_FIFO3 : FIFO_DUALCLOCK_MACRO generic map ( DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES" ALMOST_FULL_OFFSET => X"0008", -- Sets almost full threshold ALMOST_EMPTY_OFFSET => X"001f", -- Sets the almost empty threshold DATA_WIDTH => 65, -- Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb") FIFO_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb" FIRST_WORD_FALL_THROUGH => TRUE) -- Sets the FIFO FWFT to TRUE or FALSE port map ( ALMOSTEMPTY => FIFO_AlmostEmpty, -- 1-bit output almost empty ALMOSTFULL => buf_full, -- 1-bit output almost full DO => FIFO_DO(256 downto 192), -- Output data, width defined by DATA_WIDTH parameter EMPTY => FIFO_empty, -- 1-bit output empty FULL => open, -- 1-bit output full RDCOUNT => RDCOUNT(3), -- Output read count, width determined by FIFO depth RDERR => open, -- 1-bit output read error WRCOUNT => WRCOUNT(3), -- Output write count, width determined by FIFO depth WRERR => open, -- 1-bit output write error DI => FIFO_DI, -- Input data, width defined by DATA_WIDTH parameter RDCLK => memclk, -- 1-bit input read clock RDEN => FIFO_re, -- 1-bit input read enable RST => fifo_rst, -- 1-bit input reset WRCLK => sysclk, -- 1-bit input write clock WREN => FIFO_we(3) -- 1-bit input write enable ); process(memclk) begin if(memclk'event and memclk = '1')then if(resetMem = '1' or run = '0')then AddrQueue_wa0SyncRegs <= (others => '0'); AddrQueue_wa1SyncRegs <= (others => '0'); AddrQueue_ra <= (others => '0'); -- got_eoeSyncRegs <= (others => '0'); -- got_eoeMem <= '0'; EventDataDone <= '0'; EventDone <= '1'; EventDone_dl <= '1'; rqst_i <= '0'; dout_wc <= (others => '0'); wc_left <= (others => '0'); en_app_en <= '0'; else AddrQueue_wa0SyncRegs <= AddrQueue_wa0SyncRegs(1 downto 0) & AddrQueue_wa(0); AddrQueue_wa1SyncRegs <= AddrQueue_wa1SyncRegs(1 downto 0) & AddrQueue_wa(1); -- if(FIFO_DO(256) = '1' and app_wdf_accept = '1')then if(EventDataDone = '1' and en_app_en = '0')then AddrQueue_ra(1) <= AddrQueue_ra(0); AddrQueue_ra(0) <= not AddrQueue_ra(1); end if; -- if(EventDone = '1')then -- got_eoeSyncRegs <= (others => '0'); -- else -- got_eoeSyncRegs <= got_eoeSyncRegs(2 downto 0) & got_eoe; -- end if; if(FIFO_DO(256) = '1' and app_wdf_accept = '1')then EventDataDone <= '1'; elsif(en_app_en = '0')then EventDataDone <= '0'; end if; -- if(en_dinSyncRegs(3 downto 2) = "01")then if(EventDone = '1' and FIFO_empty = '0')then EventDone <= '0'; elsif(EventDataDone = '1' and en_app_en = '0')then EventDone <= '1'; end if; EventDone_dl <= EventDone; if(EventDataDone = '1' or EventDone = '1' or ((FIFO_DO(256) = '1' or and_reduce(dout_wc) = '1') and app_wdf_accept = '1'))then rqst_i <= '0'; -- elsif(((got_eoeMem = '1' and FIFO_empty = '0') or FIFO_AlmostEmpty = '0') and en_app_en = '0' and fifo_en = '1')then elsif((((AddrQueue_ra(1) /= AddrQueue_wa1SyncRegs(2) or AddrQueue_ra(0) /= AddrQueue_wa0SyncRegs(2)) and FIFO_empty = '0') or FIFO_AlmostEmpty = '0') and en_app_en = '0' and fifo_en = '1')then rqst_i <= '1'; end if; -- if(got_eoeSyncRegs(3 downto 2) = "01")then -- got_eoeMem <= '1'; -- elsif(EventDataDone = '1')then -- got_eoeMem <= '0'; -- end if; if(EventDone = '1')then dout_wc <= (others => '0'); elsif(app_wdf_accept = '1')then dout_wc <= dout_wc + 1; end if; if(EventDone = '1')then wc_left <= (others => '0'); elsif(app_wdf_accept = '1' and (en_app_en = '0' or app_rdy = '0'))then wc_left <= wc_left + 1; elsif(app_wdf_accept = '0' and en_app_en = '1' and app_rdy = '1')then wc_left <= wc_left - 1; end if; if(or_reduce(wc_left(4 downto 1)) = '1' or app_wdf_accept = '1' or (app_rdy = '0' and wc_left(0) = '1'))then en_app_en <= '1'; else en_app_en <= '0'; end if; end if; end if; end process; process(memclk) begin if(memclk'event and memclk = '1')then -- en_dinSyncRegs <= en_dinSyncRegs(2 downto 0) & en_din; -- if(en_dinSyncRegs(3 downto 2) = "01")then if(EventDone_dl = '1')then app_addr_i(6 downto 0) <= (others => '0'); -- app_addr_i(10 downto 7) <= event_addr(3 downto 0); app_addr_i(10 downto 7) <= AddrQueue_do(3 downto 0); elsif(en_app_en = '1' and app_rdy = '1')then app_addr_i(10 downto 0) <= app_addr_i(10 downto 0) + 1; end if; end if; end process; app_wdf_accept <= app_wdf_rdy and ack and rqst_i; dout <= FIFO_DO(255 downto 0); FIFO_re <= app_wdf_accept and not FIFO_empty; end Behavioral;