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 signal evt_ongoing : ;
206 signal track_evt_num : (23 downto 0);
208 --***********************************************************
209 --********************** BEGIN ****************************
210 --***********************************************************
214 -- Set the TEST mode and DAQ_ON with function (6)
215 -- this function will come from optical link send by DAQ side
216 process(Greset_CLK,clock)
218 if Greset_CLK = '0' then
219 sel_test_mode <= '0';
220 LINKDOWN_cell <= '0';
221 elsif rising_edge(clock) then
222 if func(6) = '1' and wr_cmd = '1' then
223 sel_test_mode <= data_wr(31);
224 LINKDOWN_cell <= data_wr(30);
231 if rising_edge(sys_clk) then
232 rsyc_test_mode(1) <= rsyc_test_mode(0);
233 rsyc_test_mode(0) <= sel_test_mode;
238 local_reg(
31) <= sel_test_mode;
239 local_reg(
30) <= LINKDOWN_cell;
240 local_reg(
29) <= Backpressure;
241 local_reg(
28) <= '1'
when block_free = '1'
else '0';
242 local_reg(
27 downto 7) <= (
others => '0');
243 local_reg(
6) <= found_dup;
244 local_reg(
5) <= TR_dup;
245 local_reg(
4) <= HD_dup;
246 local_reg(
3) <= evt_ongoing;
247 local_reg(
2 downto 0) <= state_machine_status(
2 downto 0);
249 process(Greset_sysCLK,sys_clk)
251 if rising_edge(sys_clk) then
252 rsyc_DAQON(1) <= rsyc_DAQON(0);
253 rsyc_DAQON(0) <= LINKDOWN_cell;
257 LinkDown <= rsyc_DAQON(1);
259 -- measure the frequency used by the fed to send data
262 reset => Greset_sysCLK,
263 sysclk => sys_clk,
-- clock used by the FED to send data and to measure the backpressure
265 frequency => freq_measure_reg
-- measure of the frequency)
268 process(Greset_sysCLK,sys_clk)
270 if Greset_sysCLK = '0' then
271 cnt_back_p <= (others => '0');
272 elsif rising_edge(sys_clk) then
273 if backpressure_mux = '0' then
274 cnt_back_p <= cnt_back_p + '1';
279 --multiplex data local and Event_gen status/data for read command coming from optical link send by DAQ side
283 if rising_edge(clock) then
284 data_rd(63 downto 32) <= (others => '0');
285 if func(6) = '1' then
286 data_rd(31 downto 0) <= local_reg;
287 elsif func(7) = '1' then
288 data_rd <= data_counter;
289 elsif func(8) = '1' then
290 data_rd(31 downto 0) <= event_counter;
291 elsif func(9) = '1' then
292 data_rd(31 downto 0) <= block_counter;
293 elsif func(10) = '1' then
294 data_rd(31 downto 0) <= cnt_pckt_rcv;
295 elsif func(11) = '1' then
296 data_rd(31 downto 0) <= status_state_core;
297 elsif func(12) = '1' then
298 data_rd(31 downto 0) <= cnt_pckt_snd;
299 elsif func(13) = '1' then
300 data_rd(31 downto 0) <= status_state_build_p;
301 elsif func(14) = '1' then
302 data_rd(31 downto 0) <= cnt_back_p;
303 elsif func(15) = '1' then
304 data_rd(31 downto 0) <= version;
305 elsif func(16) = '1' then
306 data_rd(31 downto 0) <= Serdes_status;
307 elsif func(17) = '1' then
308 data_rd(31 downto 0) <= Retransmit_counter;
309 elsif func(18) = '1' then
310 data_rd(31 downto 0) <= freq_measure_reg;
312 data_rd(31 downto 0) <= PCIe_dto;
317 -- status going back to FED side
320 if rising_edge(sys_clk) then
321 status_data(63 downto 00) <= (others => '0');
322 if addr = x"0001" then
323 status_data(31 downto 0) <= local_reg;
324 elsif addr = x"0002" then
325 status_data <= data_counter;
326 elsif addr = x"0003" then
327 status_data(31 downto 0) <= event_counter;
328 elsif addr = x"0004" then
329 status_data(31 downto 0) <= block_counter;
330 elsif addr = x"0005" then
331 status_data(31 downto 0) <= cnt_pckt_rcv;
332 elsif addr = x"0006" then
333 status_data(31 downto 0) <= status_state_core;
334 elsif addr = x"0007" then
335 status_data(31 downto 0) <= cnt_pckt_snd;
336 elsif addr = x"0008" then
337 status_data(31 downto 0) <= status_state_build_p;
338 elsif addr = x"0009" then
339 status_data(31 downto 0) <= cnt_back_p;
340 elsif addr = x"000A" then
341 status_data(31 downto 0) <= version;
342 elsif addr = x"000B" then
343 status_data(31 downto 0) <= Serdes_status;
344 elsif addr = x"000C" then
345 status_data(31 downto 0) <= Retransmit_counter;
346 elsif addr = x"000D" then
347 status_data(31 downto 0) <= FED_CRC_error_cnt;
348 elsif addr = x"000E" then
349 status_data(31 downto 0) <= freq_measure_reg;
354 -- retransmit counter
355 process(Greset_CLK,clock)
357 if Greset_CLK = '0' then
358 Retransmit_counter <= (others => '0');
359 elsif rising_edge(clock) then
360 if retransmit_ena = '1' then
361 Retransmit_counter <= Retransmit_counter + '1';
366 -- local Event generator used to test the link
367 generator_inst:if generator generate
371 low_clk => clock,
-- frequency of ??? Mhz
373 PCIe_func => func
(15 downto 0),
376 PCIe_dto => PCIe_dto,
377 PCIe_cs => sel_test_mode,
382 Back_p => backpressure_mux
387 --******************************************************************************
388 -- multiplexer for event DATA
389 -- mux external (FED) and local data path (Event generator) ********************
391 wen_mux <= wen_tm when rsyc_test_mode(1) = '1' and generator else not(LinkWe);
392 data_mux <= data_tm when rsyc_test_mode(1) = '1' and generator else LinkData;
393 uctrl_mux <= uctrl_tm when rsyc_test_mode(1) = '1' and generator else LinkCtrl;
395 --******************************************************************************
396 process(Greset_sysCLK,sys_clk)
398 if Greset_sysCLK = '0' then
399 data_counter <= (others => '0');
400 elsif rising_edge(sys_clk) then
401 if wen_mux = '1' then
402 data_counter <= data_counter + '1';
407 --indicate the last word of the EVENT
408 end_frag <= '1' when data_mux(63 downto 60) = x"A" and uctrl_mux = '0' else '0';
410 -- pulse to count the number of event dicover
411 process(Greset_sysCLK,sys_clk)
413 if Greset_sysCLK = '0' then
415 elsif rising_edge(sys_clk) then
417 if end_frag = '1' then
423 -- internal FIFO used to chnage the DATA clock domaine
427 aclr => Greset_sysCLK,
430 dataw
(63 downto 0) => data_mux,
431 dataw
(64) => uctrl_mux,
432 dataw
(65) => end_frag,
433 almost_f => backpressure_mux,
441 -- LinkAlmostFull LFF is valid only in no TEST mode otherwise ALLTIME active (low)
442 Backpressure <= '0' when rsyc_test_mode(1) = '1' else backpressure_mux;
443 LinkAlmostFull <= Backpressure;
445 --******************************************************************************
446 -- -******* This state machine is used to read the FIFO and fill the blocks in the CORE_LOGIC.VHD file
447 --state machine clock
448 FED_itf_state_clk:
process(Greset_CLK,clock)
450 if Greset_CLK = '0' then
452 elsif rising_edge(clock) then
453 fill_blk <= fill_blkNext;
457 FED_itf_state_machine:
process(fill_blk,empt_ff,block_free,blk_full,last_word)
459 fill_blkNext <= fill_blk;
460 state_machine_status <= (others => '0');
462 -- wait data and free block in CORE_LOGIC.VHD
465 state_machine_status(0) <='1';
466 if empt_ff = '0' and block_free = '1' then
467 fill_blkNext <= read_fifo;
470 -- continue until the last word of the EVENT or until no free BLOCK
472 state_machine_status(1) <='1';
473 if blk_full = '1' or last_word = '1' then --stop_evt_mem = '1' then
474 fill_blkNext <= update_para;
477 -- unpdate flags and indicate end of block (block full or end_of_event)
479 state_machine_status(2) <='1';
480 fill_blkNext <= dummy_a;
483 fill_blkNext <= dummy_b;
486 fill_blkNext <= dummy_c;
-- take 3 clock
to finish
to clsoe the
buffer,
if no the block_free value can be wrong
489 fill_blkNext <= idle;
492 fill_blkNext <= idle;
495 --******************************************************************************
497 last_word <= '1' when rd_ff_reg = '1' and datar(65) = '1' else '0';
499 G_rst_rd <= '0' when Greset_CLK = '0' or empt_ff = '1' or blk_full = '1' else '1';
501 -- automatic read FIFO until the the last word of the EVENT or end of block (change state FILL_BLK)
502 process(G_rst_rd,clock)
504 if G_rst_rd = '0' then
506 elsif rising_edge(clock) then
508 if fill_blk = read_fifo and last_word = '0' then
514 --******************************************************************************
516 process(Greset_CLK,clock)
518 if Greset_CLK = '0' then
521 event_counter <= (others => '0');
526 track_evt_num <= (others => '0');
527 elsif rising_edge(clock) then
529 if datar(64) = '0' and datar(63 downto 60) = x"A" and rd_ff_reg = '1' then -- UCTRL= 0 + trailer + DATA_valid
530 -- remove the CRC in the trailer to compute the CRC
531 data_r_crc(63 downto 32) <= datar(63 downto 32);
532 data_r_crc(31 downto 16) <= (others => '0');
533 data_r_crc(15 downto 0) <= datar(15 downto 0);
535 data_r_crc <= datar(63 downto 00);
538 datar_reg <= datar(63 downto 00);
540 -- create the envelop of the event + counter status
541 if datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
542 event_counter <= event_counter + '1';
544 if evt_ongoing = '1' then
547 if track_evt_num = datar(55 downto 32) then
550 track_evt_num <= datar(55 downto 32);
553 -- specify the place of the Trailer
554 ena_CRC_reg <= ena_CRC;
557 if datar(64) = '0' and datar(63 downto 60) = x"A" and rd_ff_reg = '1' then
559 crc_frag <= datar(31 downto 16);
561 if evt_ongoing = '0' then
566 -- reset the CRC machine between 2 fragments
567 if ena_crc = '1' then
569 elsif datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
586 -- compare the CRC received and the CRC computed
587 crc_check <= '0' when crc_cmp = crc_frag else '1';
589 -- count number of FED crc error
590 process(Greset_CLK,clock)
592 if Greset_CLK = '0' then
593 FED_CRC_error_cnt <= (others => '0');
594 elsif rising_edge(clock) then
595 if ena_CRC_reg = '1' and crc_check = '1' then
596 FED_CRC_error_cnt <= FED_CRC_error_cnt + '1';
601 -- generate FLAG to indicate the beginning and the end of the event for each BLOCK
602 process(Greset_CLK,clock)
604 if Greset_CLK = '0' then
605 start_evt_mem <= '0';
607 elsif rising_edge(clock) then
608 if datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
609 start_evt_mem <= '1';
610 elsif last_word = '1' then
612 elsif fill_blk = update_para then --finish_blk = '1' then
613 start_evt_mem <= '0';
619 -- compute the size of valid data in the BLOCK
620 process(Greset_CLK,clock)
622 if Greset_CLK = '0' then
623 blk_size <= (others => '0');
624 elsif rising_edge(clock) then
625 if fill_blk = idle then
626 blk_size <= (others => '0');
627 elsif rd_ff_reg = '1' and blk_full = '0' then
628 blk_size <= blk_size + '1';
633 -- count the number of block used
634 process(Greset_CLK,clock)
636 if Greset_CLK = '0' then
637 block_counter <= (others => '0');
638 elsif rising_edge(clock) then
639 if blk_full = '1' or last_word = '1' then
640 block_counter <= block_counter + '1';
645 --flag when the BLOCK is full
646 process(Greset_CLK,clock)
648 if Greset_CLK = '0' then
650 elsif rising_edge(clock) then
651 if blk_size = x"01FF" and rd_ff_reg = '1' then --blk_size = 0x200
653 elsif End_pckt_lgc = '1' then
659 End_pckt_lgc <= '1' when fill_blk = update_para else '0';
661 --Pipe data for the CRC check
665 if rising_edge(clock) then
666 datar_rreg(63 downto 0) <= datar_reg(63 downto 0);
667 blk_size_reg <= blk_size;
668 start_evt_mem_reg <= start_evt_mem;
669 stop_evt_mem_reg <= stop_evt_mem;
670 End_pckt_lgc_reg <= End_pckt_lgc;
675 data_out(63 downto 32) <= datar_rreg(63 downto 32);
676 data_out(31 downto 16) <= crc_cmp when ena_CRC_reg = '1' else datar_rreg(31 downto 16);
677 data_out(15 downto 3) <= datar_rreg(15 downto 3);
678 data_out(2) <= crc_check when ena_CRC_reg = '1' else datar_rreg(2);
679 data_out(1 downto 0) <= datar_rreg(1 downto 0) ;
683 if rising_edge(clock) then
684 del_rd_ff(1) <= del_rd_ff(0);
685 del_rd_ff(0) <= rd_ff_reg;
689 --Output value to Optical interface
690 block_sz_fed <= blk_size_reg;
-- number of data in the block ready to send
691 data_fed <= data_out;
692 wr_ena <= del_rd_ff(1);
693 start_evt <= start_evt_mem_reg;
-- flag is set if this block is the first of the event
694 stop_evt <= stop_evt_mem_reg;
-- flag is set if this block is the last of the event
695 end_blk_fed <= End_pckt_lgc_reg;
-- flag is set at the end of the event