AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
ddr_rport.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 11:02:29 01/25/2013
6 -- Design Name:
7 -- Module Name: ddr_wportA - Behavioral
8 -- Project Name:
9 -- Target Devices:
10 -- Tool versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 ----------------------------------------------------------------------------------
20 library IEEE;
21 use IEEE.STD_LOGIC_1164.ALL;
22 use IEEE.STD_LOGIC_ARITH.ALL;
23 use IEEE.STD_LOGIC_UNSIGNED.ALL;
24 use IEEE.std_logic_misc.all;
25 use work.amc13_pack.all;
26 
27 -- Uncomment the following library declaration if using
28 -- arithmetic functions with Signed or Unsigned values
29 --use IEEE.NUMERIC_STD.ALL;
30 
31 -- Uncomment the following library declaration if instantiating
32 -- any Xilinx primitives in this code.
33 library UNISIM;
34 use UNISIM.VComponents.all;
35 Library UNIMACRO;
36 use UNIMACRO.vcomponents.all;
37 
38 entity ddr_rport is
39  Port ( memclk : in STD_LOGIC;
40  sysclk : in STD_LOGIC;
41  reset : in STD_LOGIC;
42  resetSys : in STD_LOGIC;
43  resetMem : in STD_LOGIC;
44  run : in STD_LOGIC;
45  test : in STD_LOGIC_VECTOR(1 downto 0); -- memory test
46  test_block_sent : in STD_LOGIC; -- indicating test writing progress. One pulse every 256 32-bit words
47  test_pause : OUT std_logic;
48  test_status : out STD_LOGIC_VECTOR(63 downto 0);
49 -- 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)
50 -- and memory starting address of the segment payload data(24-bit)
51 -- for alignment purposes, each entry occupies 32 bytes of memory space (256 bits)
52  TCP_dout : out STD_LOGIC_VECTOR(31 downto 0); -- TCP data are written in unit of 32-bit words
53  TCP_dout_type : out STD_LOGIC_VECTOR(2 downto 0); -- TCP data destination
54  TCP_addr : in STD_LOGIC_VECTOR(28 downto 0); -- 28-26 encoded request source 25-0 address in 64 bit word
55  TCP_length : in STD_LOGIC_VECTOR(12 downto 0); -- in 64 bit word, actual length - 1
56  TCP_dout_valid : out STD_LOGIC;
57  TCP_rqst : in STD_LOGIC;
58  TCP_ack : out STD_LOGIC;
59  TCP_lastword : out STD_LOGIC;
60 -- ipbus signals
61  ipb_clk : in STD_LOGIC;
62  ipb_write : in STD_LOGIC;
63  ipb_strobe : in STD_LOGIC;
64  ipb_addr : in STD_LOGIC_VECTOR(31 downto 0);
65  ipb_rdata : out STD_LOGIC_VECTOR(31 downto 0);
66  ipb_ack : out STD_LOGIC;
67  page_addr : in STD_LOGIC_VECTOR(9 downto 0); -- monitored event memory window
68  cs_out : out STD_LOGIC_VECTOR(511 downto 0);
69 -- ddr3 user interface
70  app_rqst : out STD_LOGIC; -- request to output data
71  app_ack : in STD_LOGIC; -- permission to output data
72  app_rdy : in STD_LOGIC;
73  app_en : out STD_LOGIC;
74  app_rd_data_valid : in STD_LOGIC;
75  app_rd_data : in STD_LOGIC_VECTOR(255 downto 0);
76  app_addr : out STD_LOGIC_VECTOR (27 downto 0) := (others => '0')); -- in unit of 32bit word, bit 27 is not used
77 end ddr_rport;
78 
79 architecture Behavioral of ddr_rport is
80 COMPONENT FIFO_RESET_7S
81  PORT(
82  reset : IN std_logic;
83  clk : IN std_logic;
84  fifo_rst : OUT std_logic;
85  fifo_en : OUT std_logic
86  );
87 END COMPONENT;
88 COMPONENT RAM32x6D
89  PORT(
90  wclk : IN std_logic;
91  rclk : IN std_logic;
92  di : IN std_logic_vector(5 downto 0);
93  we : IN std_logic;
94  wa : IN std_logic_vector(4 downto 0);
95  ra : IN std_logic_vector(4 downto 0);
96  ceReg : IN std_logic;
97  do : OUT std_logic_vector(5 downto 0)
98  );
99 END COMPONENT;
100 COMPONENT RAM32x6Db
101  PORT(
102  wclk : IN std_logic;
103  di : IN std_logic_vector(5 downto 0);
104  we : IN std_logic;
105  wa : IN std_logic_vector(4 downto 0);
106  ra : IN std_logic_vector(4 downto 0);
107  do : OUT std_logic_vector(5 downto 0)
108  );
109 END COMPONENT;
110 signal TCPqueue_we : std_logic := '0';
111 signal ipb_start_addr : std_logic_vector(26 downto 0) := (others => '0');
112 signal ipbReadSyncRegs : std_logic_vector(3 downto 0) := (others => '0');
113 signal ipbRead : std_logic := '0';
114 signal ipbRead_q : std_logic := '0';
115 signal ipb_ack_i : std_logic := '0';
116 signal ipb_rqst : std_logic := '0';
117 signal ipb_raddr : std_logic_vector(23 downto 0) := (others => '0');
118 signal ipb_seq : std_logic_vector(1 downto 0) := (others => '0');
119 signal ipb_rqst_cnt : std_logic_vector(1 downto 0) := (others => '0');
120 signal ipb_rqst_inqueue : std_logic_vector(1 downto 0) := (others => '0');
121 signal ipb_rqstSyncRegs : std_logic_vector(3 downto 0) := (others => '0');
122 signal queue_we : std_logic := '0';
123 signal queue_ceReg : std_logic := '0';
124 signal queue_do_vld : std_logic := '0';
125 signal TCP_addr1and0 : std_logic_vector(1 downto 0) := (others => '0');
126 signal queue_di : std_logic_vector(29 downto 0) := (others => '0');
127 signal queue_do : std_logic_vector(29 downto 0) := (others => '0');
128 signal queue_wa : std_logic_vector(4 downto 0) := (others => '0');
129 signal queue_ra : std_logic_vector(4 downto 0) := (others => '0');
130 signal queue_wap : std_logic_vector(3 downto 0) := (others => '0');
131 signal queue_wa0SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
132 signal queue_wa1SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
133 signal queue_wa2SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
134 signal queue_wa3SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
135 signal Oqueue_di : std_logic_vector(12 downto 0) := (others => '0');
136 signal Oqueue_dop : std_logic_vector(12 downto 0) := (others => '0');
137 signal Oqueue_do : std_logic_vector(12 downto 0) := (others => '0');
138 signal Oqueue_a : std_logic_vector(3 downto 0) := (others => '1');
139 signal Oqueue_re : std_logic := '0';
140 signal Oqueue_do_vld : std_logic := '0';
141 signal test_wc : std_logic_vector(3 downto 0) := (others => '0');
142 signal lfsr: std_logic_vector(31 downto 0) := (others => '0');
143 signal testErr : std_logic := '0';
144 signal testCntr: std_logic_vector(30 downto 0) := (others => '0');
145 signal app_rqst_i : std_logic := '0';
146 signal app_ren : std_logic := '0';
147 signal last_word : std_logic := '0';
148 signal s_demux : std_logic_vector(2 downto 0) := (others => '0');
149 signal data_demux : std_logic_vector(31 downto 0) := (others => '0');
150 signal lengthCntr : std_logic_vector(7 downto 0) := (others => '0');
151 signal rd_cnt : std_logic_vector(4 downto 0) := (others => '0');
152 signal app_addr_i : std_logic_vector(27 downto 0) := (others => '0');
153 signal fifo_en : std_logic := '0';
154 signal fifo_rst : std_logic := '0';
155 signal buf_empty : std_logic_vector(3 downto 0) := (others => '0');
156 signal buf_we : std_logic := '0';
157 signal buf_re : std_logic := '0';
158 signal buf_di : std_logic_vector(255 downto 0) := (others => '0');
159 signal buf_do : std_logic_vector(255 downto 0) := (others => '0');
160 signal TCPqueue_do_vld : std_logic := '0';
161 signal TCP_rrqst : std_logic := '0';
162 signal TCP_raddr : std_logic_vector(23 downto 0) := (others => '0');
163 signal TCP_raddr_end : std_logic_vector(12 downto 0) := (others => '0');
164 signal TCP_rlengthp : std_logic_vector(6 downto 0) := (others => '0');
165 signal TCP_rlength : std_logic_vector(7 downto 0) := (others => '0');
166 signal TCPqueue_di : std_logic_vector(41 downto 0) := (others => '0');
167 signal TCPqueue_dop : std_logic_vector(41 downto 0) := (others => '0');
168 signal TCPqueue_do : std_logic_vector(41 downto 0) := (others => '0');
169 signal TCPqueue_a : std_logic_vector(3 downto 0) := (others => '1');
170 signal Last_TCP_addr : std_logic_vector(12 downto 0) := (others => '0');
171 signal first_test_read : std_logic := '1';
172 signal sel_TCP : std_logic := '0';
173 signal rd_ipb : std_logic := '0';
174 signal ipbus_rbuf_wa : std_logic_vector(4 downto 0) := (others => '0');
175 signal ipbus_rbuf_ra : std_logic_vector(4 downto 0) := (others => '0');
176 signal ipbus_rbuf_di : std_logic_vector(257 downto 0) := (others => '0');
177 signal ipbus_rbuf_do : std_logic_vector(257 downto 0) := (others => '0');
178 signal ipbus_rbuf_wa2SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
179 signal ipbus_rbuf_wa1SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
180 signal ipbus_rbuf_wa0SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
181 signal ipbus_rbuf_wap : std_logic_vector(2 downto 0) := (others => '0');
182 signal ipb_rdata_i : std_logic_vector(31 downto 0) := (others => '0');
183 signal rd_queue_o : std_logic_vector(2 downto 0) := (others => '0');
184 signal rd_queue_q : std_logic_vector(2 downto 0) := (others => '0');
185 signal rd_queue_wa : std_logic_vector(5 downto 0) := (others => '0');
186 signal rd_queue_ra : std_logic_vector(5 downto 0) := (others => '0');
187 signal rd_queue_q_vld : std_logic := '0';
188 signal WRCOUNT : array4x9;
189 signal RDCOUNT : array4x9;
190 signal TCP_dout_valid_i : std_logic := '0';
191 signal TCP_lastword_i : std_logic := '0';
192 COMPONENT chipscope
193  generic (N : integer := 5);
194  PORT(
195  clka : IN std_logic;
196  clkb : IN std_logic;
197  ina : IN std_logic_vector(135 downto 0);
198  inb : IN std_logic_vector(135 downto 0)
199  );
200 END COMPONENT;
201 COMPONENT chipscope1
202  generic (N : integer := 5);
203  PORT(
204  clk : IN std_logic;
205  Din : IN std_logic_vector(303 downto 0)
206  );
207 END COMPONENT;
208 COMPONENT chipscope1b
209  generic (USER2 : boolean := false);
210  PORT(
211  clk : IN std_logic;
212  Din : IN std_logic_vector(303 downto 0)
213  );
214 END COMPONENT;
215 signal chk_SEQ : std_logic := '0';
216 signal bad_SEQ : std_logic := '0';
217 signal NXT_SEQ : std_logic_vector(15 downto 0) := (others => '0');
218 signal ina : std_logic_vector(135 downto 0) := (others => '0');
219 signal inb : std_logic_vector(135 downto 0) := (others => '0');
220 signal cs_in : std_logic_vector(303 downto 0) := (others => '0');
221 begin
222 cs_out(165) <= app_rdy;
223 cs_out(164) <= app_ack;
224 cs_out(163) <= app_rqst_i;
225 cs_out(162 downto 159) <= queue_wap(3 downto 0);
226 cs_out(158 downto 155) <= queue_ra(3 downto 0);
227 cs_out(154 downto 149) <= cs_in(247 downto 242);
228 cs_out(148 downto 105) <= cs_in(166 downto 123);
229 cs_out(104 downto 0) <= cs_in(104 downto 0);
230 --i_chipscope1b: chipscope1b PORT MAP(
231 -- clk => sysclk,
232 -- din => cs_in
233 -- );
234 cs_in(297) <= Oqueue_do_vld;
235 cs_in(296) <= buf_empty(0);
236 cs_in(295 downto 292) <= Oqueue_do(12 downto 9);
237 cs_in(291) <= Oqueue_re;
238 cs_in(290) <= TCP_rrqst;
239 --cs_in(289) <= TCP_addr(29);
240 cs_in(288) <= bad_SEQ;
241 --cs_in() <= ;
242 --cs_in() <= ;
243 --cs_in() <= ;
244 cs_in(280) <= TCP_lastword_i;
245 --cs_in( downto ) <= ;
246 --cs_in( downto ) <= ;
247 cs_in(279 downto 251) <= TCP_addr(28 downto 0);
248 cs_in(250 downto 247) <= buf_empty;
249 cs_in(246) <= queue_we;
250 cs_in(245) <= Oqueue_re;
251 cs_in(244) <= Oqueue_do_vld;
252 cs_in(242) <= buf_re;
253 cs_in(241) <= TCP_rrqst;
254 cs_in(240 downto 239) <= TCP_addr1and0;
255 cs_in(227 downto 220) <= TCP_rlength;
256 cs_in(219 downto 213) <= TCP_rlengthp;
257 cs_in(190 downto 167) <= TCP_raddr;
258 cs_in(166 downto 163) <= TCPqueue_a;
259 cs_in(104 downto 73) <= data_demux;
260 cs_in(72 downto 70) <= s_demux;
261 cs_in(69 downto 62) <= lengthCntr;
262 cs_in(61 downto 58) <= Oqueue_a;
263 cs_in(57 downto 45) <= Oqueue_do;
264 cs_in(44 downto 32) <= Oqueue_di;
265 cs_in(31) <= TCP_dout_valid_i;
266 cs_in(30) <= TCPqueue_we;
267 cs_in(29) <= TCPqueue_do_vld;
268 cs_in(28 downto 0) <= queue_di(28 downto 0);
269 test_pause <= test_wc(3) or testErr;
270 ipb_rdata <= ipb_rdata_i;
271 ipb_ack <= ipb_ack_i;
272 app_rqst <= '0' when app_rqst_i = '0' or (last_word = '1' and app_ren = '1') else '1';
273 app_en <= app_ren;
274 app_ren <= app_ack and app_rdy;
275 TCP_ack <= TCPqueue_we;
276 --test_status(5 downto 0) <= rd_queue_ra;
277 --test_status(11 downto 6) <= rd_queue_wa;
278 --test_status(12) <= rd_queue_q_vld;
279 --test_status(13) <= queue_do_vld;
280 --test_status(14) <= Oqueue_do_vld;
281 --test_status(18 downto 15) <= Oqueue_a;
282 --test_status(22 downto 19) <= queue_wa(3 downto 0);
283 --test_status(26 downto 23) <= queue_ra(3 downto 0);
284 --test_status(30 downto 27) <= TCPqueue_a;
285 --test_status(40 downto 31) <= Oqueue_do(9 downto 0);
286 --test_status(48 downto 41) <= lengthCntr;
287 --test_status(51 downto 49) <= s_demux;
288 test_status(31 downto 0) <= testErr & testCntr;
289 --test_status(32) <= '0';
290 --test_status(33) <= first_test_read;
291 --test_status(40 downto 34) <= (others => '0');
292 --test_status(46 downto 41) <= rd_queue_ra;
293 --test_status(52 downto 47) <= rd_queue_wa;
294 --test_status(55 downto 53) <= ipbus_rbuf_ra(2 downto 0);
295 --test_status(58 downto 56) <= ipbus_rbuf_wap;
296 --test_status(62 downto 59) <= test_wc;
297 test_status(63 downto 32) <= (others => '0');
298 app_addr <= app_addr_i;
299 TCP_dout <= data_demux;
300 TCP_dout_valid <= TCP_dout_valid_i;
301 TCP_lastword <= TCP_lastword_i;
302 ipb_ack_i <= '0' when ipbRead = '0' or ipbus_rbuf_wap = ipbus_rbuf_ra(2 downto 0) else ipb_strobe;
303 process(ipb_clk)
304 begin
305  if(ipb_clk'event and ipb_clk = '1')then
306  if(reset = '1')then
307  ipb_rqst <= '0';
308  elsif((ipbRead = '1' and ipbRead_q = '0') or (first_test_read = '1' and test_wc(2) = '1'))then
309  ipb_rqst <= '1';
310  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
311  ipb_rqst <= '1';
312  elsif((ipbus_rbuf_ra(2 downto 0) = "001" or ipbus_rbuf_ra(2 downto 0) = "111") and testCntr(2 downto 0) = "001")then
313  ipb_rqst <= '1';
314  else
315  ipb_rqst <= '0';
316  end if;
317  if(test(0) = '0')then
318  first_test_read <= '1';
319  elsif(ipb_rqst = '1')then
320  first_test_read <= '0';
321  end if;
322  if(reset = '1' or test(0) = '0')then
323  test_wc <= (others => '0');
324  elsif(test_block_sent = '1' and ipb_rqst = '0')then
325  test_wc <= test_wc + 1;
326  elsif(test_block_sent = '0' and ipb_rqst = '1')then
327  test_wc <= test_wc - 1;
328  end if;
329  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
330  ipbRead <= '1';
331  else
332  ipbRead <= '0';
333  end if;
334  ipbRead_q <= ipbRead;
335  if(ipbRead = '0')then
336  if(ipb_addr(27) = '1')then
337  ipb_start_addr <= ipb_addr(26 downto 0);
338  elsif(ipb_addr(17) = '1')then
339  ipb_start_addr <= page_addr & ipb_addr(16 downto 0);
340  end if;
341  end if;
342  if(ipbRead = '0' and test(0) = '0')then
343  ipbus_rbuf_ra <= (others => '0');
344  elsif((ipb_ack_i = '1' and ipb_addr(2 downto 0) = "111") or testCntr(2 downto 0) = "111")then
345  case ipbus_rbuf_ra(2 downto 0) is
346  when "000" => ipbus_rbuf_ra(2 downto 0) <= "001";
347  when "001" => ipbus_rbuf_ra(2 downto 0) <= "011";
348  when "011" => ipbus_rbuf_ra(2 downto 0) <= "010";
349  when "010" => ipbus_rbuf_ra(2 downto 0) <= "110";
350  when "110" => ipbus_rbuf_ra(2 downto 0) <= "111";
351  when "111" => ipbus_rbuf_ra(2 downto 0) <= "101";
352  when "101" => ipbus_rbuf_ra(2 downto 0) <= "100";
353  when others => ipbus_rbuf_ra(2 downto 0) <= "000";
354  end case;
355  end if;
356  if(ipbRead = '0' and test(0) = '0')then
357  ipbus_rbuf_wa2SyncRegs <= "000";
358  ipbus_rbuf_wa1SyncRegs <= "000";
359  ipbus_rbuf_wa0SyncRegs <= "000";
360  ipbus_rbuf_wap <= "000";
361  else
362  ipbus_rbuf_wa2SyncRegs <= ipbus_rbuf_wa2SyncRegs(1 downto 0) & ipbus_rbuf_wa(2);
363  ipbus_rbuf_wa1SyncRegs <= ipbus_rbuf_wa1SyncRegs(1 downto 0) & ipbus_rbuf_wa(1);
364  ipbus_rbuf_wa0SyncRegs <= ipbus_rbuf_wa0SyncRegs(1 downto 0) & ipbus_rbuf_wa(0);
365  ipbus_rbuf_wap(2) <= ipbus_rbuf_wa2SyncRegs(2);
366  ipbus_rbuf_wap(1) <= ipbus_rbuf_wa1SyncRegs(2);
367  ipbus_rbuf_wap(0) <= ipbus_rbuf_wa0SyncRegs(2);
368  end if;
369  if(reset = '1' or test(0) = '0')then
370  testErr <= '0';
371  testCntr <= (others => '0');
372  elsif(ipbus_rbuf_wap /= ipbus_rbuf_ra(2 downto 0))then
373  if(lfsr /= ipb_rdata_i)then
374  testErr <= '1';
375  end if;
376  if(testErr = '0')then
377  testCntr <= testCntr + 1;
378  end if;
379  end if;
380  if(test(0) = '0')then
381  lfsr <= (others => '0');
382  elsif(ipbus_rbuf_wap /= ipbus_rbuf_ra(2 downto 0))then
383  if(test(1) = '0')then
384  lfsr <= lfsr(30 downto 0) & not(lfsr(31) xor lfsr(21) xor lfsr(1) xor lfsr(0));
385  else
386  lfsr <= lfsr + 1;
387  end if;
388  end if;
389  end if;
390 end process;
391 process(ipb_addr,ipbus_rbuf_do,testCntr)
392 variable s : std_logic_vector(2 downto 0);
393 begin
394  if(test(0) = '0')then
395  s := ipb_addr(2 downto 0);
396  else
397  s := testCntr(2 downto 0);
398  end if;
399  case s is
400  when "000" => ipb_rdata_i <= ipbus_rbuf_do(31 downto 0);
401  when "001" => ipb_rdata_i <= ipbus_rbuf_do(63 downto 32);
402  when "010" => ipb_rdata_i <= ipbus_rbuf_do(95 downto 64);
403  when "011" => ipb_rdata_i <= ipbus_rbuf_do(127 downto 96);
404  when "100" => ipb_rdata_i <= ipbus_rbuf_do(159 downto 128);
405  when "101" => ipb_rdata_i <= ipbus_rbuf_do(191 downto 160);
406  when "110" => ipb_rdata_i <= ipbus_rbuf_do(223 downto 192);
407  when others => ipb_rdata_i <= ipbus_rbuf_do(255 downto 224);
408  end case;
409 end process;
410 g_TCPqueue: for i in 0 to 41 generate
411  i_TCPqueue : SRL16E
412  port map (
413  Q => TCPqueue_dop(i), -- SRL data output
414  A0 => TCPqueue_a(0), -- Select[0] input
415  A1 => TCPqueue_a(1), -- Select[1] input
416  A2 => TCPqueue_a(2), -- Select[2] input
417  A3 => TCPqueue_a(3), -- Select[3] input
418  CE => TCPqueue_we, -- Clock enable input
419  CLK => sysclk, -- Clock input
420  D => TCPqueue_di(i) -- SRL data input
421  );
422 end generate;
423 g_Oqueue: for i in 0 to 12 generate
424  i_Oqueue : SRL16E
425  port map (
426  Q => Oqueue_dop(i), -- SRL data output
427  A0 => Oqueue_a(0), -- Select[0] input
428  A1 => Oqueue_a(1), -- Select[1] input
429  A2 => Oqueue_a(2), -- Select[2] input
430  A3 => Oqueue_a(3), -- Select[3] input
431  CE => queue_we, -- Clock enable input
432  CLK => sysclk, -- Clock input
433  D => Oqueue_di(i) -- SRL data input
434  );
435 end generate;
436 g_queue : for i in 0 to 4 generate
437  i_queue : RAM32X6D
438  port map (
439  wclk => sysclk,
440  rclk => memclk,
441  di => queue_di(i*6+5 downto i*6),
442  we => queue_we,
443  wa => queue_wa,
444  ra => queue_ra,
445  ceReg => queue_ceReg,
446  do => queue_do(i*6+5 downto i*6)
447  );
448 end generate;
449 queue_ceReg <= '1' when queue_do_vld = '0' or (last_word = '1' and app_ren = '1' and sel_TCP = '1') else '0';
450 TCP_rlengthp <= TCP_rlength(6 downto 0) + "0000011";
451 TCPqueue_di <= Last_TCP_addr & TCP_addr(28 downto 0);
452 process(sysclk)
453 variable dif : std_logic_vector(7 downto 0);
454 begin
455  dif := (Oqueue_do(8 downto 2) & '0') - lengthCntr;
456  if(sysclk'event and sysclk = '1')then
457  if(resetSys = '1' or run = '0' or TCPqueue_we = '1')then
458  TCPqueue_we <= '0';
459  elsif(TCP_rqst = '1')then
460  TCPqueue_we <= '1';
461  end if;
462  Last_TCP_addr <= TCP_addr(12 downto 0) + TCP_length;
463  if(resetSys = '1')then
464  TCPqueue_a <= (others => '1');
465  elsif(TCPqueue_we = '1' and (and_reduce(TCPqueue_a) = '1' or TCPqueue_do_vld = '1'))then
466  TCPqueue_a <= TCPqueue_a + 1;
467  elsif(TCPqueue_we = '0' and and_reduce(TCPqueue_a) = '0' and TCPqueue_do_vld = '0')then
468  TCPqueue_a <= TCPqueue_a - 1;
469  end if;
470  if(resetSys = '1' or (queue_we = '1' and Oqueue_di(9) = '1'))then
471  TCPqueue_do_vld <= '0';
472  elsif(and_reduce(TCPqueue_a) = '0')then
473  TCPqueue_do_vld <= '1';
474  end if;
475  if(TCPqueue_do_vld = '0')then
476  TCPqueue_do <= TCPqueue_dop;
477  end if;
478  if(resetSys = '1')then
479  TCP_rrqst <= '0';
480  elsif(queue_we = '1' and Oqueue_di(9) = '1')then
481  TCP_rrqst <= '0';
482  elsif(TCPqueue_do_vld = '1')then
483  TCP_rrqst <= '1';
484  end if;
485  if(TCP_rrqst = '0')then
486  TCP_addr1and0 <= TCPqueue_do(1 downto 0);
487  TCP_raddr <= TCPqueue_do(25 downto 2); -- in unit of 256 bit word
488  TCP_raddr_end(12 downto 7) <= TCPqueue_do(41 downto 36) - 1;
489  TCP_raddr_end(6 downto 0) <= TCPqueue_do(35 downto 29);
490  if(TCPqueue_do(12 downto 7) = TCPqueue_do(41 downto 36))then
491  TCP_rlength(7) <= '1';
492  TCP_rlength(6 downto 0) <= TCPqueue_do(35 downto 29) - TCPqueue_do(6 downto 0) + 1;
493  else
494  TCP_rlength(7) <= '0';
495  TCP_rlength(6 downto 0) <= "0000000" - TCPqueue_do(6 downto 0);
496  end if;
497  Oqueue_di(12 downto 10) <= TCPqueue_do(28 downto 26);
498  elsif(queue_we = '1')then
499  TCP_addr1and0 <= "00";
500  TCP_raddr(23 downto 5) <= TCP_raddr(23 downto 5) + 1;
501  TCP_raddr(4 downto 0) <= (others => '0');
502  if(TCP_raddr(10 downto 5) = TCP_raddr_end(12 downto 7))then
503  TCP_rlength(7) <= '1';
504  TCP_rlength(6 downto 0) <= (TCP_raddr_end(6 downto 0) + 1);
505  else
506  TCP_rlength <= (others => '0');
507  end if;
508  end if;
509  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
510  TCP_dout_valid_i <= '0';
511  else
512  TCP_dout_valid_i <= '1';
513  end if;
514  case s_demux is
515  when "000" => data_demux <= buf_do(31 downto 0);
516  when "001" => data_demux <= buf_do(63 downto 32);
517  when "010" => data_demux <= buf_do(95 downto 64);
518  when "011" => data_demux <= buf_do(127 downto 96);
519  when "100" => data_demux <= buf_do(159 downto 128);
520  when "101" => data_demux <= buf_do(191 downto 160);
521  when "110" => data_demux <= buf_do(223 downto 192);
522  when others => data_demux <= buf_do(255 downto 224);
523  end case;
524  if(resetSys = '1' or (Oqueue_do(9) = '1' and Oqueue_re = '1'))then
525  chk_SEQ <= '0';
526  elsif(Oqueue_do(12) = '0' and s_demux = "001")then
527  chk_SEQ <= '1';
528  end if;
529  if(Oqueue_do(12) = '0' and s_demux(1 downto 0) = "10")then
530  NXT_SEQ <= data_demux(15 downto 0);
531  end if;
532  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
533  bad_SEQ <= '1';
534  else
535  bad_SEQ <= '0';
536  end if;
537  TCP_dout_type <= Oqueue_do(12 downto 10);
538  if(buf_empty(0) = '1' or Oqueue_re = '1')then
539  s_demux <= "000";
540  else
541  s_demux <= s_demux + 1;
542  end if;
543  if(resetSys = '1' or queue_we = '1')then
544  queue_we <= '0';
545  elsif(TCP_rrqst = '1' and Oqueue_a(3 downto 2) /= "01")then
546  queue_we <= '1';
547  else
548  queue_we <= '0';
549  end if;
550  queue_di(23 downto 0) <= TCP_raddr;
551  queue_di(28 downto 24) <= TCP_rlengthp(6 downto 2); -- length in 256-bit words
552  Oqueue_di(1 downto 0) <= TCP_addr1and0;
553  Oqueue_di(8 downto 2) <= TCP_rlength(6 downto 0); -- length in 64-bit words
554  Oqueue_di(9) <= TCP_rlength(7);
555  if(resetSys = '1')then
556  Oqueue_do_vld <= '0';
557  elsif(Oqueue_a /= x"f")then
558  Oqueue_do_vld <= '1';
559  elsif(Oqueue_re = '1')then
560  Oqueue_do_vld <= '0';
561  end if;
562  if(Oqueue_do_vld = '0' or Oqueue_re = '1')then
563  Oqueue_do <= Oqueue_dop;
564  end if;
565  if(resetSys = '1' or Oqueue_re = '1' or (lengthCntr = x"01" and s_demux(2 downto 1) < Oqueue_do(1 downto 0)))then
566  lengthCntr <= x"01";
567  elsif(buf_empty(0) = '0')then
568  lengthCntr <= lengthCntr + 1;
569  end if;
570  if(resetSys = '1')then
571  Oqueue_re <= '0';
572  TCP_lastword_i <= '0';
573  elsif(lengthCntr = (Oqueue_do(8 downto 2) & '0') and buf_empty(0) = '0')then
574  Oqueue_re <= '1';
575  TCP_lastword_i <= Oqueue_do(9);
576  else
577  Oqueue_re <= '0';
578  TCP_lastword_i <= '0';
579  end if;
580  if(resetSys = '1')then
581  Oqueue_a <= (others => '1');
582  elsif(queue_we = '1' and (Oqueue_a = x"f" or (Oqueue_do_vld = '1' and Oqueue_re = '0')))then
583  Oqueue_a <= Oqueue_a + 1;
584  elsif(queue_we = '0' and Oqueue_a /= x"f" and (Oqueue_do_vld = '0' or Oqueue_re = '1'))then
585  Oqueue_a <= Oqueue_a - 1;
586  end if;
587  if(resetSys = '1')then
588  queue_wa <= (others => '0');
589  elsif(queue_we = '1')then
590  queue_wa(1) <= queue_wa(0);
591  queue_wa(0) <= not queue_wa(1);
592  if(queue_wa(1 downto 0) = "10")then
593  queue_wa(3 downto 2) <= queue_wa(3 downto 2) + 1;
594  end if;
595  end if;
596  if(resetSys = '1' or fifo_en = '0' or buf_re = '1')then
597  buf_re <= '0';
598  elsif(s_demux = "110" or (lengthCntr = (Oqueue_do(8 downto 2) & '0') and Oqueue_do(9) = '1'))then
599  buf_re <= '1';
600  end if;
601  end if;
602 end process;
603 process(memclk)
604 begin
605  if(memclk'event and memclk = '1')then
606  if(resetMem = '1')then
607  queue_do_vld <= '0';
608  elsif(queue_wap /= queue_ra(3 downto 0))then
609  queue_do_vld <= '1';
610  elsif(last_word = '1' and app_ren = '1' and sel_TCP = '1')then
611  queue_do_vld <= '0';
612  end if;
613  if(resetMem = '1')then
614  queue_ra <= (others => '0');
615  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
616  queue_ra(1) <= queue_ra(0);
617  queue_ra(0) <= not queue_ra(1);
618  if(queue_ra(1 downto 0) = "10")then
619  queue_ra(3 downto 2) <= queue_ra(3 downto 2) + 1;
620  end if;
621  end if;
622  if(resetMem = '1')then
623  queue_wa0SyncRegs <= (others => '0');
624  queue_wa1SyncRegs <= (others => '0');
625  queue_wap <= (others => '0');
626  else
627  queue_wa0SyncRegs <= queue_wa0SyncRegs(1 downto 0) & queue_wa(0);
628  queue_wa1SyncRegs <= queue_wa1SyncRegs(1 downto 0) & queue_wa(1);
629  queue_wap(0) <= queue_wa0SyncRegs(2);
630  queue_wap(1) <= queue_wa1SyncRegs(2);
631  if(queue_wap(1) = '1' and queue_wa1SyncRegs(2) = '0')then
632  queue_wap(3 downto 2) <= queue_wap(3 downto 2) + 1;
633  end if;
634  end if;
635  if(resetMem = '1' or (last_word = '1' and app_ren = '1'))then
636  app_rqst_i <= '0';
637  elsif(queue_do_vld = '1' or or_reduce(ipb_rqst_cnt) = '1')then
638  app_rqst_i <= '1';
639  end if;
640  if(app_rqst_i = '0')then
641  if(queue_do_vld = '1' and queue_do(28 downto 24) = "00001")then
642  last_word <= '1';
643  else
644  last_word <= '0';
645  end if;
646  elsif(app_ren = '1')then
647  if(rd_cnt = "00010")then
648  last_word <= '1';
649  else
650  last_word <= '0';
651  end if;
652  end if;
653  if(app_rqst_i = '0')then
654  if(or_reduce(ipb_rqst_cnt) = '1')then
655  app_addr_i <= '0' & ipb_raddr & "000";
656  rd_cnt <= "00100";
657  sel_TCP <= '0';
658  elsif(queue_do_vld = '1')then
659  app_addr_i <= '0' & queue_do(23 downto 0) & "000";
660  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)
661  sel_TCP <= '1';
662  end if;
663  elsif(app_ren = '1')then
664  app_addr_i(24 downto 3) <= app_addr_i(24 downto 3) + 1;-- should never carry to app_addr_i(25), must wrap around
665  rd_cnt <= rd_cnt - 1;
666  end if;
667  end if;
668 end process;
669 i_FIFO_RESET_7S: FIFO_RESET_7S PORT MAP(
670  reset => resetMem,
671  clk => memclk ,
672  fifo_rst => fifo_rst,
673  fifo_en => fifo_en
674  );
675 g_rbuf : for i in 0 to 3 generate
676  i_rbuf : FIFO_DUALCLOCK_MACRO
677  generic map (
678  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES"
679  ALMOST_FULL_OFFSET => X"0080", -- Sets almost full threshold
680  ALMOST_EMPTY_OFFSET => X"0080", -- Sets the almost empty threshold
681  DATA_WIDTH => 64, -- Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb")
682  FIFO_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb"
683  FIRST_WORD_FALL_THROUGH => TRUE) -- Sets the FIFO FWFT to TRUE or FALSE
684  port map (
685  ALMOSTEMPTY => open, -- 1-bit output almost empty
686  ALMOSTFULL => open, -- 1-bit output almost full
687  DO => buf_do(i*64+63 downto i*64), -- Output data, width defined by DATA_WIDTH parameter
688  EMPTY => buf_empty(i), -- 1-bit output empty
689  FULL => open, -- 1-bit output full
690  RDCOUNT => RDCOUNT(i), -- Output read count, width determined by FIFO depth
691  RDERR => open, -- 1-bit output read error
692  WRCOUNT => WRCOUNT(i), -- Output write count, width determined by FIFO depth
693  WRERR => open, -- 1-bit output write error
694  DI => buf_di(i*64+63 downto i*64), -- Input data, width defined by DATA_WIDTH parameter
695  RDCLK => sysclk, -- 1-bit input read clock
696  RDEN => buf_re, -- 1-bit input read enable
697  RST => fifo_rst, -- 1-bit input reset
698  WRCLK => memclk, -- 1-bit input write clock
699  WREN => buf_we -- 1-bit input write enable
700  );
701 end generate;
702 buf_di <= app_rd_data;
703 buf_we <= '1' when app_rd_data_valid = '1' and fifo_en = '1' and rd_queue_q(2) = '1' else '0';
704 g_ipbus_rbuf : for i in 0 to 42 generate
705  i_ipbus_rbuf : RAM32x6Db PORT MAP(
706  wclk => memclk ,
707  di => ipbus_rbuf_di(i*6+5 downto i*6),
708  we => app_rd_data_valid,
709  wa => ipbus_rbuf_wa,
710  ra => ipbus_rbuf_ra,
711  do => ipbus_rbuf_do(i*6+5 downto i*6)
712  );
713 end generate;
714 ipbus_rbuf_di(255 downto 0) <= app_rd_data;
715 process(memclk,ipbRead,test)
716 begin
717  if(ipbRead = '0' and test(0) = '0')then
718  ipbus_rbuf_wa(2 downto 0) <= (others => '0');
719  ipb_rqstSyncRegs <= (others => '0');
720  ipb_rqst_cnt <= (others => '0');
721  elsif(memclk'event and memclk = '1')then
722  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
723  case ipbus_rbuf_wa(2 downto 0) is
724  when "000" => ipbus_rbuf_wa(2 downto 0) <= "001";
725  when "001" => ipbus_rbuf_wa(2 downto 0) <= "011";
726  when "011" => ipbus_rbuf_wa(2 downto 0) <= "010";
727  when "010" => ipbus_rbuf_wa(2 downto 0) <= "110";
728  when "110" => ipbus_rbuf_wa(2 downto 0) <= "111";
729  when "111" => ipbus_rbuf_wa(2 downto 0) <= "101";
730  when "101" => ipbus_rbuf_wa(2 downto 0) <= "100";
731  when others => ipbus_rbuf_wa(2 downto 0) <= "000";
732  end case;
733  end if;
734  ipb_rqstSyncRegs <= ipb_rqstSyncRegs(2 downto 0) & ipb_rqst;
735  if(ipb_rqstSyncRegs(3 downto 2) = "10" and (app_rqst_i = '1' or or_reduce(ipb_rqst_cnt) = '0'))then
736  ipb_rqst_cnt <= ipb_rqst_cnt + 1;
737  elsif(ipb_rqstSyncRegs(3 downto 2) /= "10" and app_rqst_i = '0' and or_reduce(ipb_rqst_cnt) = '1')then
738  ipb_rqst_cnt <= ipb_rqst_cnt - 1;
739  end if;
740  end if;
741 end process;
742 ipbus_rbuf_wa(4) <= rd_queue_q(2);
743 process(memclk)
744 begin
745  if(memclk'event and memclk = '1')then
746  ipbReadSyncRegs <= ipbReadSyncRegs(2 downto 0) & ipbRead;
747  if(ipbReadSyncRegs(3 downto 2) = "10")then -- ipb_seq is used to eject stalemate read data
748  ipb_seq <= ipb_seq + 1;
749  end if;
750  if(resetMem = '1')then
751  ipb_raddr <= (others => '0');
752  elsif(ipbReadSyncRegs(3 downto 2) = "01")then
753  ipb_raddr <= ipb_start_addr(26 downto 3);
754  elsif(sel_TCP = '0' and app_ren = '1')then
755  ipb_raddr <= ipb_raddr + 1;
756  end if;
757  if(resetMem = '1')then
758  rd_queue_wa <= (others => '0');
759  elsif(app_ren = '1')then
760  rd_queue_wa <= rd_queue_wa + 1;
761  end if;
762  if(resetMem = '1')then
763  rd_queue_ra <= (others => '0');
764  elsif(rd_queue_wa /= rd_queue_ra and (app_rd_data_valid = '1' or rd_queue_q_vld = '0'))then
765  rd_queue_ra <= rd_queue_ra + 1;
766  end if;
767  if(resetMem = '1')then
768  rd_queue_q_vld <= '0';
769  elsif(rd_queue_wa /= rd_queue_ra)then
770  rd_queue_q_vld <= '1';
771  elsif(app_rd_data_valid = '1')then
772  rd_queue_q_vld <= '0';
773  end if;
774  if(app_rd_data_valid = '1' or rd_queue_q_vld = '0')then
775  rd_queue_q <= rd_queue_o;
776  end if;
777  end if;
778 end process;
779 i_rd_queue : RAM64M
780  port map (
781  DOA => rd_queue_o(0), -- Read port A 1-bit output
782  DOB => rd_queue_o(1), -- Read port B 1-bit output
783  DOC => rd_queue_o(2), -- Read port C 1-bit output
784  DOD => open, -- Read/Write port D 1-bit output
785  ADDRA => rd_queue_ra, -- Read port A 6-bit address input
786  ADDRB => rd_queue_ra, -- Read port B 6-bit address input
787  ADDRC => rd_queue_ra, -- Read port C 6-bit address input
788  ADDRD => rd_queue_wa, -- Read/Write port D 6-bit address input
789  DIA => ipb_seq(0), -- RAM 1-bit data write input addressed by ADDRD,
790  -- read addressed by ADDRA
791  DIB => ipb_seq(1), -- RAM 1-bit data write input addressed by ADDRD,
792  -- read addressed by ADDRB
793  DIC => sel_TCP, -- RAM 1-bit data write input addressed by ADDRD,
794  -- read addressed by ADDRC
795  DID => '0', -- RAM 1-bit data write input addressed by ADDRD,
796  -- read addressed by ADDRD
797  WCLK => memclk, -- Write clock input
798  WE => app_ren -- Write enable input
799  );
800 end Behavioral;