AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
ddr_wportA.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_wportA is
39  Port ( sysclk : in STD_LOGIC;
40  memclk : in STD_LOGIC;
41  fifo_rst : in STD_LOGIC;
42  fifo_en : in STD_LOGIC;
43  resetSys : in STD_LOGIC;
44  resetMem : in STD_LOGIC;
45  run : in STD_LOGIC;
46  din : in STD_LOGIC_VECTOR (65 downto 0);
47  din_we : in STD_LOGIC;
48  port_rdy : out STD_LOGIC; -- port ready to accept a new event
49  WrtMonBlkDone : out STD_LOGIC;
50  WrtMonEvtDone : out STD_LOGIC;
51  KiloByte_toggle : out STD_LOGIC;
52  EoB_toggle : out STD_LOGIC;
53  buf_full : out STD_LOGIC;
54  event_addr : in STD_LOGIC_VECTOR (13 downto 0);
55  addr_we : in STD_LOGIC;
56  rqst : out STD_LOGIC; -- request to output data
57  ack : in STD_LOGIC; -- permission to output data
58  app_wdf_rdy : in STD_LOGIC;
59  app_rdy : in STD_LOGIC;
60  app_en : out STD_LOGIC;
61  app_wdf_wren : out STD_LOGIC;
62  app_addr : out STD_LOGIC_VECTOR (23 downto 0) := (others => '0'); -- starting address of write burst(1Kbytes or until end of event)
63  dout : out STD_LOGIC_VECTOR (255 downto 0) := (others => '0');
64  cs_out : out STD_LOGIC_VECTOR (511 downto 0);
65  debug : out STD_LOGIC_VECTOR (63 downto 0)
66  );
67 end ddr_wportA;
68 
69 architecture Behavioral of ddr_wportA is
70 COMPONENT RAM32x6D
71  PORT(
72  wclk : IN std_logic;
73  rclk : IN std_logic;
74  di : IN std_logic_vector(5 downto 0);
75  we : IN std_logic;
76  wa : IN std_logic_vector(4 downto 0);
77  ra : IN std_logic_vector(4 downto 0);
78  ceReg : IN std_logic;
79  do : OUT std_logic_vector(5 downto 0)
80  );
81 END COMPONENT;
82 signal AddrQueue_di : std_logic_vector(13 downto 0) := (others => '0');
83 signal AddrQueue_do : std_logic_vector(13 downto 0) := (others => '0');
84 signal AddrQueue_dop : std_logic_vector(13 downto 12) := (others => '0');
85 signal AddrQueue_wa : std_logic_vector(4 downto 0) := (others => '0');
86 signal AddrQueue_rap : std_logic_vector(1 downto 0) := (others => '0');
87 signal AddrQueue_ra : std_logic_vector(4 downto 0) := (others => '0');
88 signal AddrQueue_wa0SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
89 signal AddrQueue_wa1SyncRegs : std_logic_vector(2 downto 0) := (others => '0');
90 signal EoE_toggleSyncRegs : std_logic_vector(3 downto 0) := (others => '0');
91 signal EoB_toggleSyncRegs : std_logic_vector(3 downto 0) := (others => '0');
92 signal en_din : std_logic := '0';
93 signal rqst_i : std_logic := '0';
94 signal KiloByte_toggle_i : std_logic := '0';
95 signal EoB_toggle_i : std_logic := '0';
96 signal EoE_toggle_i : std_logic := '0';
97 signal last_word : std_logic := '0';
98 signal EventDone : std_logic := '0';
99 signal EventDone_dl : std_logic := '0';
100 signal FIFO_empty : std_logic := '1';
101 --signal FIFO_empty_q : std_logic := '1';
102 signal FIFO_AlmostEmpty : std_logic := '1';
103 signal FIFO_sel : std_logic_vector(1 downto 0) := (others => '0');
104 signal FIFO_we : std_logic_vector(3 downto 0) := (others => '0');
105 signal FIFO_DI : std_logic_vector(65 downto 0) := (others => '0');
106 signal FIFO_DO : std_logic_vector(257 downto 0) := (others => '0');
107 signal WRCOUNT : array4x9;
108 signal RDCOUNT : array4x9;
109 signal dout_wc : std_logic_vector(4 downto 0) := (others => '0');
110 signal app_wren : std_logic := '0';
111 signal app_addr_i : std_logic_vector(13 downto 0) := (others => '0');
112 begin
113 --process(memclk)
114 --begin
115 -- if(memclk'event and memclk = '1')then
116 -- cs_out(39) <= rqst_i and ack and fifo_empty;
117 -- cs_out(38) <= rqst_i and fifo_empty;
118 -- end if;
119 --end process;
120 cs_out(42) <= app_wdf_rdy;
121 cs_out(41) <= app_rdy;
122 cs_out(40) <= ack;
123 cs_out(37) <= din(64);
124 cs_out(36) <= din_we;
125 cs_out(35) <= en_din;
126 cs_out(34 downto 31) <= FIFO_we;
127 cs_out(30 downto 29) <= FIFO_sel;
128 cs_out(28 downto 25) <= EoE_toggleSyncRegs;
129 cs_out(24 downto 23) <= AddrQueue_rap;
130 cs_out(22 downto 21) <= AddrQueue_wa(1 downto 0);
131 cs_out(20) <= EoE_toggle_i;
132 cs_out(19) <= EoB_toggle_i;
133 cs_out(18) <= rqst_i;
134 cs_out(17) <= EventDone;
135 cs_out(16) <= last_word;
136 cs_out(15) <= FIFO_DO(256);
137 cs_out(14) <= FIFO_AlmostEmpty;
138 cs_out(13) <= FIFO_empty;
139 cs_out(12 downto 10) <= AddrQueue_wa0SyncRegs;
140 cs_out(9 downto 7) <= AddrQueue_wa1SyncRegs;
141 cs_out(6 downto 5) <= AddrQueue_ra(1 downto 0);
142 cs_out(4 downto 0) <= dout_wc;
143 --cs_out(14) <= rqst_i;
144 --cs_out(13) <= EventDone;
145 --cs_out(12) <= last_word;
146 --cs_out(11) <= FIFO_DO(256);
147 --cs_out(10) <= FIFO_AlmostEmpty;
148 --cs_out(9) <= FIFO_empty;
149 --cs_out(8) <= AddrQueue_wa0SyncRegs(2);
150 --cs_out(7) <= AddrQueue_wa1SyncRegs(2);
151 --cs_out(6 downto 5) <= AddrQueue_ra(1 downto 0);
152 --cs_out(4 downto 0) <= dout_wc;
153 debug(63 downto 1) <= (others => '0');
154 process(memclk)
155 begin
156  if(memclk'event and memclk = '1')then
157  if(resetMem = '1')then
158  debug(0) <= '0';
159  elsif(ack = '1' and fifo_empty = '1')then
160  debug(0) <= '1';
161  end if;
162  end if;
163 end process;
164 KiloByte_toggle <= KiloByte_toggle_i;
165 EoB_toggle <= EoB_toggle_i;
166 rqst <= '0' when rqst_i = '0' or ((FIFO_DO(256) = '1' or last_word = '1') and app_wren = '1') else '1';
167 app_wdf_wren <= app_wren;
168 app_en <= app_wren;
169 --app_wren <= ack and app_rdy and app_wdf_rdy and not FIFO_empty and not FIFO_empty_q;
170 app_wren <= ack and app_rdy and app_wdf_rdy;
171 app_addr <= AddrQueue_do(13 downto 4) & app_addr_i;
172 g_AddrQueue : for i in 0 to 1 generate
173  i_AddrQueue: RAM32x6D PORT MAP(
174  wclk => sysclk ,
175  rclk => memclk ,
176  di => AddrQueue_di(i*6+5 downto i*6),
177  we => addr_we,
178  wa => AddrQueue_wa,
179  ra => AddrQueue_ra,
180  ceReg => '1',
181  do => AddrQueue_do(i*6+5 downto i*6)
182  );
183  i_AddrQueueH : RAM32X1D
184  port map (
185  DPO => AddrQueue_dop(i+12), -- Read-only 1-bit data output
186  SPO => open, -- R/W 1-bit data output
187  A0 => AddrQueue_wa(0), -- R/W address[0] input bit
188  A1 => AddrQueue_wa(1), -- R/W address[1] input bit
189  A2 => AddrQueue_wa(2), -- R/W address[2] input bit
190  A3 => AddrQueue_wa(3), -- R/W address[3] input bit
191  A4 => AddrQueue_wa(4), -- R/W address[4] input bit
192  D => AddrQueue_di(i+12), -- Write 1-bit data input
193  DPRA0 => AddrQueue_ra(0), -- Read-only address[0] input bit
194  DPRA1 => AddrQueue_ra(1), -- Read-only address[1] input bit
195  DPRA2 => AddrQueue_ra(2), -- Read-only address[2] input bit
196  DPRA3 => AddrQueue_ra(3), -- Read-only address[3] input bit
197  DPRA4 => AddrQueue_ra(4), -- Read-only address[4] input bit
198  WCLK => sysclk, -- Write clock input
199  WE => addr_we -- Write enable input
200  );
201 end generate;
202 process(memclk)
203 begin
204  if(memclk'event and memclk = '1')then
205  AddrQueue_do(13 downto 12) <= AddrQueue_dop(13 downto 12);
206  end if;
207 end process;
208 AddrQueue_di <= event_addr;
209 process(sysclk, AddrQueue_wa, AddrQueue_rap)
210 variable dist : std_logic_vector(3 downto 0);
211 begin
212 dist := AddrQueue_wa(1 downto 0) & AddrQueue_rap;
213  if(sysclk'event and sysclk = '1')then
214  if(fifo_en = '0' or (din(64) = '1' and din_we = '1'))then
215  en_din <= '0';
216  elsif(addr_we = '1')then
217  en_din <= '1';
218  end if;
219  if(fifo_en = '0')then
220  AddrQueue_wa <= (others => '0');
221  elsif(en_din = '1' and din(64) = '1' and din_we = '1')then
222  AddrQueue_wa(1) <= AddrQueue_wa(0);
223  AddrQueue_wa(0) <= not AddrQueue_wa(1);
224  end if;
225  if(fifo_en = '0')then
226  AddrQueue_rap <= (others => '0');
227  elsif(EoB_toggleSyncRegs(3) /= EoB_toggleSyncRegs(2))then
228  AddrQueue_rap(1) <= AddrQueue_rap(0);
229  AddrQueue_rap(0) <= not AddrQueue_rap(1);
230  end if;
231  EoB_toggleSyncRegs <= EoB_toggleSyncRegs(2 downto 0) & EoB_toggle_i;
232  EoE_toggleSyncRegs <= EoE_toggleSyncRegs(2 downto 0) & EoE_toggle_i;
233  if(resetSys = '1' or EoB_toggleSyncRegs(3) = EoB_toggleSyncRegs(2))then
234  WrtMonBlkDone <= '0';
235  else
236  WrtMonBlkDone <= '1';
237  end if;
238  if(resetSys = '1' or EoE_toggleSyncRegs(3) = EoE_toggleSyncRegs(2))then
239  WrtMonEvtDone <= '0';
240  else
241  WrtMonEvtDone <= '1';
242  end if;
243  if(en_din = '1')then
244  port_rdy <= '0';
245  else
246  case dist is
247  when x"1" | x"7" | x"8" | x"e" => port_rdy <= '0';
248  when others => port_rdy <= '1';
249  end case;
250  end if;
251  FIFO_DI <= din;
252  if(resetSys = '1' or en_din = '0')then
253  FIFO_sel <= (others => '0');
254  elsif(din_we = '1')then
255  FIFO_sel <= FIFO_sel + 1;
256  end if;
257  FIFO_we(0) <= en_din and din_we and not FIFO_sel(1) and not FIFO_sel(0);
258  FIFO_we(1) <= en_din and din_we and not FIFO_sel(1) and (din(64) or FIFO_sel(0));
259  FIFO_we(2) <= en_din and din_we and ((din(64) and not FIFO_sel(1)) or (FIFO_sel(1) and not FIFO_sel(0)));
260  FIFO_we(3) <= en_din and din_we and (din(64) or (FIFO_sel(1) and FIFO_sel(0)));
261  end if;
262 end process;
263 g_FIFO: for i in 0 to 2 generate
264  i_FIFO : FIFO_DUALCLOCK_MACRO
265  generic map (
266  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES"
267  ALMOST_FULL_OFFSET => X"0080", -- Sets almost full threshold
268  ALMOST_EMPTY_OFFSET => X"0080", -- Sets the almost empty threshold
269  DATA_WIDTH => 64, -- Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb")
270  FIFO_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb"
271  FIRST_WORD_FALL_THROUGH => TRUE) -- Sets the FIFO FWFT to TRUE or FALSE
272  port map (
273  ALMOSTEMPTY => open, -- 1-bit output almost empty
274  ALMOSTFULL => open, -- 1-bit output almost full
275  DO => FIFO_DO(i*64+63 downto i*64), -- Output data, width defined by DATA_WIDTH parameter
276  EMPTY => open, -- 1-bit output empty
277  FULL => open, -- 1-bit output full
278  RDCOUNT => RDCOUNT(i), -- Output read count, width determined by FIFO depth
279  RDERR => open, -- 1-bit output read error
280  WRCOUNT => WRCOUNT(i), -- Output write count, width determined by FIFO depth
281  WRERR => open, -- 1-bit output write error
282  DI => FIFO_DI(63 downto 0), -- Input data, width defined by DATA_WIDTH parameter
283  RDCLK => memclk, -- 1-bit input read clock
284  RDEN => app_wren, -- 1-bit input read enable
285  RST => fifo_rst, -- 1-bit input reset
286  WRCLK => sysclk, -- 1-bit input write clock
287  WREN => FIFO_we(i) -- 1-bit input write enable
288  );
289 end generate;
290 i_FIFO3 : FIFO_DUALCLOCK_MACRO
291  generic map (
292  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES"
293  ALMOST_FULL_OFFSET => X"0008", -- Sets almost full threshold
294  ALMOST_EMPTY_OFFSET => X"001f", -- Sets the almost empty threshold
295  DATA_WIDTH => 66, -- Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb")
296  FIFO_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb"
297  FIRST_WORD_FALL_THROUGH => TRUE) -- Sets the FIFO FWFT to TRUE or FALSE
298  port map (
299  ALMOSTEMPTY => FIFO_AlmostEmpty, -- 1-bit output almost empty
300  ALMOSTFULL => buf_full, -- 1-bit output almost full
301  DO => FIFO_DO(257 downto 192), -- Output data, width defined by DATA_WIDTH parameter
302  EMPTY => FIFO_empty, -- 1-bit output empty
303  FULL => open, -- 1-bit output full
304  RDCOUNT => RDCOUNT(3), -- Output read count, width determined by FIFO depth
305  RDERR => open, -- 1-bit output read error
306  WRCOUNT => WRCOUNT(3), -- Output write count, width determined by FIFO depth
307  WRERR => open, -- 1-bit output write error
308  DI => FIFO_DI, -- Input data, width defined by DATA_WIDTH parameter
309  RDCLK => memclk, -- 1-bit input read clock
310  RDEN => app_wren, -- 1-bit input read enable
311  RST => fifo_rst, -- 1-bit input reset
312  WRCLK => sysclk, -- 1-bit input write clock
313  WREN => FIFO_we(3) -- 1-bit input write enable
314  );
315 process(memclk)
316 begin
317  if(memclk'event and memclk = '1')then
318  if(resetMem = '1' or run = '0')then
319  AddrQueue_wa0SyncRegs <= (others => '0');
320  AddrQueue_wa1SyncRegs <= (others => '0');
321  AddrQueue_ra <= (others => '0');
322  EventDone <= '1';
323  EventDone_dl <= '1';
324  last_word <= '0';
325  rqst_i <= '0';
326  dout_wc <= (others => '0');
327  else
328  AddrQueue_wa0SyncRegs <= AddrQueue_wa0SyncRegs(1 downto 0) & AddrQueue_wa(0);
329  AddrQueue_wa1SyncRegs <= AddrQueue_wa1SyncRegs(1 downto 0) & AddrQueue_wa(1);
330  if(EventDone = '1' and EventDone_dl = '0')then
331  AddrQueue_ra(1) <= AddrQueue_ra(0);
332  AddrQueue_ra(0) <= not AddrQueue_ra(1);
333  end if;
334  if(EventDone = '1' and FIFO_empty = '0')then
335  EventDone <= '0';
336  elsif(FIFO_DO(256) = '1' and app_wren = '1')then
337  EventDone <= '1';
338  end if;
339  EventDone_dl <= EventDone;
340  if(app_wren = '1')then
341  if(dout_wc = "11110")then
342  last_word <= '1';
343  else
344  last_word <= '0';
345  end if;
346  end if;
347  if(fifo_en = '0' or EventDone = '1' or FIFO_empty = '1' or ((FIFO_DO(256) = '1' or last_word = '1') and app_wren = '1'))then
348  rqst_i <= '0';
349  elsif((AddrQueue_ra(1) /= AddrQueue_wa1SyncRegs(2) or AddrQueue_ra(0) /= AddrQueue_wa0SyncRegs(2)) or FIFO_AlmostEmpty = '0')then
350  rqst_i <= '1';
351  end if;
352  if(EventDone = '1')then
353  dout_wc <= (others => '0');
354  elsif(app_wren = '1')then
355  dout_wc <= dout_wc + 1;
356  end if;
357  end if;
358 -- if(resetMem = '0' and run = '1' and FIFO_DO(256) = '0' and last_word = '1' and app_wren = '1')then
359  if(resetMem = '0' and run = '1' and last_word = '1' and app_wren = '1')then
360  KiloByte_toggle_i <= not KiloByte_toggle_i;
361  end if;
362  if(resetMem = '0' and run = '1' and FIFO_DO(256) = '1' and app_wren = '1')then
363  EoB_toggle_i <= not EoB_toggle_i;
364  end if;
365  if(resetMem = '0' and run = '1' and FIFO_DO(257) = '1' and app_wren = '1')then
366  EoE_toggle_i <= not EoE_toggle_i;
367  end if;
368  end if;
369 end process;
370 process(memclk)
371 begin
372  if(memclk'event and memclk = '1')then
373  if(EventDone_dl = '1')then
374  app_addr_i(9 downto 0) <= (others => '0');
375  app_addr_i(13 downto 10) <= AddrQueue_do(3 downto 0);
376  elsif(app_wren = '1')then
377  app_addr_i(13 downto 0) <= app_addr_i(13 downto 0) + 1;
378  end if;
379  end if;
380 end process;
381 dout <= FIFO_DO(255 downto 0);
382 end Behavioral;
383