---------------------------------------------------------------------------------- -- 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_rport is Port ( memclk : in STD_LOGIC; sysclk : in STD_LOGIC; reset : in STD_LOGIC; resetSys : in STD_LOGIC; resetMem : in STD_LOGIC; run : in STD_LOGIC; test : in STD_LOGIC_VECTOR(1 downto 0); -- memory test test_block_sent : in STD_LOGIC; -- indicating test writing progress. One pulse every 256 32-bit words test_pause : OUT std_logic; test_status : out STD_LOGIC_VECTOR(63 downto 0); -- 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_dout : out STD_LOGIC_VECTOR(31 downto 0); -- TCP data are written in unit of 32-bit words TCP_dout_type : out STD_LOGIC_VECTOR(2 downto 0); -- TCP data destination TCP_addr : in STD_LOGIC_VECTOR(28 downto 0); -- 28-26 encoded request source 25-0 address in 64 bit word TCP_length : in STD_LOGIC_VECTOR(12 downto 0); -- in 64 bit word, actual length - 1 TCP_dout_valid : out STD_LOGIC; TCP_rqst : in STD_LOGIC; TCP_ack : out STD_LOGIC; TCP_lastword : out STD_LOGIC; -- 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_rdata : out STD_LOGIC_VECTOR(31 downto 0); ipb_ack : out STD_LOGIC; page_addr : in STD_LOGIC_VECTOR(9 downto 0); -- monitored event memory window cs_out : out STD_LOGIC_VECTOR(511 downto 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_rd_data_valid : in STD_LOGIC; app_rd_data : in STD_LOGIC_VECTOR(255 downto 0); app_addr : out STD_LOGIC_VECTOR (27 downto 0) := (others => '0')); -- in unit of 32bit word, bit 27 is not used end ddr_rport; architecture Behavioral of ddr_rport is COMPONENT FIFO_RESET_7S PORT( reset : IN std_logic; clk : IN std_logic; fifo_rst : OUT std_logic; fifo_en : OUT std_logic ); END COMPONENT; 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; COMPONENT RAM32x6Db PORT( wclk : 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); do : OUT std_logic_vector(5 downto 0) ); END COMPONENT; signal TCPqueue_we : std_logic := '0'; signal ipb_start_addr : std_logic_vector(26 downto 0) := (others => '0'); signal ipbReadSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal ipbRead : std_logic := '0'; signal ipbRead_q : std_logic := '0'; signal ipb_ack_i : std_logic := '0'; signal ipb_rqst : std_logic := '0'; signal ipb_raddr : std_logic_vector(23 downto 0) := (others => '0'); signal ipb_seq : std_logic_vector(1 downto 0) := (others => '0'); signal ipb_rqst_cnt : std_logic_vector(1 downto 0) := (others => '0'); signal ipb_rqst_inqueue : std_logic_vector(1 downto 0) := (others => '0'); signal ipb_rqstSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal queue_we : std_logic := '0'; signal queue_ceReg : std_logic := '0'; signal queue_do_vld : std_logic := '0'; signal TCP_addr1and0 : std_logic_vector(1 downto 0) := (others => '0'); signal queue_di : std_logic_vector(29 downto 0) := (others => '0'); signal queue_do : std_logic_vector(29 downto 0) := (others => '0'); signal queue_wa : std_logic_vector(4 downto 0) := (others => '0'); signal queue_ra : std_logic_vector(4 downto 0) := (others => '0'); signal queue_wap : std_logic_vector(3 downto 0) := (others => '0'); signal queue_wa0SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal queue_wa1SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal queue_wa2SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal queue_wa3SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal Oqueue_di : std_logic_vector(12 downto 0) := (others => '0'); signal Oqueue_dop : std_logic_vector(12 downto 0) := (others => '0'); signal Oqueue_do : std_logic_vector(12 downto 0) := (others => '0'); signal Oqueue_a : std_logic_vector(3 downto 0) := (others => '1'); signal Oqueue_re : std_logic := '0'; signal Oqueue_do_vld : std_logic := '0'; signal test_wc : std_logic_vector(3 downto 0) := (others => '0'); signal lfsr: std_logic_vector(31 downto 0) := (others => '0'); signal testErr : std_logic := '0'; signal testCntr: std_logic_vector(30 downto 0) := (others => '0'); signal app_rqst_i : std_logic := '0'; signal app_ren : std_logic := '0'; signal last_word : std_logic := '0'; signal s_demux : std_logic_vector(2 downto 0) := (others => '0'); signal data_demux : std_logic_vector(31 downto 0) := (others => '0'); signal lengthCntr : std_logic_vector(7 downto 0) := (others => '0'); signal rd_cnt : std_logic_vector(4 downto 0) := (others => '0'); signal app_addr_i : std_logic_vector(27 downto 0) := (others => '0'); signal fifo_en : std_logic := '0'; signal fifo_rst : std_logic := '0'; signal buf_empty : std_logic_vector(3 downto 0) := (others => '0'); signal buf_we : std_logic := '0'; signal buf_re : std_logic := '0'; signal buf_di : std_logic_vector(255 downto 0) := (others => '0'); signal buf_do : std_logic_vector(255 downto 0) := (others => '0'); signal TCPqueue_do_vld : std_logic := '0'; signal TCP_rrqst : std_logic := '0'; signal TCP_raddr : std_logic_vector(23 downto 0) := (others => '0'); signal TCP_raddr_end : std_logic_vector(12 downto 0) := (others => '0'); signal TCP_rlengthp : std_logic_vector(6 downto 0) := (others => '0'); signal TCP_rlength : std_logic_vector(7 downto 0) := (others => '0'); signal TCPqueue_di : std_logic_vector(41 downto 0) := (others => '0'); signal TCPqueue_dop : std_logic_vector(41 downto 0) := (others => '0'); signal TCPqueue_do : std_logic_vector(41 downto 0) := (others => '0'); signal TCPqueue_a : std_logic_vector(3 downto 0) := (others => '1'); signal Last_TCP_addr : std_logic_vector(12 downto 0) := (others => '0'); signal first_test_read : std_logic := '1'; signal sel_TCP : std_logic := '0'; signal rd_ipb : std_logic := '0'; signal ipbus_rbuf_wa : std_logic_vector(4 downto 0) := (others => '0'); signal ipbus_rbuf_ra : std_logic_vector(4 downto 0) := (others => '0'); signal ipbus_rbuf_di : std_logic_vector(257 downto 0) := (others => '0'); signal ipbus_rbuf_do : std_logic_vector(257 downto 0) := (others => '0'); signal ipbus_rbuf_wa2SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal ipbus_rbuf_wa1SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal ipbus_rbuf_wa0SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal ipbus_rbuf_wap : std_logic_vector(2 downto 0) := (others => '0'); signal ipb_rdata_i : std_logic_vector(31 downto 0) := (others => '0'); signal rd_queue_o : std_logic_vector(2 downto 0) := (others => '0'); signal rd_queue_q : std_logic_vector(2 downto 0) := (others => '0'); signal rd_queue_wa : std_logic_vector(5 downto 0) := (others => '0'); signal rd_queue_ra : std_logic_vector(5 downto 0) := (others => '0'); signal rd_queue_q_vld : std_logic := '0'; signal WRCOUNT : array4x9; signal RDCOUNT : array4x9; signal TCP_dout_valid_i : std_logic := '0'; signal TCP_lastword_i : std_logic := '0'; COMPONENT chipscope generic (N : integer := 5); PORT( clka : IN std_logic; clkb : IN std_logic; ina : IN std_logic_vector(135 downto 0); inb : IN std_logic_vector(135 downto 0) ); END COMPONENT; COMPONENT chipscope1 generic (N : integer := 5); PORT( clk : IN std_logic; Din : IN std_logic_vector(303 downto 0) ); END COMPONENT; COMPONENT chipscope1b generic (USER2 : boolean := false); PORT( clk : IN std_logic; Din : IN std_logic_vector(303 downto 0) ); END COMPONENT; signal chk_SEQ : std_logic := '0'; signal bad_SEQ : std_logic := '0'; signal NXT_SEQ : std_logic_vector(15 downto 0) := (others => '0'); signal ina : std_logic_vector(135 downto 0) := (others => '0'); signal inb : std_logic_vector(135 downto 0) := (others => '0'); signal cs_in : std_logic_vector(303 downto 0) := (others => '0'); begin cs_out(165) <= app_rdy; cs_out(164) <= app_ack; cs_out(163) <= app_rqst_i; cs_out(162 downto 159) <= queue_wap(3 downto 0); cs_out(158 downto 155) <= queue_ra(3 downto 0); cs_out(154 downto 149) <= cs_in(247 downto 242); cs_out(148 downto 105) <= cs_in(166 downto 123); cs_out(104 downto 0) <= cs_in(104 downto 0); --i_chipscope1b: chipscope1b PORT MAP( -- clk => sysclk, -- din => cs_in -- ); cs_in(297) <= Oqueue_do_vld; cs_in(296) <= buf_empty(0); cs_in(295 downto 292) <= Oqueue_do(12 downto 9); cs_in(291) <= Oqueue_re; cs_in(290) <= TCP_rrqst; --cs_in(289) <= TCP_addr(29); cs_in(288) <= bad_SEQ; --cs_in() <= ; --cs_in() <= ; --cs_in() <= ; cs_in(280) <= TCP_lastword_i; --cs_in( downto ) <= ; --cs_in( downto ) <= ; cs_in(279 downto 251) <= TCP_addr(28 downto 0); cs_in(250 downto 247) <= buf_empty; cs_in(246) <= queue_we; cs_in(245) <= Oqueue_re; cs_in(244) <= Oqueue_do_vld; cs_in(242) <= buf_re; cs_in(241) <= TCP_rrqst; cs_in(240 downto 239) <= TCP_addr1and0; cs_in(227 downto 220) <= TCP_rlength; cs_in(219 downto 213) <= TCP_rlengthp; cs_in(190 downto 167) <= TCP_raddr; cs_in(166 downto 163) <= TCPqueue_a; cs_in(104 downto 73) <= data_demux; cs_in(72 downto 70) <= s_demux; cs_in(69 downto 62) <= lengthCntr; cs_in(61 downto 58) <= Oqueue_a; cs_in(57 downto 45) <= Oqueue_do; cs_in(44 downto 32) <= Oqueue_di; cs_in(31) <= TCP_dout_valid_i; cs_in(30) <= TCPqueue_we; cs_in(29) <= TCPqueue_do_vld; cs_in(28 downto 0) <= queue_di(28 downto 0); test_pause <= test_wc(3) or testErr; ipb_rdata <= ipb_rdata_i; ipb_ack <= ipb_ack_i; app_rqst <= '0' when app_rqst_i = '0' or (last_word = '1' and app_ren = '1') else '1'; app_en <= app_ren; app_ren <= app_ack and app_rdy; TCP_ack <= TCPqueue_we; --test_status(5 downto 0) <= rd_queue_ra; --test_status(11 downto 6) <= rd_queue_wa; --test_status(12) <= rd_queue_q_vld; --test_status(13) <= queue_do_vld; --test_status(14) <= Oqueue_do_vld; --test_status(18 downto 15) <= Oqueue_a; --test_status(22 downto 19) <= queue_wa(3 downto 0); --test_status(26 downto 23) <= queue_ra(3 downto 0); --test_status(30 downto 27) <= TCPqueue_a; --test_status(40 downto 31) <= Oqueue_do(9 downto 0); --test_status(48 downto 41) <= lengthCntr; --test_status(51 downto 49) <= s_demux; test_status(31 downto 0) <= testErr & testCntr; --test_status(32) <= '0'; --test_status(33) <= first_test_read; --test_status(40 downto 34) <= (others => '0'); --test_status(46 downto 41) <= rd_queue_ra; --test_status(52 downto 47) <= rd_queue_wa; --test_status(55 downto 53) <= ipbus_rbuf_ra(2 downto 0); --test_status(58 downto 56) <= ipbus_rbuf_wap; --test_status(62 downto 59) <= test_wc; test_status(63 downto 32) <= (others => '0'); app_addr <= app_addr_i; TCP_dout <= data_demux; TCP_dout_valid <= TCP_dout_valid_i; TCP_lastword <= TCP_lastword_i; ipb_ack_i <= '0' when ipbRead = '0' or ipbus_rbuf_wap = ipbus_rbuf_ra(2 downto 0) else ipb_strobe; process(ipb_clk) begin if(ipb_clk'event and ipb_clk = '1')then if(reset = '1')then ipb_rqst <= '0'; elsif((ipbRead = '1' and ipbRead_q = '0') or (first_test_read = '1' and test_wc(2) = '1'))then ipb_rqst <= '1'; elsif((ipbus_rbuf_ra(2 downto 0) = "001" or ipbus_rbuf_ra(2 downto 0) = "111") and ipb_addr(2 downto 0) = "000" and ipb_ack_i = '1' and test(0) = '0')then ipb_rqst <= '1'; elsif((ipbus_rbuf_ra(2 downto 0) = "001" or ipbus_rbuf_ra(2 downto 0) = "111") and testCntr(2 downto 0) = "001")then ipb_rqst <= '1'; else ipb_rqst <= '0'; end if; if(test(0) = '0')then first_test_read <= '1'; elsif(ipb_rqst = '1')then first_test_read <= '0'; end if; if(reset = '1' or test(0) = '0')then test_wc <= (others => '0'); elsif(test_block_sent = '1' and ipb_rqst = '0')then test_wc <= test_wc + 1; elsif(test_block_sent = '0' and ipb_rqst = '1')then test_wc <= test_wc - 1; end if; if(reset = '0' and test(0) = '0' and ipb_strobe = '1' and ipb_write = '0' and (ipb_addr(27) = '1' or ipb_addr(17) = '1'))then ipbRead <= '1'; else ipbRead <= '0'; end if; ipbRead_q <= ipbRead; if(ipbRead = '0')then if(ipb_addr(27) = '1')then ipb_start_addr <= ipb_addr(26 downto 0); elsif(ipb_addr(17) = '1')then ipb_start_addr <= page_addr & ipb_addr(16 downto 0); end if; end if; if(ipbRead = '0' and test(0) = '0')then ipbus_rbuf_ra <= (others => '0'); elsif((ipb_ack_i = '1' and ipb_addr(2 downto 0) = "111") or testCntr(2 downto 0) = "111")then case ipbus_rbuf_ra(2 downto 0) is when "000" => ipbus_rbuf_ra(2 downto 0) <= "001"; when "001" => ipbus_rbuf_ra(2 downto 0) <= "011"; when "011" => ipbus_rbuf_ra(2 downto 0) <= "010"; when "010" => ipbus_rbuf_ra(2 downto 0) <= "110"; when "110" => ipbus_rbuf_ra(2 downto 0) <= "111"; when "111" => ipbus_rbuf_ra(2 downto 0) <= "101"; when "101" => ipbus_rbuf_ra(2 downto 0) <= "100"; when others => ipbus_rbuf_ra(2 downto 0) <= "000"; end case; end if; if(ipbRead = '0' and test(0) = '0')then ipbus_rbuf_wa2SyncRegs <= "000"; ipbus_rbuf_wa1SyncRegs <= "000"; ipbus_rbuf_wa0SyncRegs <= "000"; ipbus_rbuf_wap <= "000"; else ipbus_rbuf_wa2SyncRegs <= ipbus_rbuf_wa2SyncRegs(1 downto 0) & ipbus_rbuf_wa(2); ipbus_rbuf_wa1SyncRegs <= ipbus_rbuf_wa1SyncRegs(1 downto 0) & ipbus_rbuf_wa(1); ipbus_rbuf_wa0SyncRegs <= ipbus_rbuf_wa0SyncRegs(1 downto 0) & ipbus_rbuf_wa(0); ipbus_rbuf_wap(2) <= ipbus_rbuf_wa2SyncRegs(2); ipbus_rbuf_wap(1) <= ipbus_rbuf_wa1SyncRegs(2); ipbus_rbuf_wap(0) <= ipbus_rbuf_wa0SyncRegs(2); end if; if(reset = '1' or test(0) = '0')then testErr <= '0'; testCntr <= (others => '0'); elsif(ipbus_rbuf_wap /= ipbus_rbuf_ra(2 downto 0))then if(lfsr /= ipb_rdata_i)then testErr <= '1'; end if; if(testErr = '0')then testCntr <= testCntr + 1; end if; end if; if(test(0) = '0')then lfsr <= (others => '0'); elsif(ipbus_rbuf_wap /= ipbus_rbuf_ra(2 downto 0))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; end if; end if; end process; process(ipb_addr,ipbus_rbuf_do,testCntr) variable s : std_logic_vector(2 downto 0); begin if(test(0) = '0')then s := ipb_addr(2 downto 0); else s := testCntr(2 downto 0); end if; case s is when "000" => ipb_rdata_i <= ipbus_rbuf_do(31 downto 0); when "001" => ipb_rdata_i <= ipbus_rbuf_do(63 downto 32); when "010" => ipb_rdata_i <= ipbus_rbuf_do(95 downto 64); when "011" => ipb_rdata_i <= ipbus_rbuf_do(127 downto 96); when "100" => ipb_rdata_i <= ipbus_rbuf_do(159 downto 128); when "101" => ipb_rdata_i <= ipbus_rbuf_do(191 downto 160); when "110" => ipb_rdata_i <= ipbus_rbuf_do(223 downto 192); when others => ipb_rdata_i <= ipbus_rbuf_do(255 downto 224); end case; end process; g_TCPqueue: for i in 0 to 41 generate i_TCPqueue : SRL16E port map ( Q => TCPqueue_dop(i), -- SRL data output A0 => TCPqueue_a(0), -- Select[0] input A1 => TCPqueue_a(1), -- Select[1] input A2 => TCPqueue_a(2), -- Select[2] input A3 => TCPqueue_a(3), -- Select[3] input CE => TCPqueue_we, -- Clock enable input CLK => sysclk, -- Clock input D => TCPqueue_di(i) -- SRL data input ); end generate; g_Oqueue: for i in 0 to 12 generate i_Oqueue : SRL16E port map ( Q => Oqueue_dop(i), -- SRL data output A0 => Oqueue_a(0), -- Select[0] input A1 => Oqueue_a(1), -- Select[1] input A2 => Oqueue_a(2), -- Select[2] input A3 => Oqueue_a(3), -- Select[3] input CE => queue_we, -- Clock enable input CLK => sysclk, -- Clock input D => Oqueue_di(i) -- SRL data input ); end generate; g_queue : for i in 0 to 4 generate i_queue : RAM32X6D port map ( wclk => sysclk, rclk => memclk, di => queue_di(i*6+5 downto i*6), we => queue_we, wa => queue_wa, ra => queue_ra, ceReg => queue_ceReg, do => queue_do(i*6+5 downto i*6) ); end generate; queue_ceReg <= '1' when queue_do_vld = '0' or (last_word = '1' and app_ren = '1' and sel_TCP = '1') else '0'; TCP_rlengthp <= TCP_rlength(6 downto 0) + "0000011"; TCPqueue_di <= Last_TCP_addr & TCP_addr(28 downto 0); process(sysclk) variable dif : std_logic_vector(7 downto 0); begin dif := (Oqueue_do(8 downto 2) & '0') - lengthCntr; if(sysclk'event and sysclk = '1')then if(resetSys = '1' or run = '0' or TCPqueue_we = '1')then TCPqueue_we <= '0'; elsif(TCP_rqst = '1')then TCPqueue_we <= '1'; end if; Last_TCP_addr <= TCP_addr(12 downto 0) + TCP_length; if(resetSys = '1')then TCPqueue_a <= (others => '1'); elsif(TCPqueue_we = '1' and (and_reduce(TCPqueue_a) = '1' or TCPqueue_do_vld = '1'))then TCPqueue_a <= TCPqueue_a + 1; elsif(TCPqueue_we = '0' and and_reduce(TCPqueue_a) = '0' and TCPqueue_do_vld = '0')then TCPqueue_a <= TCPqueue_a - 1; end if; if(resetSys = '1' or (queue_we = '1' and Oqueue_di(9) = '1'))then TCPqueue_do_vld <= '0'; elsif(and_reduce(TCPqueue_a) = '0')then TCPqueue_do_vld <= '1'; end if; if(TCPqueue_do_vld = '0')then TCPqueue_do <= TCPqueue_dop; end if; if(resetSys = '1')then TCP_rrqst <= '0'; elsif(queue_we = '1' and Oqueue_di(9) = '1')then TCP_rrqst <= '0'; elsif(TCPqueue_do_vld = '1')then TCP_rrqst <= '1'; end if; if(TCP_rrqst = '0')then TCP_addr1and0 <= TCPqueue_do(1 downto 0); TCP_raddr <= TCPqueue_do(25 downto 2); -- in unit of 256 bit word TCP_raddr_end(12 downto 7) <= TCPqueue_do(41 downto 36) - 1; TCP_raddr_end(6 downto 0) <= TCPqueue_do(35 downto 29); if(TCPqueue_do(12 downto 7) = TCPqueue_do(41 downto 36))then TCP_rlength(7) <= '1'; TCP_rlength(6 downto 0) <= TCPqueue_do(35 downto 29) - TCPqueue_do(6 downto 0) + 1; else TCP_rlength(7) <= '0'; TCP_rlength(6 downto 0) <= "0000000" - TCPqueue_do(6 downto 0); end if; Oqueue_di(12 downto 10) <= TCPqueue_do(28 downto 26); elsif(queue_we = '1')then TCP_addr1and0 <= "00"; TCP_raddr(23 downto 5) <= TCP_raddr(23 downto 5) + 1; TCP_raddr(4 downto 0) <= (others => '0'); if(TCP_raddr(10 downto 5) = TCP_raddr_end(12 downto 7))then TCP_rlength(7) <= '1'; TCP_rlength(6 downto 0) <= (TCP_raddr_end(6 downto 0) + 1); else TCP_rlength <= (others => '0'); end if; end if; if(resetSys = '1' or buf_empty(0) = '1' or Oqueue_do_vld = '0' or Oqueue_re = '1' or (lengthCntr = x"01" and s_demux(2 downto 1) < Oqueue_do(1 downto 0)))then TCP_dout_valid_i <= '0'; else TCP_dout_valid_i <= '1'; end if; case s_demux is when "000" => data_demux <= buf_do(31 downto 0); when "001" => data_demux <= buf_do(63 downto 32); when "010" => data_demux <= buf_do(95 downto 64); when "011" => data_demux <= buf_do(127 downto 96); when "100" => data_demux <= buf_do(159 downto 128); when "101" => data_demux <= buf_do(191 downto 160); when "110" => data_demux <= buf_do(223 downto 192); when others => data_demux <= buf_do(255 downto 224); end case; if(resetSys = '1' or (Oqueue_do(9) = '1' and Oqueue_re = '1'))then chk_SEQ <= '0'; elsif(Oqueue_do(12) = '0' and s_demux = "001")then chk_SEQ <= '1'; end if; if(Oqueue_do(12) = '0' and s_demux(1 downto 0) = "10")then NXT_SEQ <= data_demux(15 downto 0); end if; if(chk_SEQ = '1' and Oqueue_do(12) = '0' and s_demux(1 downto 0) = "01" and NXT_SEQ /= data_demux(31 downto 16))then bad_SEQ <= '1'; else bad_SEQ <= '0'; end if; TCP_dout_type <= Oqueue_do(12 downto 10); if(buf_empty(0) = '1' or Oqueue_re = '1')then s_demux <= "000"; else s_demux <= s_demux + 1; end if; if(resetSys = '1' or queue_we = '1')then queue_we <= '0'; elsif(TCP_rrqst = '1' and Oqueue_a(3 downto 2) /= "01")then queue_we <= '1'; else queue_we <= '0'; end if; queue_di(23 downto 0) <= TCP_raddr; queue_di(28 downto 24) <= TCP_rlengthp(6 downto 2); -- length in 256-bit words Oqueue_di(1 downto 0) <= TCP_addr1and0; Oqueue_di(8 downto 2) <= TCP_rlength(6 downto 0); -- length in 64-bit words Oqueue_di(9) <= TCP_rlength(7); if(resetSys = '1')then Oqueue_do_vld <= '0'; elsif(Oqueue_a /= x"f")then Oqueue_do_vld <= '1'; elsif(Oqueue_re = '1')then Oqueue_do_vld <= '0'; end if; if(Oqueue_do_vld = '0' or Oqueue_re = '1')then Oqueue_do <= Oqueue_dop; end if; if(resetSys = '1' or Oqueue_re = '1' or (lengthCntr = x"01" and s_demux(2 downto 1) < Oqueue_do(1 downto 0)))then lengthCntr <= x"01"; elsif(buf_empty(0) = '0')then lengthCntr <= lengthCntr + 1; end if; if(resetSys = '1')then Oqueue_re <= '0'; TCP_lastword_i <= '0'; elsif(lengthCntr = (Oqueue_do(8 downto 2) & '0') and buf_empty(0) = '0')then Oqueue_re <= '1'; TCP_lastword_i <= Oqueue_do(9); else Oqueue_re <= '0'; TCP_lastword_i <= '0'; end if; if(resetSys = '1')then Oqueue_a <= (others => '1'); elsif(queue_we = '1' and (Oqueue_a = x"f" or (Oqueue_do_vld = '1' and Oqueue_re = '0')))then Oqueue_a <= Oqueue_a + 1; elsif(queue_we = '0' and Oqueue_a /= x"f" and (Oqueue_do_vld = '0' or Oqueue_re = '1'))then Oqueue_a <= Oqueue_a - 1; end if; if(resetSys = '1')then queue_wa <= (others => '0'); elsif(queue_we = '1')then queue_wa(1) <= queue_wa(0); queue_wa(0) <= not queue_wa(1); if(queue_wa(1 downto 0) = "10")then queue_wa(3 downto 2) <= queue_wa(3 downto 2) + 1; end if; end if; if(resetSys = '1' or fifo_en = '0' or buf_re = '1')then buf_re <= '0'; elsif(s_demux = "110" or (lengthCntr = (Oqueue_do(8 downto 2) & '0') and Oqueue_do(9) = '1'))then buf_re <= '1'; end if; end if; end process; process(memclk) begin if(memclk'event and memclk = '1')then if(resetMem = '1')then queue_do_vld <= '0'; elsif(queue_wap /= queue_ra(3 downto 0))then queue_do_vld <= '1'; elsif(last_word = '1' and app_ren = '1' and sel_TCP = '1')then queue_do_vld <= '0'; end if; if(resetMem = '1')then queue_ra <= (others => '0'); elsif(queue_wap /= queue_ra(3 downto 0) and (queue_do_vld = '0' or (last_word = '1' and app_ren = '1' and sel_TCP = '1')))then queue_ra(1) <= queue_ra(0); queue_ra(0) <= not queue_ra(1); if(queue_ra(1 downto 0) = "10")then queue_ra(3 downto 2) <= queue_ra(3 downto 2) + 1; end if; end if; if(resetMem = '1')then queue_wa0SyncRegs <= (others => '0'); queue_wa1SyncRegs <= (others => '0'); queue_wap <= (others => '0'); else queue_wa0SyncRegs <= queue_wa0SyncRegs(1 downto 0) & queue_wa(0); queue_wa1SyncRegs <= queue_wa1SyncRegs(1 downto 0) & queue_wa(1); queue_wap(0) <= queue_wa0SyncRegs(2); queue_wap(1) <= queue_wa1SyncRegs(2); if(queue_wap(1) = '1' and queue_wa1SyncRegs(2) = '0')then queue_wap(3 downto 2) <= queue_wap(3 downto 2) + 1; end if; end if; if(resetMem = '1' or (last_word = '1' and app_ren = '1'))then app_rqst_i <= '0'; elsif(queue_do_vld = '1' or or_reduce(ipb_rqst_cnt) = '1')then app_rqst_i <= '1'; end if; if(app_rqst_i = '0')then if(queue_do_vld = '1' and queue_do(28 downto 24) = "00001")then last_word <= '1'; else last_word <= '0'; end if; elsif(app_ren = '1')then if(rd_cnt = "00010")then last_word <= '1'; else last_word <= '0'; end if; end if; if(app_rqst_i = '0')then if(or_reduce(ipb_rqst_cnt) = '1')then app_addr_i <= '0' & ipb_raddr & "000"; rd_cnt <= "00100"; sel_TCP <= '0'; elsif(queue_do_vld = '1')then app_addr_i <= '0' & queue_do(23 downto 0) & "000"; rd_cnt <= queue_do(28 downto 24); -- rd_cnt is number of read in unit of 256 bit word(equivalent to eight 32-bit word) sel_TCP <= '1'; end if; elsif(app_ren = '1')then app_addr_i(24 downto 3) <= app_addr_i(24 downto 3) + 1;-- should never carry to app_addr_i(25), must wrap around rd_cnt <= rd_cnt - 1; end if; end if; end process; i_FIFO_RESET_7S: FIFO_RESET_7S PORT MAP( reset => resetMem, clk => memclk, fifo_rst => fifo_rst, fifo_en => fifo_en ); g_rbuf : for i in 0 to 3 generate i_rbuf : 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 => buf_do(i*64+63 downto i*64), -- Output data, width defined by DATA_WIDTH parameter EMPTY => buf_empty(i), -- 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 => buf_di(i*64+63 downto i*64), -- Input data, width defined by DATA_WIDTH parameter RDCLK => sysclk, -- 1-bit input read clock RDEN => buf_re, -- 1-bit input read enable RST => fifo_rst, -- 1-bit input reset WRCLK => memclk, -- 1-bit input write clock WREN => buf_we -- 1-bit input write enable ); end generate; buf_di <= app_rd_data; buf_we <= '1' when app_rd_data_valid = '1' and fifo_en = '1' and rd_queue_q(2) = '1' else '0'; g_ipbus_rbuf : for i in 0 to 42 generate i_ipbus_rbuf : RAM32x6Db PORT MAP( wclk => memclk, di => ipbus_rbuf_di(i*6+5 downto i*6), we => app_rd_data_valid, wa => ipbus_rbuf_wa, ra => ipbus_rbuf_ra, do => ipbus_rbuf_do(i*6+5 downto i*6) ); end generate; ipbus_rbuf_di(255 downto 0) <= app_rd_data; process(memclk,ipbRead,test) begin if(ipbRead = '0' and test(0) = '0')then ipbus_rbuf_wa(2 downto 0) <= (others => '0'); ipb_rqstSyncRegs <= (others => '0'); ipb_rqst_cnt <= (others => '0'); elsif(memclk'event and memclk = '1')then if(app_rd_data_valid = '1' and ipb_seq = rd_queue_q(1 downto 0) and rd_queue_q_vld = '1' and rd_queue_q(2) = '0')then case ipbus_rbuf_wa(2 downto 0) is when "000" => ipbus_rbuf_wa(2 downto 0) <= "001"; when "001" => ipbus_rbuf_wa(2 downto 0) <= "011"; when "011" => ipbus_rbuf_wa(2 downto 0) <= "010"; when "010" => ipbus_rbuf_wa(2 downto 0) <= "110"; when "110" => ipbus_rbuf_wa(2 downto 0) <= "111"; when "111" => ipbus_rbuf_wa(2 downto 0) <= "101"; when "101" => ipbus_rbuf_wa(2 downto 0) <= "100"; when others => ipbus_rbuf_wa(2 downto 0) <= "000"; end case; end if; ipb_rqstSyncRegs <= ipb_rqstSyncRegs(2 downto 0) & ipb_rqst; if(ipb_rqstSyncRegs(3 downto 2) = "10" and (app_rqst_i = '1' or or_reduce(ipb_rqst_cnt) = '0'))then ipb_rqst_cnt <= ipb_rqst_cnt + 1; elsif(ipb_rqstSyncRegs(3 downto 2) /= "10" and app_rqst_i = '0' and or_reduce(ipb_rqst_cnt) = '1')then ipb_rqst_cnt <= ipb_rqst_cnt - 1; end if; end if; end process; ipbus_rbuf_wa(4) <= rd_queue_q(2); process(memclk) begin if(memclk'event and memclk = '1')then ipbReadSyncRegs <= ipbReadSyncRegs(2 downto 0) & ipbRead; if(ipbReadSyncRegs(3 downto 2) = "10")then -- ipb_seq is used to eject stalemate read data ipb_seq <= ipb_seq + 1; end if; if(resetMem = '1')then ipb_raddr <= (others => '0'); elsif(ipbReadSyncRegs(3 downto 2) = "01")then ipb_raddr <= ipb_start_addr(26 downto 3); elsif(sel_TCP = '0' and app_ren = '1')then ipb_raddr <= ipb_raddr + 1; end if; if(resetMem = '1')then rd_queue_wa <= (others => '0'); elsif(app_ren = '1')then rd_queue_wa <= rd_queue_wa + 1; end if; if(resetMem = '1')then rd_queue_ra <= (others => '0'); elsif(rd_queue_wa /= rd_queue_ra and (app_rd_data_valid = '1' or rd_queue_q_vld = '0'))then rd_queue_ra <= rd_queue_ra + 1; end if; if(resetMem = '1')then rd_queue_q_vld <= '0'; elsif(rd_queue_wa /= rd_queue_ra)then rd_queue_q_vld <= '1'; elsif(app_rd_data_valid = '1')then rd_queue_q_vld <= '0'; end if; if(app_rd_data_valid = '1' or rd_queue_q_vld = '0')then rd_queue_q <= rd_queue_o; end if; end if; end process; i_rd_queue : RAM64M port map ( DOA => rd_queue_o(0), -- Read port A 1-bit output DOB => rd_queue_o(1), -- Read port B 1-bit output DOC => rd_queue_o(2), -- Read port C 1-bit output DOD => open, -- Read/Write port D 1-bit output ADDRA => rd_queue_ra, -- Read port A 6-bit address input ADDRB => rd_queue_ra, -- Read port B 6-bit address input ADDRC => rd_queue_ra, -- Read port C 6-bit address input ADDRD => rd_queue_wa, -- Read/Write port D 6-bit address input DIA => ipb_seq(0), -- RAM 1-bit data write input addressed by ADDRD, -- read addressed by ADDRA DIB => ipb_seq(1), -- RAM 1-bit data write input addressed by ADDRD, -- read addressed by ADDRB DIC => sel_TCP, -- RAM 1-bit data write input addressed by ADDRD, -- read addressed by ADDRC DID => '0', -- RAM 1-bit data write input addressed by ADDRD, -- read addressed by ADDRD WCLK => memclk, -- Write clock input WE => app_ren -- Write enable input ); end Behavioral;