---------------------------------------------------------------------------------- -- 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_wportB is Port ( memclk : in STD_LOGIC; sysclk : in STD_LOGIC; reset : in STD_LOGIC; resetSys : in STD_LOGIC; resetMem : in STD_LOGIC; test : in STD_LOGIC_VECTOR(1 downto 0); -- memory test test_block_sent : out STD_LOGIC := '0'; -- indicating test writing progress. Pulse once every 32 32-bit words test_pause : in std_logic; -- each TCP segment sent will have dest IP address (32-bit), TCP port(2x16-bit), SEQ number(32-bit), length(16 bit), time stamp(16 bit), control bits(6) -- and memory starting address of the segment payload data(24-bit) -- for alignment purposes, each entry occupies 32 bytes of memory space (256 bits) TCP_din : in STD_LOGIC_VECTOR(31 downto 0); TCP_channel : in STD_LOGIC_VECTOR(1 downto 0); TCP_we : in std_logic; TCP_wcount : out STD_LOGIC_VECTOR (2 downto 0); -- ipbus signals ipb_clk : in STD_LOGIC; ipb_write : in STD_LOGIC; ipb_strobe : in STD_LOGIC; ipb_addr : in STD_LOGIC_VECTOR(31 downto 0); ipb_wdata : in STD_LOGIC_VECTOR(31 downto 0); ipb_ack : out STD_LOGIC; run : in STD_LOGIC; -- ipbus write is allowed only when run = '0' -- ddr3 user interface app_rqst : out STD_LOGIC; -- request to output data app_ack : in STD_LOGIC; -- permission to output data app_rdy : in STD_LOGIC; app_en : out STD_LOGIC; app_wdf_rdy : in STD_LOGIC; app_wdf_wren : out STD_LOGIC; app_wdf_mask : out STD_LOGIC_VECTOR(7 downto 0); 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 : out STD_LOGIC_VECTOR (63 downto 0) ); end ddr_wportB; architecture Behavioral of ddr_wportB 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 TCP_sr : std_logic_vector(63 downto 0) := (others => '0'); signal TCP_wc : std_logic_vector(2 downto 0) := (others => '0'); signal TCPqueue_di : std_logic_vector(257 downto 0) := (others => '0'); signal TCPqueue_do : std_logic_vector(257 downto 0) := (others => '0'); signal TCPqueue_we : std_logic_vector(2 downto 0) := (others => '0'); signal TCPqueue_wa : std_logic_vector(4 downto 0) := (others => '0'); signal TCPqueue_ra : std_logic_vector(4 downto 0) := (others => '0'); signal TCPqueue_wap : std_logic_vector(3 downto 0) := (others => '0'); signal TCPqueue_wa0SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal TCPqueue_wa1SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal TCPqueue_wa2SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal TCPqueue_wa3SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal ipb_strobe_q : std_logic := '0'; signal ipb_addr0_wr : std_logic := '0'; signal ipb_weToggle : std_logic := '0'; signal ipb_di : std_logic_vector(31 downto 0) := (others => '0'); signal ipb_mask : std_logic_vector(1 downto 0) := (others => '0'); signal ipb_addr_q : std_logic_vector(7 downto 0) := (others => '0'); signal ipb_waddr : std_logic_vector(26 downto 0) := (others => '0'); signal ipb_weToggleSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal ec_lfsr : std_logic := '0'; signal lfsr: std_logic_vector(31 downto 0) := (others => '0'); signal lfsrCntr: std_logic_vector(4 downto 0) := (others => '0'); signal TCPqueue_ceReg : std_logic := '0'; signal TCPqueue_do_vld : std_logic := '0'; signal dout_vld : std_logic := '0'; signal app_rqst_i : std_logic := '0'; signal app_addr_i : std_logic_vector(23 downto 0) := (others => '0'); signal app_wren : std_logic := '0'; signal TCP_addr : array3X18 := (others => (others => '0')); signal ipb_queue_di : std_logic_vector(31 downto 0) := (others => '0'); signal ipb_queue_do : std_logic_vector(31 downto 0) := (others => '0'); signal ipb_queue_a : std_logic_vector(3 downto 0) := (others => '1'); signal ipb_queue_we : std_logic := '0'; signal ipb_wddr : std_logic := '0'; signal ipb_wddrSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal sent_odd : std_logic := '0'; signal wcountToggle : std_logic_vector(2 downto 0) := (others => '0'); signal wcountToggle0SyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal wcountToggle1SyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal wcountToggle2SyncRegs : std_logic_vector(3 downto 0) := (others => '0'); begin app_rqst <= '0' when app_rqst_i = '0' or (TCPqueue_do_vld = '0' and app_wren = '1') else '1'; app_addr <= app_addr_i; app_wdf_wren <= app_wren; app_en <= app_wren; app_wren <= app_ack and app_rdy and app_wdf_rdy; ipb_ack <= ipb_strobe and ipb_write and ipb_addr(27) and not run; process(ipb_clk) begin if(ipb_clk'event and ipb_clk = '1')then if(reset = '1' or run = '1')then ipb_weToggle <= '0'; elsif((ipb_strobe = '1' and ipb_write = '1' and ipb_addr(27) = '1') or ec_lfsr = '1')then ipb_weToggle <= not ipb_weToggle; end if; ipb_wddr <= not reset and not run and not test(0) and ipb_strobe and ipb_write and ipb_addr(27); ipb_addr_q(7 downto 0) <= ipb_addr(7 downto 0); if(test(0) = '1')then ipb_di <= lfsr; if(test_pause = '0')then ec_lfsr <= '1'; elsif(lfsrCntr(2 downto 0) = "111")then ec_lfsr <= '0'; end if; else ipb_di(31 downto 0) <= ipb_wdata; ec_lfsr <= '0'; end if; if(test(0) = '0')then lfsr <= (others => '0'); lfsrCntr <= (others => '0'); elsif(ec_lfsr = '1')then if(test(1) = '0')then lfsr <= lfsr(30 downto 0) & not(lfsr(31) xor lfsr(21) xor lfsr(1) xor lfsr(0)); else lfsr <= lfsr + 1; end if; lfsrCntr <= lfsrCntr + 1; end if; test_block_sent <= not reset and and_reduce(lfsrCntr); end if; end process; process(sysclk) begin if(sysclk'event and sysclk = '1')then if(resetSys = '1' or run = '0')then TCPqueue_wa <= (others => '0'); elsif(TCPqueue_we(2) = '1')then case TCPqueue_wa(3 downto 0) is when x"0" => TCPqueue_wa(3 downto 0) <= x"1"; when x"1" => TCPqueue_wa(3 downto 0) <= x"3"; when x"3" => TCPqueue_wa(3 downto 0) <= x"2"; when x"2" => TCPqueue_wa(3 downto 0) <= x"6"; when x"6" => TCPqueue_wa(3 downto 0) <= x"7"; when x"7" => TCPqueue_wa(3 downto 0) <= x"5"; when x"5" => TCPqueue_wa(3 downto 0) <= x"4"; when x"4" => TCPqueue_wa(3 downto 0) <= x"c"; when x"c" => TCPqueue_wa(3 downto 0) <= x"d"; when x"d" => TCPqueue_wa(3 downto 0) <= x"f"; when x"f" => TCPqueue_wa(3 downto 0) <= x"e"; when x"e" => TCPqueue_wa(3 downto 0) <= x"a"; when x"a" => TCPqueue_wa(3 downto 0) <= x"b"; when x"b" => TCPqueue_wa(3 downto 0) <= x"9"; when x"9" => TCPqueue_wa(3 downto 0) <= x"8"; when others => TCPqueue_wa(3 downto 0) <= x"0"; end case; end if; if(TCP_we = '1')then TCP_sr <= TCP_din & TCP_sr(63 downto 32); end if; if(resetSys = '1')then TCP_wc <= "000"; elsif(TCP_we = '1')then TCP_wc <= TCP_wc + 1; end if; wcountToggle0SyncRegs <= wcountToggle0SyncRegs(2 downto 0) & wcountToggle(0); wcountToggle1SyncRegs <= wcountToggle1SyncRegs(2 downto 0) & wcountToggle(1); wcountToggle2SyncRegs <= wcountToggle2SyncRegs(2 downto 0) & wcountToggle(2); if(resetSys = '1')then TCP_wcount <= (others => '0'); else if(wcountToggle0SyncRegs(3) = wcountToggle0SyncRegs(2))then TCP_wcount(0) <= '0'; else TCP_wcount(0) <= '1'; end if; if(wcountToggle1SyncRegs(3) = wcountToggle1SyncRegs(2))then TCP_wcount(1) <= '0'; else TCP_wcount(1) <= '1'; end if; if(wcountToggle2SyncRegs(3) = wcountToggle2SyncRegs(2))then TCP_wcount(2) <= '0'; else TCP_wcount(2) <= '1'; end if; end if; end if; end process; g_TCPqueue : for i in 0 to 42 generate i_TCPqueue: RAM32x6D PORT MAP( wclk => sysclk, rclk => memclk, di => TCPqueue_di(i*6+5 downto i*6), we => TCPqueue_we(i/16), wa => TCPqueue_wa, ra => TCPqueue_ra, ceReg => TCPqueue_ceReg, do => TCPqueue_do(i*6+5 downto i*6) ); end generate; TCPqueue_we(0) <= '1' when TCP_we = '1' and TCP_wc = "010" else '0'; TCPqueue_we(1) <= '1' when TCP_we = '1' and TCP_wc = "101" else '0'; TCPqueue_we(2) <= '1' when TCP_we = '1' and TCP_wc = "111" else '0'; TCPqueue_di(257 downto 256) <= TCP_channel; TCPqueue_di(255 downto 224) <= TCP_din; TCPqueue_di(223 downto 192) <= TCP_sr(63 downto 32); TCPqueue_di(191 downto 160) <= TCP_din; TCPqueue_di(159 downto 96) <= TCP_sr; TCPqueue_di(95 downto 64) <= TCP_din; TCPqueue_di(63 downto 0) <= TCP_sr; TCPqueue_ceReg <= '1' when TCPqueue_do_vld = '0' or dout_vld = '0' or app_wren = '1' else '0'; g_ipb_queue: for i in 0 to 31 generate i_ipb_queue : SRL16E port map ( Q => ipb_queue_do(i), -- SRL data output A0 => ipb_queue_a(0), -- Select[0] input A1 => ipb_queue_a(1), -- Select[1] input A2 => ipb_queue_a(2), -- Select[2] input A3 => ipb_queue_a(3), -- Select[3] input CE => ipb_queue_we, -- Clock enable input CLK => memclk, -- Clock input D => ipb_queue_di(i) -- SRL data input ); end generate; ipb_queue_di <= ipb_di; ipb_queue_we <= ipb_weToggleSyncRegs(3) xor ipb_weToggleSyncRegs(2); process(memclk) begin if(memclk'event and memclk = '1')then if(resetMem = '1')then ipb_weToggleSyncRegs <= (others => '0'); ipb_wddrSyncRegs <= (others => '0'); else ipb_weToggleSyncRegs <= ipb_weToggleSyncRegs(2 downto 0) & ipb_weToggle; ipb_wddrSyncRegs <= ipb_wddrSyncRegs(2 downto 0) & ipb_wddr; end if; if(resetMem = '1' or run = '1')then ipb_queue_a <= (others => '1'); elsif(ipb_weToggleSyncRegs(3) /= ipb_weToggleSyncRegs(2) and app_wren = '0')then ipb_queue_a <= ipb_queue_a + 1; elsif(ipb_weToggleSyncRegs(3) = ipb_weToggleSyncRegs(2) and app_wren = '1' and and_reduce(ipb_queue_a) = '0')then ipb_queue_a <= ipb_queue_a - 1; end if; if(resetMem = '1' or run = '1')then ipb_waddr <= (others => '0'); elsif(ipb_wddrSyncRegs(3 downto 2) = "01")then ipb_waddr <= ipb_addr(26 downto 8) & ipb_addr_q; elsif(app_wren = '1')then ipb_waddr <= ipb_waddr + 1; end if; if(resetMem = '1')then TCPqueue_ra <= (others => '0'); elsif(TCPqueue_wap /= TCPqueue_ra(3 downto 0) and TCPqueue_ceReg = '1')then case TCPqueue_ra(3 downto 0) is when x"0" => TCPqueue_ra(3 downto 0) <= x"1"; when x"1" => TCPqueue_ra(3 downto 0) <= x"3"; when x"3" => TCPqueue_ra(3 downto 0) <= x"2"; when x"2" => TCPqueue_ra(3 downto 0) <= x"6"; when x"6" => TCPqueue_ra(3 downto 0) <= x"7"; when x"7" => TCPqueue_ra(3 downto 0) <= x"5"; when x"5" => TCPqueue_ra(3 downto 0) <= x"4"; when x"4" => TCPqueue_ra(3 downto 0) <= x"c"; when x"c" => TCPqueue_ra(3 downto 0) <= x"d"; when x"d" => TCPqueue_ra(3 downto 0) <= x"f"; when x"f" => TCPqueue_ra(3 downto 0) <= x"e"; when x"e" => TCPqueue_ra(3 downto 0) <= x"a"; when x"a" => TCPqueue_ra(3 downto 0) <= x"b"; when x"b" => TCPqueue_ra(3 downto 0) <= x"9"; when x"9" => TCPqueue_ra(3 downto 0) <= x"8"; when others => TCPqueue_ra(3 downto 0) <= x"0"; end case; end if; if(resetMem = '1')then TCPqueue_do_vld <= '0'; elsif(TCPqueue_wap /= TCPqueue_ra(3 downto 0))then TCPqueue_do_vld <= '1'; elsif(dout_vld = '0' or app_wren = '1')then TCPqueue_do_vld <= '0'; end if; if(resetMem = '1')then dout_vld <= '0'; elsif(TCPqueue_do_vld = '1')then dout_vld <= '1'; elsif(app_wren = '1')then dout_vld <= '0'; end if; if(resetMem = '1')then TCPqueue_wa0SyncRegs <= (others => '0'); TCPqueue_wa1SyncRegs <= (others => '0'); TCPqueue_wa2SyncRegs <= (others => '0'); TCPqueue_wa3SyncRegs <= (others => '0'); TCPqueue_wap <= (others => '0'); else TCPqueue_wa0SyncRegs <= TCPqueue_wa0SyncRegs(1 downto 0) & TCPqueue_wa(0); TCPqueue_wa1SyncRegs <= TCPqueue_wa1SyncRegs(1 downto 0) & TCPqueue_wa(1); TCPqueue_wa2SyncRegs <= TCPqueue_wa2SyncRegs(1 downto 0) & TCPqueue_wa(2); TCPqueue_wa3SyncRegs <= TCPqueue_wa3SyncRegs(1 downto 0) & TCPqueue_wa(3); TCPqueue_wap(0) <= TCPqueue_wa0SyncRegs(2); TCPqueue_wap(1) <= TCPqueue_wa1SyncRegs(2); TCPqueue_wap(2) <= TCPqueue_wa2SyncRegs(2); TCPqueue_wap(3) <= TCPqueue_wa3SyncRegs(2); end if; if(resetMem = '1' or run = '0')then TCP_addr <= (others => (others => '0')); elsif(TCPqueue_do_vld = '1' and (app_wren = '1' or dout_vld = '0'))then TCP_addr(conv_integer(TCPqueue_do(257 downto 256))) <= TCP_addr(conv_integer(TCPqueue_do(257 downto 256))) + 1; end if; if(run = '1')then app_wdf_mask <= x"00"; else for i in 0 to 7 loop if(i = conv_integer(ipb_waddr(2 downto 0)))then app_wdf_mask(i) <= '0'; else app_wdf_mask(i) <= '1'; end if; end loop; end if; if(run = '1')then if(dout_vld = '0' or app_wren = '1')then dout <= TCPqueue_do(255 downto 0); case TCPqueue_do(257 downto 256) is when "00" => app_addr_i <= "00" & TCP_addr(0)(17 downto 10) & x"f" & TCP_addr(0)(9 downto 0); when "01" => app_addr_i <= "01" & TCP_addr(1)(17 downto 10) & x"f" & TCP_addr(1)(9 downto 0); when others => app_addr_i <= "10" & TCP_addr(2)(17 downto 10) & x"f" & TCP_addr(2)(9 downto 0); end case; end if; else for i in 0 to 7 loop dout(32*i+31 downto 32*i) <= ipb_queue_do; end loop; app_addr_i <= ipb_waddr(26 downto 3); end if; if(resetMem = '1' or run = '0')then sent_odd <= '0'; elsif(app_wren = '1')then sent_odd <= not sent_odd; end if; if(app_wren = '1' and sent_odd = '1')then wcountToggle(conv_integer(app_addr_i(23 downto 22))) <= not wcountToggle(conv_integer(app_addr_i(23 downto 22))); end if; if(resetMem = '1')then app_rqst_i <= '0'; elsif(app_wren = '1' and TCPqueue_do_vld = '0')then app_rqst_i <= '0'; elsif(((TCPqueue_do_vld = '1' or sent_odd = '1') and dout_vld = '1') or (and_reduce(ipb_queue_a) = '0' and app_ack = '0'))then app_rqst_i <= '1'; end if; end if; end process; end Behavioral;