AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
ddr_wportB.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_wportB 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  test : in STD_LOGIC_VECTOR(1 downto 0); -- memory test
45  test_block_sent : out STD_LOGIC := '0'; -- indicating test writing progress. Pulse once every 32 32-bit words
46  test_pause : in std_logic;
47 -- 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)
48 -- and memory starting address of the segment payload data(24-bit)
49 -- for alignment purposes, each entry occupies 32 bytes of memory space (256 bits)
50  TCP_din : in STD_LOGIC_VECTOR(31 downto 0);
51  TCP_channel : in STD_LOGIC_VECTOR(1 downto 0);
52  TCP_we : in std_logic;
53  TCP_wcount : out STD_LOGIC_VECTOR (2 downto 0);
54 -- ipbus signals
55  ipb_clk : in STD_LOGIC;
56  ipb_write : in STD_LOGIC;
57  ipb_strobe : in STD_LOGIC;
58  ipb_addr : in STD_LOGIC_VECTOR(31 downto 0);
59  ipb_wdata : in STD_LOGIC_VECTOR(31 downto 0);
60  ipb_ack : out STD_LOGIC;
61  run : in STD_LOGIC; -- ipbus write is allowed only when run = '0'
62 -- ddr3 user interface
63  app_rqst : out STD_LOGIC; -- request to output data
64  app_ack : in STD_LOGIC; -- permission to output data
65  app_rdy : in STD_LOGIC;
66  app_en : out STD_LOGIC;
67  app_wdf_rdy : in STD_LOGIC;
68  app_wdf_wren : out STD_LOGIC;
69  app_wdf_mask : out STD_LOGIC_VECTOR(7 downto 0);
70  app_addr : out STD_LOGIC_VECTOR (23 downto 0) := (others => '0'); -- starting address of write burst(1Kbytes or until end of event)
71  dout : out STD_LOGIC_VECTOR (255 downto 0) := (others => '0');
72  debug_out : out STD_LOGIC_VECTOR (63 downto 0)
73  );
74 end ddr_wportB;
75 
76 architecture Behavioral of ddr_wportB is
77 COMPONENT RAM32x6D
78  PORT(
79  wclk : IN std_logic;
80  rclk : IN std_logic;
81  di : IN std_logic_vector(5 downto 0);
82  we : IN std_logic;
83  wa : IN std_logic_vector(4 downto 0);
84  ra : IN std_logic_vector(4 downto 0);
85  ceReg : IN std_logic;
86  do : OUT std_logic_vector(5 downto 0)
87  );
88 END COMPONENT;
89 signal TCP_sr : std_logic_vector(63 downto 0) := (others => '0');
90 signal TCP_wc : std_logic_vector(2 downto 0) := (others => '0');
91 signal TCPqueue_di : std_logic_vector(257 downto 0) := (others => '0');
92 signal TCPqueue_do : std_logic_vector(257 downto 0) := (others => '0');
93 signal TCPqueue_we : std_logic_vector(2 downto 0) := (others => '0');
94 signal TCPqueue_wa : std_logic_vector(4 downto 0) := (others => '0');
95 signal TCPqueue_ra : std_logic_vector(4 downto 0) := (others => '0');
96 signal TCPqueue_wap : std_logic_vector(3 downto 0) := (others => '0');
97 signal TCPqueue_wa0SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
98 signal TCPqueue_wa1SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
99 signal TCPqueue_wa2SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
100 signal TCPqueue_wa3SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
101 signal ipb_strobe_q : std_logic := '0';
102 signal ipb_addr0_wr : std_logic := '0';
103 signal ipb_weToggle : std_logic := '0';
104 signal ipb_di : std_logic_vector(31 downto 0) := (others => '0');
105 signal ipb_mask : std_logic_vector(1 downto 0) := (others => '0');
106 signal ipb_addr_q : std_logic_vector(7 downto 0) := (others => '0');
107 signal ipb_waddr : std_logic_vector(26 downto 0) := (others => '0');
108 signal ipb_weToggleSyncRegs : std_logic_vector(3 downto 0) := (others => '0');
109 signal ec_lfsr : std_logic := '0';
110 signal lfsr: std_logic_vector(31 downto 0) := (others => '0');
111 signal lfsrCntr: std_logic_vector(4 downto 0) := (others => '0');
112 signal TCPqueue_ceReg : std_logic := '0';
113 signal TCPqueue_do_vld : std_logic := '0';
114 signal dout_vld : std_logic := '0';
115 signal app_rqst_i : std_logic := '0';
116 signal app_addr_i : std_logic_vector(23 downto 0) := (others => '0');
117 signal app_wren : std_logic := '0';
118 signal TCP_addr : array3X18 := (others => (others => '0'));
119 signal ipb_queue_di : std_logic_vector(31 downto 0) := (others => '0');
120 signal ipb_queue_do : std_logic_vector(31 downto 0) := (others => '0');
121 signal ipb_queue_a : std_logic_vector(3 downto 0) := (others => '1');
122 signal ipb_queue_we : std_logic := '0';
123 signal ipb_wddr : std_logic := '0';
124 signal ipb_wddrSyncRegs : std_logic_vector(3 downto 0) := (others => '0');
125 signal sent_odd : std_logic := '0';
126 signal wcountToggle : std_logic_vector(2 downto 0) := (others => '0');
127 signal wcountToggle0SyncRegs : std_logic_vector(3 downto 0) := (others => '0');
128 signal wcountToggle1SyncRegs : std_logic_vector(3 downto 0) := (others => '0');
129 signal wcountToggle2SyncRegs : std_logic_vector(3 downto 0) := (others => '0');
130 
131 begin
132 app_rqst <= '0' when app_rqst_i = '0' or (TCPqueue_do_vld = '0' and app_wren = '1') else '1';
133 app_addr <= app_addr_i;
134 app_wdf_wren <= app_wren;
135 app_en <= app_wren;
136 app_wren <= app_ack and app_rdy and app_wdf_rdy;
137 ipb_ack <= ipb_strobe and ipb_write and ipb_addr(27) and not run;
138 process(ipb_clk)
139 begin
140  if(ipb_clk'event and ipb_clk = '1')then
141  if(reset = '1' or run = '1')then
142  ipb_weToggle <= '0';
143  elsif((ipb_strobe = '1' and ipb_write = '1' and ipb_addr(27) = '1') or ec_lfsr = '1')then
144  ipb_weToggle <= not ipb_weToggle;
145  end if;
146  ipb_wddr <= not reset and not run and not test(0) and ipb_strobe and ipb_write and ipb_addr(27);
147  ipb_addr_q(7 downto 0) <= ipb_addr(7 downto 0);
148  if(test(0) = '1')then
149  ipb_di <= lfsr;
150  if(test_pause = '0')then
151  ec_lfsr <= '1';
152  elsif(lfsrCntr(2 downto 0) = "111")then
153  ec_lfsr <= '0';
154  end if;
155  else
156  ipb_di(31 downto 0) <= ipb_wdata;
157  ec_lfsr <= '0';
158  end if;
159  if(test(0) = '0')then
160  lfsr <= (others => '0');
161  lfsrCntr <= (others => '0');
162  elsif(ec_lfsr = '1')then
163  if(test(1) = '0')then
164  lfsr <= lfsr(30 downto 0) & not(lfsr(31) xor lfsr(21) xor lfsr(1) xor lfsr(0));
165  else
166  lfsr <= lfsr + 1;
167  end if;
168  lfsrCntr <= lfsrCntr + 1;
169  end if;
170  test_block_sent <= not reset and and_reduce(lfsrCntr);
171  end if;
172 end process;
173 process(sysclk)
174 begin
175  if(sysclk'event and sysclk = '1')then
176  if(resetSys = '1' or run = '0')then
177  TCPqueue_wa <= (others => '0');
178  elsif(TCPqueue_we(2) = '1')then
179  case TCPqueue_wa(3 downto 0) is
180  when x"0" => TCPqueue_wa(3 downto 0) <= x"1";
181  when x"1" => TCPqueue_wa(3 downto 0) <= x"3";
182  when x"3" => TCPqueue_wa(3 downto 0) <= x"2";
183  when x"2" => TCPqueue_wa(3 downto 0) <= x"6";
184  when x"6" => TCPqueue_wa(3 downto 0) <= x"7";
185  when x"7" => TCPqueue_wa(3 downto 0) <= x"5";
186  when x"5" => TCPqueue_wa(3 downto 0) <= x"4";
187  when x"4" => TCPqueue_wa(3 downto 0) <= x"c";
188  when x"c" => TCPqueue_wa(3 downto 0) <= x"d";
189  when x"d" => TCPqueue_wa(3 downto 0) <= x"f";
190  when x"f" => TCPqueue_wa(3 downto 0) <= x"e";
191  when x"e" => TCPqueue_wa(3 downto 0) <= x"a";
192  when x"a" => TCPqueue_wa(3 downto 0) <= x"b";
193  when x"b" => TCPqueue_wa(3 downto 0) <= x"9";
194  when x"9" => TCPqueue_wa(3 downto 0) <= x"8";
195  when others => TCPqueue_wa(3 downto 0) <= x"0";
196  end case;
197  end if;
198  if(TCP_we = '1')then
199  TCP_sr <= TCP_din & TCP_sr(63 downto 32);
200  end if;
201  if(resetSys = '1')then
202  TCP_wc <= "000";
203  elsif(TCP_we = '1')then
204  TCP_wc <= TCP_wc + 1;
205  end if;
206  wcountToggle0SyncRegs <= wcountToggle0SyncRegs(2 downto 0) & wcountToggle(0);
207  wcountToggle1SyncRegs <= wcountToggle1SyncRegs(2 downto 0) & wcountToggle(1);
208  wcountToggle2SyncRegs <= wcountToggle2SyncRegs(2 downto 0) & wcountToggle(2);
209  if(resetSys = '1')then
210  TCP_wcount <= (others => '0');
211  else
212  if(wcountToggle0SyncRegs(3) = wcountToggle0SyncRegs(2))then
213  TCP_wcount(0) <= '0';
214  else
215  TCP_wcount(0) <= '1';
216  end if;
217  if(wcountToggle1SyncRegs(3) = wcountToggle1SyncRegs(2))then
218  TCP_wcount(1) <= '0';
219  else
220  TCP_wcount(1) <= '1';
221  end if;
222  if(wcountToggle2SyncRegs(3) = wcountToggle2SyncRegs(2))then
223  TCP_wcount(2) <= '0';
224  else
225  TCP_wcount(2) <= '1';
226  end if;
227  end if;
228  end if;
229 end process;
230 g_TCPqueue : for i in 0 to 42 generate
231  i_TCPqueue: RAM32x6D PORT MAP(
232  wclk => sysclk ,
233  rclk => memclk ,
234  di => TCPqueue_di(i*6+5 downto i*6),
235  we => TCPqueue_we(i/16),
236  wa => TCPqueue_wa,
237  ra => TCPqueue_ra,
238  ceReg => TCPqueue_ceReg ,
239  do => TCPqueue_do(i*6+5 downto i*6)
240  );
241 end generate;
242 TCPqueue_we(0) <= '1' when TCP_we = '1' and TCP_wc = "010" else '0';
243 TCPqueue_we(1) <= '1' when TCP_we = '1' and TCP_wc = "101" else '0';
244 TCPqueue_we(2) <= '1' when TCP_we = '1' and TCP_wc = "111" else '0';
245 TCPqueue_di(257 downto 256) <= TCP_channel;
246 TCPqueue_di(255 downto 224) <= TCP_din;
247 TCPqueue_di(223 downto 192) <= TCP_sr(63 downto 32);
248 TCPqueue_di(191 downto 160) <= TCP_din;
249 TCPqueue_di(159 downto 96) <= TCP_sr;
250 TCPqueue_di(95 downto 64) <= TCP_din;
251 TCPqueue_di(63 downto 0) <= TCP_sr;
252 TCPqueue_ceReg <= '1' when TCPqueue_do_vld = '0' or dout_vld = '0' or app_wren = '1' else '0';
253 g_ipb_queue: for i in 0 to 31 generate
254  i_ipb_queue : SRL16E
255  port map (
256  Q => ipb_queue_do(i), -- SRL data output
257  A0 => ipb_queue_a(0), -- Select[0] input
258  A1 => ipb_queue_a(1), -- Select[1] input
259  A2 => ipb_queue_a(2), -- Select[2] input
260  A3 => ipb_queue_a(3), -- Select[3] input
261  CE => ipb_queue_we, -- Clock enable input
262  CLK => memclk, -- Clock input
263  D => ipb_queue_di(i) -- SRL data input
264  );
265 end generate;
266 ipb_queue_di <= ipb_di;
267 ipb_queue_we <= ipb_weToggleSyncRegs(3) xor ipb_weToggleSyncRegs(2);
268 process(memclk)
269 begin
270  if(memclk'event and memclk = '1')then
271  if(resetMem = '1')then
272  ipb_weToggleSyncRegs <= (others => '0');
273  ipb_wddrSyncRegs <= (others => '0');
274  else
275  ipb_weToggleSyncRegs <= ipb_weToggleSyncRegs(2 downto 0) & ipb_weToggle;
276  ipb_wddrSyncRegs <= ipb_wddrSyncRegs(2 downto 0) & ipb_wddr;
277  end if;
278  if(resetMem = '1' or run = '1')then
279  ipb_queue_a <= (others => '1');
280  elsif(ipb_weToggleSyncRegs(3) /= ipb_weToggleSyncRegs(2) and app_wren = '0')then
281  ipb_queue_a <= ipb_queue_a + 1;
282  elsif(ipb_weToggleSyncRegs(3) = ipb_weToggleSyncRegs(2) and app_wren = '1' and and_reduce(ipb_queue_a) = '0')then
283  ipb_queue_a <= ipb_queue_a - 1;
284  end if;
285  if(resetMem = '1' or run = '1')then
286  ipb_waddr <= (others => '0');
287  elsif(ipb_wddrSyncRegs(3 downto 2) = "01")then
288  ipb_waddr <= ipb_addr(26 downto 8) & ipb_addr_q;
289  elsif(app_wren = '1')then
290  ipb_waddr <= ipb_waddr + 1;
291  end if;
292  if(resetMem = '1')then
293  TCPqueue_ra <= (others => '0');
294  elsif(TCPqueue_wap /= TCPqueue_ra(3 downto 0) and TCPqueue_ceReg = '1')then
295  case TCPqueue_ra(3 downto 0) is
296  when x"0" => TCPqueue_ra(3 downto 0) <= x"1";
297  when x"1" => TCPqueue_ra(3 downto 0) <= x"3";
298  when x"3" => TCPqueue_ra(3 downto 0) <= x"2";
299  when x"2" => TCPqueue_ra(3 downto 0) <= x"6";
300  when x"6" => TCPqueue_ra(3 downto 0) <= x"7";
301  when x"7" => TCPqueue_ra(3 downto 0) <= x"5";
302  when x"5" => TCPqueue_ra(3 downto 0) <= x"4";
303  when x"4" => TCPqueue_ra(3 downto 0) <= x"c";
304  when x"c" => TCPqueue_ra(3 downto 0) <= x"d";
305  when x"d" => TCPqueue_ra(3 downto 0) <= x"f";
306  when x"f" => TCPqueue_ra(3 downto 0) <= x"e";
307  when x"e" => TCPqueue_ra(3 downto 0) <= x"a";
308  when x"a" => TCPqueue_ra(3 downto 0) <= x"b";
309  when x"b" => TCPqueue_ra(3 downto 0) <= x"9";
310  when x"9" => TCPqueue_ra(3 downto 0) <= x"8";
311  when others => TCPqueue_ra(3 downto 0) <= x"0";
312  end case;
313  end if;
314  if(resetMem = '1')then
315  TCPqueue_do_vld <= '0';
316  elsif(TCPqueue_wap /= TCPqueue_ra(3 downto 0))then
317  TCPqueue_do_vld <= '1';
318  elsif(dout_vld = '0' or app_wren = '1')then
319  TCPqueue_do_vld <= '0';
320  end if;
321  if(resetMem = '1')then
322  dout_vld <= '0';
323  elsif(TCPqueue_do_vld = '1')then
324  dout_vld <= '1';
325  elsif(app_wren = '1')then
326  dout_vld <= '0';
327  end if;
328  if(resetMem = '1')then
329  TCPqueue_wa0SyncRegs <= (others => '0');
330  TCPqueue_wa1SyncRegs <= (others => '0');
331  TCPqueue_wa2SyncRegs <= (others => '0');
332  TCPqueue_wa3SyncRegs <= (others => '0');
333  TCPqueue_wap <= (others => '0');
334  else
335  TCPqueue_wa0SyncRegs <= TCPqueue_wa0SyncRegs(1 downto 0) & TCPqueue_wa(0);
336  TCPqueue_wa1SyncRegs <= TCPqueue_wa1SyncRegs(1 downto 0) & TCPqueue_wa(1);
337  TCPqueue_wa2SyncRegs <= TCPqueue_wa2SyncRegs(1 downto 0) & TCPqueue_wa(2);
338  TCPqueue_wa3SyncRegs <= TCPqueue_wa3SyncRegs(1 downto 0) & TCPqueue_wa(3);
339  TCPqueue_wap(0) <= TCPqueue_wa0SyncRegs(2);
340  TCPqueue_wap(1) <= TCPqueue_wa1SyncRegs(2);
341  TCPqueue_wap(2) <= TCPqueue_wa2SyncRegs(2);
342  TCPqueue_wap(3) <= TCPqueue_wa3SyncRegs(2);
343  end if;
344  if(resetMem = '1' or run = '0')then
345  TCP_addr <= (others => (others => '0'));
346  elsif(TCPqueue_do_vld = '1' and (app_wren = '1' or dout_vld = '0'))then
347  TCP_addr(conv_integer(TCPqueue_do(257 downto 256))) <= TCP_addr(conv_integer(TCPqueue_do(257 downto 256))) + 1;
348  end if;
349  if(run = '1')then
350  app_wdf_mask <= x"00";
351  else
352  for i in 0 to 7 loop
353  if(i = conv_integer(ipb_waddr(2 downto 0)))then
354  app_wdf_mask(i) <= '0';
355  else
356  app_wdf_mask(i) <= '1';
357  end if;
358  end loop;
359  end if;
360  if(run = '1')then
361  if(dout_vld = '0' or app_wren = '1')then
362  dout <= TCPqueue_do(255 downto 0);
363  case TCPqueue_do(257 downto 256) is
364  when "00" => app_addr_i <= "00" & TCP_addr(0)(17 downto 10) & x"f" & TCP_addr(0)(9 downto 0);
365  when "01" => app_addr_i <= "01" & TCP_addr(1)(17 downto 10) & x"f" & TCP_addr(1)(9 downto 0);
366  when others => app_addr_i <= "10" & TCP_addr(2)(17 downto 10) & x"f" & TCP_addr(2)(9 downto 0);
367  end case;
368  end if;
369  else
370  for i in 0 to 7 loop
371  dout(32*i+31 downto 32*i) <= ipb_queue_do;
372  end loop;
373  app_addr_i <= ipb_waddr(26 downto 3);
374  end if;
375  if(resetMem = '1' or run = '0')then
376  sent_odd <= '0';
377  elsif(app_wren = '1')then
378  sent_odd <= not sent_odd;
379  end if;
380  if(app_wren = '1' and sent_odd = '1')then
381  wcountToggle(conv_integer(app_addr_i(23 downto 22))) <= not wcountToggle(conv_integer(app_addr_i(23 downto 22)));
382  end if;
383  if(resetMem = '1')then
384  app_rqst_i <= '0';
385  elsif(app_wren = '1' and TCPqueue_do_vld = '0')then
386  app_rqst_i <= '0';
387  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
388  app_rqst_i <= '1';
389  end if;
390  end if;
391 end process;
392 end Behavioral;
393