---------------------------------------------------------------------------------- -- 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 (65 downto 0); din_we : in STD_LOGIC; port_rdy : out STD_LOGIC; -- port ready to accept a new event WrtMonBlkDone : out STD_LOGIC; WrtMonEvtDone : out STD_LOGIC; KiloByte_toggle : out STD_LOGIC; EoB_toggle : out STD_LOGIC; buf_full : out STD_LOGIC; event_addr : in STD_LOGIC_VECTOR (13 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'); cs_out : out STD_LOGIC_VECTOR (511 downto 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 AddrQueue_di : std_logic_vector(13 downto 0) := (others => '0'); signal AddrQueue_do : std_logic_vector(13 downto 0) := (others => '0'); signal AddrQueue_dop : std_logic_vector(13 downto 12) := (others => '0'); signal AddrQueue_wa : std_logic_vector(4 downto 0) := (others => '0'); signal AddrQueue_rap : std_logic_vector(1 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 EoE_toggleSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal EoB_toggleSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal en_din : std_logic := '0'; signal rqst_i : std_logic := '0'; signal KiloByte_toggle_i : std_logic := '0'; signal EoB_toggle_i : std_logic := '0'; signal EoE_toggle_i : std_logic := '0'; signal last_word : std_logic := '0'; signal EventDone : std_logic := '0'; signal EventDone_dl : std_logic := '0'; signal FIFO_empty : std_logic := '1'; --signal FIFO_empty_q : 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(65 downto 0) := (others => '0'); signal FIFO_DO : std_logic_vector(257 downto 0) := (others => '0'); signal WRCOUNT : array4x9; signal RDCOUNT : array4x9; signal dout_wc : std_logic_vector(4 downto 0) := (others => '0'); signal app_wren : std_logic := '0'; signal app_addr_i : std_logic_vector(13 downto 0) := (others => '0'); begin --process(memclk) --begin -- if(memclk'event and memclk = '1')then -- cs_out(39) <= rqst_i and ack and fifo_empty; -- cs_out(38) <= rqst_i and fifo_empty; -- end if; --end process; cs_out(42) <= app_wdf_rdy; cs_out(41) <= app_rdy; cs_out(40) <= ack; cs_out(37) <= din(64); cs_out(36) <= din_we; cs_out(35) <= en_din; cs_out(34 downto 31) <= FIFO_we; cs_out(30 downto 29) <= FIFO_sel; cs_out(28 downto 25) <= EoE_toggleSyncRegs; cs_out(24 downto 23) <= AddrQueue_rap; cs_out(22 downto 21) <= AddrQueue_wa(1 downto 0); cs_out(20) <= EoE_toggle_i; cs_out(19) <= EoB_toggle_i; cs_out(18) <= rqst_i; cs_out(17) <= EventDone; cs_out(16) <= last_word; cs_out(15) <= FIFO_DO(256); cs_out(14) <= FIFO_AlmostEmpty; cs_out(13) <= FIFO_empty; cs_out(12 downto 10) <= AddrQueue_wa0SyncRegs; cs_out(9 downto 7) <= AddrQueue_wa1SyncRegs; cs_out(6 downto 5) <= AddrQueue_ra(1 downto 0); cs_out(4 downto 0) <= dout_wc; --cs_out(14) <= rqst_i; --cs_out(13) <= EventDone; --cs_out(12) <= last_word; --cs_out(11) <= FIFO_DO(256); --cs_out(10) <= FIFO_AlmostEmpty; --cs_out(9) <= FIFO_empty; --cs_out(8) <= AddrQueue_wa0SyncRegs(2); --cs_out(7) <= AddrQueue_wa1SyncRegs(2); --cs_out(6 downto 5) <= AddrQueue_ra(1 downto 0); --cs_out(4 downto 0) <= dout_wc; debug(63 downto 1) <= (others => '0'); process(memclk) begin if(memclk'event and memclk = '1')then if(resetMem = '1')then debug(0) <= '0'; elsif(ack = '1' and fifo_empty = '1')then debug(0) <= '1'; end if; end if; end process; KiloByte_toggle <= KiloByte_toggle_i; EoB_toggle <= EoB_toggle_i; rqst <= '0' when rqst_i = '0' or ((FIFO_DO(256) = '1' or last_word = '1') and app_wren = '1') else '1'; app_wdf_wren <= app_wren; app_en <= app_wren; --app_wren <= ack and app_rdy and app_wdf_rdy and not FIFO_empty and not FIFO_empty_q; app_wren <= ack and app_rdy and app_wdf_rdy; app_addr <= AddrQueue_do(13 downto 4) & app_addr_i; g_AddrQueue : for i in 0 to 1 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) ); i_AddrQueueH : RAM32X1D port map ( DPO => AddrQueue_dop(i+12), -- Read-only 1-bit data output SPO => open, -- R/W 1-bit data output A0 => AddrQueue_wa(0), -- R/W address[0] input bit A1 => AddrQueue_wa(1), -- R/W address[1] input bit A2 => AddrQueue_wa(2), -- R/W address[2] input bit A3 => AddrQueue_wa(3), -- R/W address[3] input bit A4 => AddrQueue_wa(4), -- R/W address[4] input bit D => AddrQueue_di(i+12), -- Write 1-bit data input DPRA0 => AddrQueue_ra(0), -- Read-only address[0] input bit DPRA1 => AddrQueue_ra(1), -- Read-only address[1] input bit DPRA2 => AddrQueue_ra(2), -- Read-only address[2] input bit DPRA3 => AddrQueue_ra(3), -- Read-only address[3] input bit DPRA4 => AddrQueue_ra(4), -- Read-only address[4] input bit WCLK => sysclk, -- Write clock input WE => addr_we -- Write enable input ); end generate; process(memclk) begin if(memclk'event and memclk = '1')then AddrQueue_do(13 downto 12) <= AddrQueue_dop(13 downto 12); end if; end process; AddrQueue_di <= event_addr; process(sysclk, AddrQueue_wa, AddrQueue_rap) variable dist : std_logic_vector(3 downto 0); begin dist := AddrQueue_wa(1 downto 0) & AddrQueue_rap; 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_rap <= (others => '0'); elsif(EoB_toggleSyncRegs(3) /= EoB_toggleSyncRegs(2))then AddrQueue_rap(1) <= AddrQueue_rap(0); AddrQueue_rap(0) <= not AddrQueue_rap(1); end if; EoB_toggleSyncRegs <= EoB_toggleSyncRegs(2 downto 0) & EoB_toggle_i; EoE_toggleSyncRegs <= EoE_toggleSyncRegs(2 downto 0) & EoE_toggle_i; if(resetSys = '1' or EoB_toggleSyncRegs(3) = EoB_toggleSyncRegs(2))then WrtMonBlkDone <= '0'; else WrtMonBlkDone <= '1'; end if; if(resetSys = '1' or EoE_toggleSyncRegs(3) = EoE_toggleSyncRegs(2))then WrtMonEvtDone <= '0'; else WrtMonEvtDone <= '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 => app_wren, -- 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 => 66, -- 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(257 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 => app_wren, -- 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'); EventDone <= '1'; EventDone_dl <= '1'; last_word <= '0'; rqst_i <= '0'; dout_wc <= (others => '0'); else AddrQueue_wa0SyncRegs <= AddrQueue_wa0SyncRegs(1 downto 0) & AddrQueue_wa(0); AddrQueue_wa1SyncRegs <= AddrQueue_wa1SyncRegs(1 downto 0) & AddrQueue_wa(1); if(EventDone = '1' and EventDone_dl = '0')then AddrQueue_ra(1) <= AddrQueue_ra(0); AddrQueue_ra(0) <= not AddrQueue_ra(1); end if; if(EventDone = '1' and FIFO_empty = '0')then EventDone <= '0'; elsif(FIFO_DO(256) = '1' and app_wren = '1')then EventDone <= '1'; end if; EventDone_dl <= EventDone; if(app_wren = '1')then if(dout_wc = "11110")then last_word <= '1'; else last_word <= '0'; end if; end if; if(fifo_en = '0' or EventDone = '1' or FIFO_empty = '1' or ((FIFO_DO(256) = '1' or last_word = '1') and app_wren = '1'))then rqst_i <= '0'; elsif((AddrQueue_ra(1) /= AddrQueue_wa1SyncRegs(2) or AddrQueue_ra(0) /= AddrQueue_wa0SyncRegs(2)) or FIFO_AlmostEmpty = '0')then rqst_i <= '1'; end if; if(EventDone = '1')then dout_wc <= (others => '0'); elsif(app_wren = '1')then dout_wc <= dout_wc + 1; end if; end if; -- if(resetMem = '0' and run = '1' and FIFO_DO(256) = '0' and last_word = '1' and app_wren = '1')then if(resetMem = '0' and run = '1' and last_word = '1' and app_wren = '1')then KiloByte_toggle_i <= not KiloByte_toggle_i; end if; if(resetMem = '0' and run = '1' and FIFO_DO(256) = '1' and app_wren = '1')then EoB_toggle_i <= not EoB_toggle_i; end if; if(resetMem = '0' and run = '1' and FIFO_DO(257) = '1' and app_wren = '1')then EoE_toggle_i <= not EoE_toggle_i; end if; end if; end process; process(memclk) begin if(memclk'event and memclk = '1')then if(EventDone_dl = '1')then app_addr_i(9 downto 0) <= (others => '0'); app_addr_i(13 downto 10) <= AddrQueue_do(3 downto 0); elsif(app_wren = '1')then app_addr_i(13 downto 0) <= app_addr_i(13 downto 0) + 1; end if; end if; end process; dout <= FIFO_DO(255 downto 0); end Behavioral;