1 ------------------------------------------------------
6 -- Dominique Gigi Feb 2012
7 ------------------------------------------------------
8 -- This is the TOP level of the core for the sender part
9 -- 17/09/2014 add some status counter
10 -- 17/09/2014 add a logic to trash data between Trailer and next Header
11 -- 21/01/2015 A detection of FED system clock
12 ------------------------------------------------------
17 USE ieee.std_logic_1164.
all;
18 use ieee.numeric_std.
all;
19 use ieee.std_logic_unsigned.
all;
23 generic (generator : := false);
29 -- link data write enable ACTIVE LOW
31 -- link data header/trailer marker when '0'
34 LinkData : in (63 downto 0);
35 -- link data buffer almost full ACTIVE LOW
36 LinkAlmostFull : out ;
37 -- link down ACTIVE LOW
40 src_ID : in (15 downto 0);
41 -- enables error injection to test error recovery
42 inject_err : in (17 downto 0);
43 -- Link status data read out
45 addr : in (15 downto 0);
46 status_data : out (63 downto 0);
48 -- Interface for internal logic
51 clock : in ;
-- clock from internal logic
52 block_free : in ;
-- almost one block is free
54 data_fed : out (63 downto 0);
55 block_sz_fed : out (15 downto 0);
57 start_evt : out ;
-- this block is the first for the current event
58 stop_evt : out ;
-- this block is the last for the current event -- both can be set
59 end_blk_fed : out ;
-- indicate end of the packet (max 4KBytes)
60 -- interface slave to read and write
62 func : in (31 downto 0);
63 data_wr : in (31 downto 0);
64 data_rd : out (63 downto 0);
65 cnt_evt : out ;
-- pulse for each event (on sys_clk);
66 cnt_pckt_rcv : in (31 downto 0);
67 cnt_pckt_snd : in (31 downto 0);
70 status_state_build_p : in (31 downto 0);
71 status_state_core : in (31 downto 0);
72 Serdes_status : in (31 downto 0)
77 architecture behavioral
of fed_itf is
79 type fill_blk_type is ( idle,
84 dummy_c -- dummy state implement du to the CRC check , which take 2 clock cylces more
86 signal fill_blk,fill_blkNext:fill_blk_type;
91 aclr :
in ;
-- active low
94 dataw :
in (
65 downto 0);
95 almost_f :
out ;
-- active low
97 datar :
out (
65 downto 0);
99 empty :
out -- active low
106 low_clk :
IN ;
-- frequency of 50 Mhz
108 PCIe_func :
IN (
15 downto 0);
110 PCIe_dti :
IN (
31 downto 0);
111 PCIe_dto :
out (
31 downto 0);
115 data :
OUT (
63 downto 0);
117 Back_p :
IN -- Back_p when '0'
123 D :
in (
63 downto 0);
124 CRC_out :
out (
15 downto 0);
133 sysclk :
in ;
-- clock used by the FED to send data and to measure the backpressure
134 base_clk :
in ;
-- clock base used to measure the sysclk
135 frequency :
out (
31 downto 0)
-- measure of the frequency)
140 signal datar_rreg : (63 downto 0);
141 signal data_out : (63 downto 0);
142 signal datar : (65 downto 0);
143 signal datar_reg : (63 downto 0);
144 signal start_evt_mem : ;
145 signal stop_evt_mem : ;
147 signal finish_blk : ;
151 signal del_rd_ff : (1 downto 0);
152 signal blk_size : (15 downto 0);
154 signal blk_full_anti : ;
156 signal End_pckt_lgc : ;
158 signal sel_test_mode : ;
160 signal data_tm : (63 downto 0);
162 signal backpressure_mux : ;
164 signal data_mux : (63 downto 0);
166 signal PCIe_dto : (31 downto 0);
167 signal local_reg : (31 downto 0);
168 signal LINKDOWN_cell : ;
170 -- use to pipe frgament during the CRC check
171 signal data_r_crc : (63 downto 0);
177 signal ena_CRC_reg : ;
178 signal CRC_frag : (15 downto 0);
179 signal CRC_cmp : (15 downto 0);
180 signal data_rb_mux : (63 downto 0);
181 signal backpressure : ;
184 signal block_counter : (31 downto 0);
185 signal event_counter : (31 downto 0);
186 signal data_counter : (63 downto 0);
187 signal Retransmit_counter : (31 downto 0);
188 signal cnt_back_p : (31 downto 0);
189 signal FED_CRC_error_cnt : (31 downto 0);
190 signal state_machine_status: (2 downto 0);
193 signal blk_size_reg : (15 downto 0);
194 signal start_evt_mem_reg : ;
195 signal stop_evt_mem_reg : ;
196 signal End_pckt_lgc_reg : ;
198 signal freq_measure_reg : (31 downto 0);
199 signal rsyc_test_mode : (1 downto 0);
200 signal rsyc_DAQON : (1 downto 0);
202 --***********************************************************
203 --********************** BEGIN ****************************
204 --***********************************************************
208 -- Set the TEST mode and DAQ_ON with function (6)
209 -- this function will come from optical link send by DAQ side
210 process(Greset_CLK,clock)
212 if Greset_CLK = '0' then
213 sel_test_mode <= '0';
214 LINKDOWN_cell <= '0';
215 elsif rising_edge(clock) then
216 if func(6) = '1' and wr_cmd = '1' then
217 sel_test_mode <= data_wr(31);
218 LINKDOWN_cell <= data_wr(30);
225 if rising_edge(sys_clk) then
226 rsyc_test_mode(1) <= rsyc_test_mode(0);
227 rsyc_test_mode(0) <= sel_test_mode;
232 local_reg(
31) <= sel_test_mode;
233 local_reg(
30) <= LINKDOWN_cell;
234 local_reg(
29) <= Backpressure;
235 local_reg(
28) <= '1'
when block_free = '1'
else '0';
236 local_reg(
27 downto 3) <= (
others => '0');
237 local_reg(
2 downto 0) <= state_machine_status(
2 downto 0);
239 process(Greset_sysCLK,sys_clk)
241 if rising_edge(sys_clk) then
242 rsyc_DAQON(1) <= rsyc_DAQON(0);
243 rsyc_DAQON(0) <= LINKDOWN_cell;
247 LinkDown <= rsyc_DAQON(1);
249 -- measure the frequency used by the fed to send data
252 reset => Greset_sysCLK,
253 sysclk => sys_clk,
-- clock used by the FED to send data and to measure the backpressure
255 frequency => freq_measure_reg
-- measure of the frequency)
258 process(Greset_sysCLK,sys_clk)
260 if Greset_sysCLK = '0' then
261 cnt_back_p <= (others => '0');
262 elsif rising_edge(sys_clk) then
263 if backpressure_mux = '0' then
264 cnt_back_p <= cnt_back_p + '1';
269 --multiplex data local and Event_gen status/data for read command coming from optical link send by DAQ side
273 if rising_edge(clock) then
274 data_rd(63 downto 32) <= (others => '0');
275 if func(6) = '1' then
276 data_rd(31 downto 0) <= local_reg;
277 elsif func(7) = '1' then
278 data_rd <= data_counter;
279 elsif func(8) = '1' then
280 data_rd(31 downto 0) <= event_counter;
281 elsif func(9) = '1' then
282 data_rd(31 downto 0) <= block_counter;
283 elsif func(10) = '1' then
284 data_rd(31 downto 0) <= cnt_pckt_rcv;
285 elsif func(11) = '1' then
286 data_rd(31 downto 0) <= status_state_core;
287 elsif func(12) = '1' then
288 data_rd(31 downto 0) <= cnt_pckt_snd;
289 elsif func(13) = '1' then
290 data_rd(31 downto 0) <= status_state_build_p;
291 elsif func(14) = '1' then
292 data_rd(31 downto 0) <= cnt_back_p;
293 elsif func(15) = '1' then
294 data_rd(31 downto 0) <= version;
295 elsif func(16) = '1' then
296 data_rd(31 downto 0) <= Serdes_status;
297 elsif func(17) = '1' then
298 data_rd(31 downto 0) <= Retransmit_counter;
299 elsif func(18) = '1' then
300 data_rd(31 downto 0) <= freq_measure_reg;
302 data_rd(31 downto 0) <= PCIe_dto;
307 -- status going back to FED side
310 if rising_edge(sys_clk) then
311 status_data(63 downto 00) <= (others => '0');
312 if addr = x"0001" then
313 status_data(31 downto 0) <= local_reg;
314 elsif addr = x"0002" then
315 status_data <= data_counter;
316 elsif addr = x"0003" then
317 status_data(31 downto 0) <= event_counter;
318 elsif addr = x"0004" then
319 status_data(31 downto 0) <= block_counter;
320 elsif addr = x"0005" then
321 status_data(31 downto 0) <= cnt_pckt_rcv;
322 elsif addr = x"0006" then
323 status_data(31 downto 0) <= status_state_core;
324 elsif addr = x"0007" then
325 status_data(31 downto 0) <= cnt_pckt_snd;
326 elsif addr = x"0008" then
327 status_data(31 downto 0) <= status_state_build_p;
328 elsif addr = x"0009" then
329 status_data(31 downto 0) <= cnt_back_p;
330 elsif addr = x"000A" then
331 status_data(31 downto 0) <= version;
332 elsif addr = x"000B" then
333 status_data(31 downto 0) <= Serdes_status;
334 elsif addr = x"000C" then
335 status_data(31 downto 0) <= Retransmit_counter;
336 elsif addr = x"000D" then
337 status_data(31 downto 0) <= FED_CRC_error_cnt;
338 elsif addr = x"000E" then
339 status_data(31 downto 0) <= freq_measure_reg;
344 -- retransmit counter
345 process(Greset_CLK,clock)
347 if Greset_CLK = '0' then
348 Retransmit_counter <= (others => '0');
349 elsif rising_edge(clock) then
350 if retransmit_ena = '1' then
351 Retransmit_counter <= Retransmit_counter + '1';
356 -- local Event generator used to test the link
357 generator_inst:if generator generate
361 low_clk => clock,
-- frequency of ??? Mhz
363 PCIe_func => func
(15 downto 0),
366 PCIe_dto => PCIe_dto,
367 PCIe_cs => sel_test_mode,
372 Back_p => backpressure_mux
377 --******************************************************************************
378 -- multiplexer for event DATA
379 -- mux external (FED) and local data path (Event generator) ********************
381 wen_mux <= wen_tm when rsyc_test_mode(1) = '1' and generator else not(LinkWe);
382 data_mux <= data_tm when rsyc_test_mode(1) = '1' and generator else LinkData;
383 uctrl_mux <= uctrl_tm when rsyc_test_mode(1) = '1' and generator else LinkCtrl;
385 --******************************************************************************
386 process(Greset_sysCLK,sys_clk)
388 if Greset_sysCLK = '0' then
389 data_counter <= (others => '0');
390 elsif rising_edge(sys_clk) then
391 if wen_mux = '1' then
392 data_counter <= data_counter + '1';
397 --indicate the last word of the EVENT
398 end_frag <= '1' when data_mux(63 downto 60) = x"A" and uctrl_mux = '0' else '0';
400 -- pulse to count the number of event dicover
401 process(Greset_sysCLK,sys_clk)
403 if Greset_sysCLK = '0' then
405 elsif rising_edge(sys_clk) then
407 if end_frag = '1' then
413 -- internal FIFO used to chnage the DATA clock domaine
417 aclr => Greset_sysCLK,
420 dataw
(63 downto 0) => data_mux,
421 dataw
(64) => uctrl_mux ,
422 dataw
(65) => end_frag ,
423 almost_f => backpressure_mux ,
431 -- LinkAlmostFull LFF is valid only in no TEST mode otherwise ALLTIME active (low)
432 Backpressure <= '0' when rsyc_test_mode(1) = '1' else backpressure_mux;
433 LinkAlmostFull <= Backpressure;
435 --******************************************************************************
436 -- -******* This state machine is used to read the FIFO and fill the blocks in the CORE_LOGIC.VHD file
437 --state machine clock
438 FED_itf_state_clk:
process(Greset_CLK,clock)
440 if Greset_CLK = '0' then
442 elsif rising_edge(clock) then
443 fill_blk <= fill_blkNext;
447 FED_itf_state_machine:
process(fill_blk,empt_ff,block_free,blk_full,last_word)
449 fill_blkNext <= fill_blk;
450 state_machine_status <= (others => '0');
452 -- wait data and free block in CORE_LOGIC.VHD
455 state_machine_status(0) <='1';
456 if empt_ff = '0' and block_free = '1' then
457 fill_blkNext <= read_fifo;
460 -- continue until the last word of the EVENT or until no free BLOCK
462 state_machine_status(1) <='1';
463 if blk_full = '1' or last_word = '1' then --stop_evt_mem = '1' then
464 fill_blkNext <= update_para;
467 -- unpdate flags and indicate end of block (block full or end_of_event)
469 state_machine_status(2) <='1';
470 fill_blkNext <= dummy_a;
473 fill_blkNext <= dummy_b;
476 fill_blkNext <= dummy_c;
-- take 3 clock
to finish
to clsoe the
buffer,
if no the block_free value can be wrong
479 fill_blkNext <= idle;
482 fill_blkNext <= idle;
485 --******************************************************************************
487 last_word <= '1' when rd_ff_reg = '1' and datar(65) = '1' else '0';
489 G_rst_rd <= '0' when Greset_CLK = '0' or empt_ff = '1' or blk_full = '1' else '1';
491 -- automatic read FIFO until the the last word of the EVENT or end of block (change state FILL_BLK)
492 process(G_rst_rd,clock)
494 if G_rst_rd = '0' then
496 elsif rising_edge(clock) then
498 if fill_blk = read_fifo and last_word = '0' then
504 --******************************************************************************
506 process(Greset_CLK,clock)
508 if Greset_CLK = '0' then
511 event_counter <= (others => '0');
512 elsif rising_edge(clock) then
514 if datar(64) = '0' and datar(63 downto 60) = x"A" and rd_ff_reg = '1' then -- UCTRL= 0 + trailer + DATA_valid
515 -- remove the CRC in the trailer to compute the CRC
516 data_r_crc(63 downto 32) <= datar(63 downto 32);
517 data_r_crc(31 downto 16) <= (others => '0');
518 data_r_crc(15 downto 0) <= datar(15 downto 0);
520 data_r_crc <= datar(63 downto 00);
523 datar_reg <= datar(63 downto 00);
525 -- create the envelop of the event + counter status
526 if datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
527 event_counter <= event_counter + '1';
530 -- specify the place of the Trailer
531 ena_CRC_reg <= ena_CRC;
534 if datar(64) = '0' and datar(63 downto 60) = x"A" and rd_ff_reg = '1' then
536 crc_frag <= datar(31 downto 16);
539 -- reset the CRC machine between 2 fragments
540 if ena_crc = '1' then
542 elsif datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
559 -- compare the CRC received and the CRC computed
560 crc_check <= '0' when crc_cmp = crc_frag else '1';
562 -- count number of FED crc error
563 process(Greset_CLK,clock)
565 if Greset_CLK = '0' then
566 FED_CRC_error_cnt <= (others => '0');
567 elsif rising_edge(clock) then
568 if ena_CRC_reg = '1' and crc_check = '1' then
569 FED_CRC_error_cnt <= FED_CRC_error_cnt + '1';
574 -- generate FLAG to indicate the beginning and the end of the event for each BLOCK
575 process(Greset_CLK,clock)
577 if Greset_CLK = '0' then
578 start_evt_mem <= '0';
580 elsif rising_edge(clock) then
581 if datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
582 start_evt_mem <= '1';
583 elsif last_word = '1' then
585 elsif fill_blk = update_para then --finish_blk = '1' then
586 start_evt_mem <= '0';
592 -- compute the size of valid data in the BLOCK
593 process(Greset_CLK,clock)
595 if Greset_CLK = '0' then
596 blk_size <= (others => '0');
597 elsif rising_edge(clock) then
598 if fill_blk = idle then
599 blk_size <= (others => '0');
600 elsif rd_ff_reg = '1' and blk_full = '0' then
601 blk_size <= blk_size + '1';
606 -- count the number of block used
607 process(Greset_CLK,clock)
609 if Greset_CLK = '0' then
610 block_counter <= (others => '0');
611 elsif rising_edge(clock) then
612 if blk_full = '1' or last_word = '1' then
613 block_counter <= block_counter + '1';
618 --flag when the BLOCK is full
619 process(Greset_CLK,clock)
621 if Greset_CLK = '0' then
623 elsif rising_edge(clock) then
624 if blk_size = x"01FF" and rd_ff_reg = '1' then --blk_size = 0x200
626 elsif End_pckt_lgc = '1' then
632 End_pckt_lgc <= '1' when fill_blk = update_para else '0';
634 --Pipe data for the CRC check
638 if rising_edge(clock) then
639 datar_rreg(63 downto 0) <= datar_reg(63 downto 0);
640 blk_size_reg <= blk_size;
641 start_evt_mem_reg <= start_evt_mem;
642 stop_evt_mem_reg <= stop_evt_mem;
643 End_pckt_lgc_reg <= End_pckt_lgc;
648 data_out(63 downto 32) <= datar_rreg(63 downto 32);
649 data_out(31 downto 16) <= crc_cmp when ena_CRC_reg = '1' else datar_rreg(31 downto 16);
650 data_out(15 downto 3) <= datar_rreg(15 downto 3);
651 data_out(2) <= crc_check when ena_CRC_reg = '1' else datar_rreg(2);
652 data_out(1 downto 0) <= datar_rreg(1 downto 0) ;
656 if rising_edge(clock) then
657 del_rd_ff(1) <= del_rd_ff(0);
658 del_rd_ff(0) <= rd_ff_reg;
662 --Output value to Optical interface
663 block_sz_fed <= blk_size_reg;
-- number of data in the block ready to send
664 data_fed <= data_out;
665 wr_ena <= del_rd_ff(1);
666 start_evt <= start_evt_mem_reg;
-- flag is set if this block is the first of the event
667 stop_evt <= stop_evt_mem_reg;
-- flag is set if this block is the last of the event
668 end_blk_fed <= End_pckt_lgc_reg;
-- flag is set at the end of the event