@@ -0,0 +1,384 | |||
|
1 | ||
|
2 | ------------------------------------------------------------------------------ | |
|
3 | -- This file is a part of the LPP VHDL IP LIBRARY | |
|
4 | -- Copyright (C) 2009 - 2010, Laboratory of Plasmas Physic - CNRS | |
|
5 | -- | |
|
6 | -- This program is free software; you can redistribute it and/or modify | |
|
7 | -- it under the terms of the GNU General Public License as published by | |
|
8 | -- the Free Software Foundation; either version 3 of the License, or | |
|
9 | -- (at your option) any later version. | |
|
10 | -- | |
|
11 | -- This program is distributed in the hope that it will be useful, | |
|
12 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
13 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
14 | -- GNU General Public License for more details. | |
|
15 | -- | |
|
16 | -- You should have received a copy of the GNU General Public License | |
|
17 | -- along with this program; if not, write to the Free Software | |
|
18 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
|
19 | ------------------------------------------------------------------------------- | |
|
20 | -- Author : Jean-christophe Pellion | |
|
21 | -- Mail : jean-christophe.pellion@lpp.polytechnique.fr | |
|
22 | -- jean-christophe.pellion@easii-ic.com | |
|
23 | ------------------------------------------------------------------------------- | |
|
24 | -- 1.0 - initial version | |
|
25 | -- 1.1 - (01/11/2013) FIX boundary error (1kB address should not be crossed by BURSTS) | |
|
26 | ------------------------------------------------------------------------------- | |
|
27 | LIBRARY ieee; | |
|
28 | USE ieee.std_logic_1164.ALL; | |
|
29 | USE ieee.numeric_std.ALL; | |
|
30 | LIBRARY grlib; | |
|
31 | USE grlib.amba.ALL; | |
|
32 | USE grlib.stdlib.ALL; | |
|
33 | USE grlib.devices.ALL; | |
|
34 | USE GRLIB.DMA2AHB_Package.ALL; | |
|
35 | LIBRARY lpp; | |
|
36 | USE lpp.lpp_amba.ALL; | |
|
37 | USE lpp.apb_devices_list.ALL; | |
|
38 | USE lpp.lpp_memory.ALL; | |
|
39 | USE lpp.lpp_dma_pkg.ALL; | |
|
40 | USE lpp.lpp_waveform_pkg.ALL; | |
|
41 | LIBRARY techmap; | |
|
42 | USE techmap.gencomp.ALL; | |
|
43 | ||
|
44 | ||
|
45 | ENTITY lpp_waveform_dma IS | |
|
46 | GENERIC ( | |
|
47 | data_size : INTEGER := 160; | |
|
48 | tech : INTEGER := inferred; | |
|
49 | hindex : INTEGER := 2; | |
|
50 | nb_burst_available_size : INTEGER := 11 | |
|
51 | ); | |
|
52 | PORT ( | |
|
53 | -- AMBA AHB system signals | |
|
54 | HCLK : IN STD_ULOGIC; | |
|
55 | HRESETn : IN STD_ULOGIC; | |
|
56 | -- AMBA AHB Master Interface | |
|
57 | AHB_Master_In : IN AHB_Mst_In_Type; | |
|
58 | AHB_Master_Out : OUT AHB_Mst_Out_Type; | |
|
59 | -- | |
|
60 | data_ready : IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- todo | |
|
61 | data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); -- todo | |
|
62 | data_data_ren : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- todo | |
|
63 | data_time_ren : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- todo | |
|
64 | -- Reg | |
|
65 | nb_burst_available : IN STD_LOGIC_VECTOR(nb_burst_available_size-1 DOWNTO 0); | |
|
66 | status_full : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); | |
|
67 | status_full_ack : IN STD_LOGIC_VECTOR(3 DOWNTO 0); | |
|
68 | status_full_err : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); | |
|
69 | -- status_new_err : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- New data f(i) before the current data is write by dma | |
|
70 | addr_data_f0 : IN STD_LOGIC_VECTOR(31 DOWNTO 0); | |
|
71 | addr_data_f1 : IN STD_LOGIC_VECTOR(31 DOWNTO 0); | |
|
72 | addr_data_f2 : IN STD_LOGIC_VECTOR(31 DOWNTO 0); | |
|
73 | addr_data_f3 : IN STD_LOGIC_VECTOR(31 DOWNTO 0) | |
|
74 | ); | |
|
75 | END; | |
|
76 | ||
|
77 | ARCHITECTURE Behavioral OF lpp_waveform_dma IS | |
|
78 | ----------------------------------------------------------------------------- | |
|
79 | SIGNAL DMAIn : DMA_In_Type; | |
|
80 | SIGNAL DMAOut : DMA_OUt_Type; | |
|
81 | ----------------------------------------------------------------------------- | |
|
82 | TYPE state_DMAWriteBurst IS (IDLE, | |
|
83 | SEND_TIME_0, WAIT_TIME_0, | |
|
84 | SEND_TIME_1, WAIT_TIME_1, | |
|
85 | SEND_5_TIME, | |
|
86 | SEND_DATA, WAIT_DATA); | |
|
87 | SIGNAL state : state_DMAWriteBurst ; | |
|
88 | ----------------------------------------------------------------------------- | |
|
89 | -- CONTROL | |
|
90 | SIGNAL sel_data_s : STD_LOGIC_VECTOR(1 DOWNTO 0); | |
|
91 | SIGNAL sel_data : STD_LOGIC_VECTOR(1 DOWNTO 0); | |
|
92 | SIGNAL update : STD_LOGIC_VECTOR(1 DOWNTO 0); | |
|
93 | SIGNAL time_select : STD_LOGIC; | |
|
94 | SIGNAL time_write : STD_LOGIC; | |
|
95 | SIGNAL time_already_send : STD_LOGIC_VECTOR(3 DOWNTO 0); | |
|
96 | SIGNAL time_already_send_s : STD_LOGIC; | |
|
97 | ----------------------------------------------------------------------------- | |
|
98 | -- SEND TIME MODULE | |
|
99 | SIGNAL time_dmai : DMA_In_Type; | |
|
100 | SIGNAL time_send : STD_LOGIC; | |
|
101 | SIGNAL time_send_ok : STD_LOGIC; | |
|
102 | SIGNAL time_send_ko : STD_LOGIC; | |
|
103 | SIGNAL time_fifo_ren : STD_LOGIC; | |
|
104 | SIGNAL time_ren : STD_LOGIC; | |
|
105 | ----------------------------------------------------------------------------- | |
|
106 | -- SEND DATA MODULE | |
|
107 | SIGNAL data_dmai : DMA_In_Type; | |
|
108 | SIGNAL data_send : STD_LOGIC; | |
|
109 | SIGNAL data_send_ok : STD_LOGIC; | |
|
110 | SIGNAL data_send_ko : STD_LOGIC; | |
|
111 | SIGNAL data_fifo_ren : STD_LOGIC; | |
|
112 | SIGNAL data_ren : STD_LOGIC; | |
|
113 | ----------------------------------------------------------------------------- | |
|
114 | -- SELECT ADDRESS | |
|
115 | SIGNAL data_address : STD_LOGIC_VECTOR(31 DOWNTO 0); | |
|
116 | SIGNAL update_and_sel : STD_LOGIC_VECTOR(7 DOWNTO 0); | |
|
117 | SIGNAL addr_data_reg_vector : STD_LOGIC_VECTOR(32*4-1 DOWNTO 0); | |
|
118 | SIGNAL addr_data_vector : STD_LOGIC_VECTOR(32*4-1 DOWNTO 0); | |
|
119 | ----------------------------------------------------------------------------- | |
|
120 | SIGNAL send_16_3_time_reg : STD_LOGIC_VECTOR(3*4-1 DOWNTO 0); | |
|
121 | SIGNAL send_16_3_time_reg_s : STD_LOGIC_VECTOR(3*4-1 DOWNTO 0); | |
|
122 | ----------------------------------------------------------------------------- | |
|
123 | SIGNAL send_16_3_time : STD_LOGIC; | |
|
124 | SIGNAL count_send_time : INTEGER; | |
|
125 | BEGIN | |
|
126 | ||
|
127 | ----------------------------------------------------------------------------- | |
|
128 | -- DMA to AHB interface | |
|
129 | DMA2AHB_1 : DMA2AHB | |
|
130 | GENERIC MAP ( | |
|
131 | hindex => hindex, | |
|
132 | vendorid => VENDOR_LPP, | |
|
133 | deviceid => 10, | |
|
134 | version => 0, | |
|
135 | syncrst => 1, | |
|
136 | boundary => 1) -- FIX 11/01/2013 | |
|
137 | PORT MAP ( | |
|
138 | HCLK => HCLK, | |
|
139 | HRESETn => HRESETn, | |
|
140 | DMAIn => DMAIn, | |
|
141 | DMAOut => DMAOut, | |
|
142 | AHBIn => AHB_Master_In, | |
|
143 | AHBOut => AHB_Master_Out); | |
|
144 | ----------------------------------------------------------------------------- | |
|
145 | ||
|
146 | ----------------------------------------------------------------------------- | |
|
147 | -- This module memorises when the Times info are write. When FSM send | |
|
148 | -- the Times info, the "reg" is set and when a full_ack is received the "reg" is reset. | |
|
149 | all_time_write : FOR I IN 3 DOWNTO 0 GENERATE | |
|
150 | PROCESS (HCLK, HRESETn) | |
|
151 | BEGIN -- PROCESS | |
|
152 | IF HRESETn = '0' THEN -- asynchronous reset (active low) | |
|
153 | time_already_send(I) <= '0'; | |
|
154 | ELSIF HCLK'EVENT AND HCLK = '1' THEN -- rising clock edge | |
|
155 | IF time_write = '1' AND UNSIGNED(sel_data) = I THEN | |
|
156 | time_already_send(I) <= '1'; | |
|
157 | ELSIF status_full_ack(I) = '1' THEN | |
|
158 | time_already_send(I) <= '0'; | |
|
159 | END IF; | |
|
160 | END IF; | |
|
161 | END PROCESS; | |
|
162 | END GENERATE all_time_write; | |
|
163 | ||
|
164 | ||
|
165 | ||
|
166 | ----------------------------------------------------------------------------- | |
|
167 | sel_data_s <= "00" WHEN data_ready(0) = '1' ELSE | |
|
168 | "01" WHEN data_ready(1) = '1' ELSE | |
|
169 | "10" WHEN data_ready(2) = '1' ELSE | |
|
170 | "11"; | |
|
171 | ||
|
172 | time_already_send_s <= time_already_send(0) WHEN data_ready(0) = '1' ELSE | |
|
173 | time_already_send(1) WHEN data_ready(1) = '1' ELSE | |
|
174 | time_already_send(2) WHEN data_ready(2) = '1' ELSE | |
|
175 | time_already_send(3); | |
|
176 | ||
|
177 | ||
|
178 | send_16_3_time <= send_16_3_time_reg(0) WHEN data_ready(0) = '1' ELSE | |
|
179 | send_16_3_time_reg(3) WHEN data_ready(1) = '1' ELSE | |
|
180 | send_16_3_time_reg(6) WHEN data_ready(2) = '1' ELSE | |
|
181 | send_16_3_time_reg(9) ; | |
|
182 | ||
|
183 | all_send_16_3: FOR I IN 3 DOWNTO 0 GENERATE | |
|
184 | send_16_3_time_reg_s(3*(I+1)-1 DOWNTO 3*I) <= | |
|
185 | send_16_3_time_reg(3*(I+1)-1 DOWNTO 3*I) WHEN data_ready(I) = '0' ELSE | |
|
186 | send_16_3_time_reg(3*(I+1)-2 DOWNTO 3*I) & send_16_3_time_reg(3*(I+1)-1); | |
|
187 | END GENERATE all_send_16_3; | |
|
188 | ||
|
189 | -- DMA control | |
|
190 | DMAWriteFSM_p : PROCESS (HCLK, HRESETn) | |
|
191 | BEGIN -- PROCESS DMAWriteBurst_p | |
|
192 | IF HRESETn = '0' THEN | |
|
193 | state <= IDLE; | |
|
194 | ||
|
195 | sel_data <= "00"; | |
|
196 | update <= "00"; | |
|
197 | time_select <= '0'; | |
|
198 | time_fifo_ren <= '1'; | |
|
199 | data_send <= '0'; | |
|
200 | time_send <= '0'; | |
|
201 | time_write <= '0'; | |
|
202 | --send_16_3_time <= "001"; | |
|
203 | send_16_3_time_reg(3*1-1 DOWNTO 3*0) <= "001"; | |
|
204 | send_16_3_time_reg(3*2-1 DOWNTO 3*1) <= "001"; | |
|
205 | send_16_3_time_reg(3*3-1 DOWNTO 3*2) <= "001"; | |
|
206 | send_16_3_time_reg(3*4-1 DOWNTO 3*3) <= "001"; | |
|
207 | ||
|
208 | ELSIF HCLK'EVENT AND HCLK = '1' THEN | |
|
209 | ||
|
210 | CASE state IS | |
|
211 | WHEN IDLE => | |
|
212 | count_send_time <= 0; | |
|
213 | sel_data <= "00"; | |
|
214 | update <= "00"; | |
|
215 | time_select <= '0'; | |
|
216 | time_fifo_ren <= '1'; | |
|
217 | data_send <= '0'; | |
|
218 | time_send <= '0'; | |
|
219 | time_write <= '0'; | |
|
220 | ||
|
221 | IF data_ready = "0000" THEN | |
|
222 | state <= IDLE; | |
|
223 | ELSE | |
|
224 | sel_data <= sel_data_s; | |
|
225 | send_16_3_time_reg <= send_16_3_time_reg_s; | |
|
226 | IF send_16_3_time = '1' THEN | |
|
227 | state <= SEND_TIME_0; | |
|
228 | ELSE | |
|
229 | state <= SEND_5_TIME; | |
|
230 | END IF; | |
|
231 | END IF; | |
|
232 | ||
|
233 | WHEN SEND_TIME_0 => | |
|
234 | time_select <= '1'; | |
|
235 | IF time_already_send_s = '0' THEN | |
|
236 | time_send <= '1'; | |
|
237 | state <= WAIT_TIME_0; | |
|
238 | ELSE | |
|
239 | time_send <= '0'; | |
|
240 | state <= SEND_TIME_1; | |
|
241 | END IF; | |
|
242 | time_fifo_ren <= '0'; | |
|
243 | ||
|
244 | WHEN WAIT_TIME_0 => | |
|
245 | time_fifo_ren <= '1'; | |
|
246 | update <= "00"; | |
|
247 | time_send <= '0'; | |
|
248 | IF time_send_ok = '1' OR time_send_ko = '1' THEN | |
|
249 | update <= "01"; | |
|
250 | state <= SEND_TIME_1; | |
|
251 | END IF; | |
|
252 | ||
|
253 | WHEN SEND_TIME_1 => | |
|
254 | time_select <= '1'; | |
|
255 | IF time_already_send_s = '0' THEN | |
|
256 | time_send <= '1'; | |
|
257 | state <= WAIT_TIME_1; | |
|
258 | ELSE | |
|
259 | time_send <= '0'; | |
|
260 | state <= SEND_5_TIME; | |
|
261 | END IF; | |
|
262 | time_fifo_ren <= '0'; | |
|
263 | ||
|
264 | WHEN WAIT_TIME_1 => | |
|
265 | time_fifo_ren <= '1'; | |
|
266 | update <= "00"; | |
|
267 | time_send <= '0'; | |
|
268 | IF time_send_ok = '1' OR time_send_ko = '1' THEN | |
|
269 | time_write <= '1'; | |
|
270 | update <= "01"; | |
|
271 | state <= SEND_5_TIME; | |
|
272 | END IF; | |
|
273 | ||
|
274 | WHEN SEND_5_TIME => | |
|
275 | update <= "00"; | |
|
276 | time_select <= '1'; | |
|
277 | time_fifo_ren <= '0'; | |
|
278 | count_send_time <= count_send_time + 1; | |
|
279 | IF count_send_time = 10 THEN | |
|
280 | state <= SEND_DATA; | |
|
281 | END IF; | |
|
282 | ||
|
283 | WHEN SEND_DATA => | |
|
284 | time_fifo_ren <= '1'; | |
|
285 | time_write <= '0'; | |
|
286 | time_send <= '0'; | |
|
287 | ||
|
288 | time_select <= '0'; | |
|
289 | data_send <= '1'; | |
|
290 | update <= "00"; | |
|
291 | state <= WAIT_DATA; | |
|
292 | ||
|
293 | WHEN WAIT_DATA => | |
|
294 | data_send <= '0'; | |
|
295 | ||
|
296 | IF data_send_ok = '1' OR data_send_ko = '1' THEN | |
|
297 | state <= IDLE; | |
|
298 | update <= "10"; | |
|
299 | END IF; | |
|
300 | ||
|
301 | WHEN OTHERS => NULL; | |
|
302 | END CASE; | |
|
303 | ||
|
304 | END IF; | |
|
305 | END PROCESS DMAWriteFSM_p; | |
|
306 | ----------------------------------------------------------------------------- | |
|
307 | ||
|
308 | ||
|
309 | ||
|
310 | ----------------------------------------------------------------------------- | |
|
311 | -- SEND 1 word by DMA | |
|
312 | ----------------------------------------------------------------------------- | |
|
313 | lpp_dma_send_1word_1 : lpp_dma_send_1word | |
|
314 | PORT MAP ( | |
|
315 | HCLK => HCLK, | |
|
316 | HRESETn => HRESETn, | |
|
317 | DMAIn => time_dmai, | |
|
318 | DMAOut => DMAOut, | |
|
319 | ||
|
320 | send => time_send, | |
|
321 | address => data_address, | |
|
322 | data => data, | |
|
323 | send_ok => time_send_ok, | |
|
324 | send_ko => time_send_ko | |
|
325 | ); | |
|
326 | ||
|
327 | ----------------------------------------------------------------------------- | |
|
328 | -- SEND 16 word by DMA (in burst mode) | |
|
329 | ----------------------------------------------------------------------------- | |
|
330 | lpp_dma_send_16word_1 : lpp_dma_send_16word | |
|
331 | PORT MAP ( | |
|
332 | HCLK => HCLK, | |
|
333 | HRESETn => HRESETn, | |
|
334 | DMAIn => data_dmai, | |
|
335 | DMAOut => DMAOut, | |
|
336 | ||
|
337 | send => data_send, | |
|
338 | address => data_address, | |
|
339 | data => data, | |
|
340 | ren => data_fifo_ren, | |
|
341 | send_ok => data_send_ok, | |
|
342 | send_ko => data_send_ko); | |
|
343 | ||
|
344 | DMAIn <= time_dmai WHEN time_select = '1' ELSE data_dmai; | |
|
345 | data_ren <= '1' WHEN time_select = '1' ELSE data_fifo_ren; | |
|
346 | time_ren <= time_fifo_ren WHEN time_select = '1' ELSE '1'; | |
|
347 | ||
|
348 | all_data_ren : FOR I IN 3 DOWNTO 0 GENERATE | |
|
349 | data_data_ren(I) <= data_ren WHEN UNSIGNED(sel_data) = I ELSE '1'; | |
|
350 | data_time_ren(I) <= time_ren WHEN UNSIGNED(sel_data) = I ELSE '1'; | |
|
351 | END GENERATE all_data_ren; | |
|
352 | ||
|
353 | ----------------------------------------------------------------------------- | |
|
354 | -- SELECT ADDRESS | |
|
355 | addr_data_reg_vector <= addr_data_f3 & addr_data_f2 & addr_data_f1 & addr_data_f0; | |
|
356 | ||
|
357 | gen_select_address : FOR I IN 3 DOWNTO 0 GENERATE | |
|
358 | ||
|
359 | update_and_sel((2*I)+1 DOWNTO 2*I) <= update WHEN UNSIGNED(sel_data) = I ELSE "00"; | |
|
360 | ||
|
361 | lpp_waveform_dma_selectaddress_I : lpp_waveform_dma_selectaddress | |
|
362 | GENERIC MAP ( | |
|
363 | nb_burst_available_size => nb_burst_available_size) | |
|
364 | PORT MAP ( | |
|
365 | HCLK => HCLK, | |
|
366 | HRESETn => HRESETn, | |
|
367 | update => update_and_sel((2*I)+1 DOWNTO 2*I), | |
|
368 | nb_burst_available => nb_burst_available, | |
|
369 | addr_data_reg => addr_data_reg_vector(32*I+31 DOWNTO 32*I), | |
|
370 | addr_data => addr_data_vector(32*I+31 DOWNTO 32*I), | |
|
371 | status_full => status_full(I), | |
|
372 | status_full_ack => status_full_ack(I), | |
|
373 | status_full_err => status_full_err(I)); | |
|
374 | ||
|
375 | END GENERATE gen_select_address; | |
|
376 | ||
|
377 | data_address <= addr_data_vector(31 DOWNTO 0) WHEN UNSIGNED(sel_data) = 0 ELSE | |
|
378 | addr_data_vector(32*1+31 DOWNTO 32*1) WHEN UNSIGNED(sel_data) = 1 ELSE | |
|
379 | addr_data_vector(32*2+31 DOWNTO 32*2) WHEN UNSIGNED(sel_data) = 2 ELSE | |
|
380 | addr_data_vector(32*3+31 DOWNTO 32*3); | |
|
381 | ----------------------------------------------------------------------------- | |
|
382 | ||
|
383 | ||
|
384 | END Behavioral; No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now