1 ------------------------------------------------------
6 -- Dominique Gigi May 2015
7 ------------------------------------------------------
8 -- This is the TOP level of the core for the sender part
10 ------------------------------------------------------
13 USE ieee.std_logic_1164.
all;
14 use ieee.numeric_std.
all;
15 use ieee.std_logic_unsigned.
all;
20 generic (generator : := false);
26 -- link data write enable ACTIVE LOW
28 -- link data header/trailer marker when '0'
31 LinkData : in (63 downto 0);
32 -- link data buffer almost full ACTIVE LOW
33 LinkAlmostFull : out ;
34 -- link down ACTIVE LOW
37 src_ID : in (15 downto 0);
38 -- enables error injection to test error recovery
39 inject_err : in (17 downto 0);
40 -- Link status data read out
42 addr : in (15 downto 0);
43 status_data : out (63 downto 0);
45 -- Interface for internal logic
48 clock : in ;
-- clock from internal logic
49 block_free : in ;
-- almost one block is free
51 data_fed : out (63 downto 0);
52 block_sz_fed : out (15 downto 0);
54 start_evt : out ;
-- this block is the first for the current event
55 stop_evt : out ;
-- this block is the last for the current event -- both can be set
56 end_blk_fed : out ;
-- indicate end of the packet (max 4KBytes)
57 -- interface slave to read and write
59 func : in (31 downto 0);
60 data_wr : in (31 downto 0);
61 data_rd : out (63 downto 0);
62 cnt_evt : out ;
-- pulse for each event (on sys_clk);
63 cnt_pckt_rcv : in (31 downto 0);
64 cnt_pckt_snd : in (31 downto 0);
67 status_state_build_p : in (31 downto 0);
68 status_state_core : in (31 downto 0);
69 Serdes_status : in (31 downto 0)
76 type fill_blk_type is ( idle,
81 dummy_c -- dummy state implement du to the CRC check , which take 2 clock cylces more
83 signal fill_blk,fill_blkNext:fill_blk_type;
88 aclr :
in ;
-- active low
91 dataw :
in (
65 downto 0);
92 almost_f :
out ;
-- active low
94 datar :
out (
65 downto 0);
96 empty :
out -- active low
103 low_clk :
IN ;
-- frequency of 50 Mhz
105 PCIe_func :
IN (
15 downto 0);
107 PCIe_dti :
IN (
31 downto 0);
108 PCIe_dto :
out (
31 downto 0);
112 data :
OUT (
63 downto 0);
114 Back_p :
IN -- Back_p when '0'
120 D :
in (
63 downto 0);
121 CRC_out :
out (
15 downto 0);
130 sysclk :
in ;
-- clock used by the FED to send data and to measure the backpressure
131 base_clk :
in ;
-- clock base used to measure the sysclk
132 frequency :
out (
31 downto 0)
-- measure of the frequency)
137 signal datar_rreg : (63 downto 0);
138 signal data_out : (63 downto 0);
139 signal datar : (65 downto 0);
140 signal datar_reg : (63 downto 0);
141 signal start_evt_mem : ;
142 signal stop_evt_mem : ;
144 signal finish_blk : ;
148 signal del_rd_ff : (1 downto 0);
149 signal blk_size : (15 downto 0);
151 signal blk_full_anti : ;
153 signal End_pckt_lgc : ;
155 signal sel_test_mode : ;
157 signal data_tm : (63 downto 0);
159 signal backpressure_mux : ;
161 signal data_mux : (63 downto 0);
163 signal PCIe_dto : (31 downto 0);
164 signal local_reg : (31 downto 0);
165 signal LINKDOWN_cell : ;
167 -- use to pipe frgament during the CRC check
168 signal data_r_crc : (63 downto 0);
174 signal ena_CRC_reg : ;
175 signal CRC_frag : (15 downto 0);
176 signal CRC_cmp : (15 downto 0);
177 signal data_rb_mux : (63 downto 0);
178 signal backpressure : ;
181 signal block_counter : (31 downto 0);
182 signal event_counter : (31 downto 0);
183 signal data_counter : (63 downto 0);
184 signal Retransmit_counter : (31 downto 0);
185 signal cnt_back_p : (31 downto 0);
186 signal FED_CRC_error_cnt : (31 downto 0);
187 signal state_machine_status: (2 downto 0);
190 signal blk_size_reg : (15 downto 0);
191 signal start_evt_mem_reg : ;
192 signal stop_evt_mem_reg : ;
193 signal End_pckt_lgc_reg : ;
195 signal freq_measure_reg : (31 downto 0);
196 signal rsyc_test_mode : (1 downto 0);
197 signal rsyc_DAQON : (1 downto 0);
199 signal evt_ongoing : ;
203 signal track_evt_num : (23 downto 0);
205 --***********************************************************
206 --********************** BEGIN ****************************
207 --***********************************************************
211 -- Set the TEST mode and DAQ_ON with function (6)
212 -- this function will come from optical link send by DAQ side
213 process(Greset_CLK,clock)
215 if Greset_CLK = '0' then
216 sel_test_mode <= '0';
217 LINKDOWN_cell <= '0';
218 elsif rising_edge(clock) then
219 if func(6) = '1' and wr_cmd = '1' then
220 sel_test_mode <= data_wr(31);
221 LINKDOWN_cell <= data_wr(30);
228 if rising_edge(sys_clk) then
229 rsyc_test_mode(1) <= rsyc_test_mode(0);
230 rsyc_test_mode(0) <= sel_test_mode;
235 local_reg(
31) <= sel_test_mode;
236 local_reg(
30) <= LINKDOWN_cell;
237 local_reg(
29) <= Backpressure;
238 local_reg(
28) <= '1'
when block_free = '1'
else '0';
239 local_reg(
27 downto 7) <= (
others => '0');
240 local_reg(
6) <= found_dup;
241 local_reg(
5) <= TR_dup;
242 local_reg(
4) <= HD_dup;
243 local_reg(
3) <= evt_ongoing;
244 local_reg(
2 downto 0) <= state_machine_status(
2 downto 0);
246 process(Greset_sysCLK,sys_clk)
248 if rising_edge(sys_clk) then
249 rsyc_DAQON(1) <= rsyc_DAQON(0);
250 rsyc_DAQON(0) <= LINKDOWN_cell;
254 LinkDown <= rsyc_DAQON(1);
256 -- measure the frequency used by the fed to send data
259 reset => Greset_sysCLK,
260 sysclk => sys_clk,
-- clock used by the FED to send data and to measure the backpressure
262 frequency => freq_measure_reg
-- measure of the frequency)
265 process(Greset_sysCLK,sys_clk)
267 if Greset_sysCLK = '0' then
268 cnt_back_p <= (others => '0');
269 elsif rising_edge(sys_clk) then
270 if backpressure_mux = '0' then
271 cnt_back_p <= cnt_back_p + '1';
276 --multiplex data local and Event_gen status/data for read command coming from optical link send by DAQ side
280 if rising_edge(clock) then
281 data_rd(63 downto 32) <= (others => '0');
282 if func(6) = '1' then
283 data_rd(31 downto 0) <= local_reg;
284 elsif func(7) = '1' then
285 data_rd <= data_counter;
286 elsif func(8) = '1' then
287 data_rd(31 downto 0) <= event_counter;
288 elsif func(9) = '1' then
289 data_rd(31 downto 0) <= block_counter;
290 elsif func(10) = '1' then
291 data_rd(31 downto 0) <= cnt_pckt_rcv;
292 elsif func(11) = '1' then
293 data_rd(31 downto 0) <= status_state_core;
294 elsif func(12) = '1' then
295 data_rd(31 downto 0) <= cnt_pckt_snd;
296 elsif func(13) = '1' then
297 data_rd(31 downto 0) <= status_state_build_p;
298 elsif func(14) = '1' then
299 data_rd(31 downto 0) <= cnt_back_p;
300 elsif func(15) = '1' then
301 data_rd(31 downto 0) <= version;
302 elsif func(16) = '1' then
303 data_rd(31 downto 0) <= Serdes_status;
304 elsif func(17) = '1' then
305 data_rd(31 downto 0) <= Retransmit_counter;
306 elsif func(18) = '1' then
307 data_rd(31 downto 0) <= freq_measure_reg;
309 data_rd(31 downto 0) <= PCIe_dto;
314 -- status going back to FED side
317 if rising_edge(sys_clk) then
318 status_data(63 downto 00) <= (others => '0');
319 if addr = x"0001" then
320 status_data(31 downto 0) <= local_reg;
321 elsif addr = x"0002" then
322 status_data <= data_counter;
323 elsif addr = x"0003" then
324 status_data(31 downto 0) <= event_counter;
325 elsif addr = x"0004" then
326 status_data(31 downto 0) <= block_counter;
327 elsif addr = x"0005" then
328 status_data(31 downto 0) <= cnt_pckt_rcv;
329 elsif addr = x"0006" then
330 status_data(31 downto 0) <= status_state_core;
331 elsif addr = x"0007" then
332 status_data(31 downto 0) <= cnt_pckt_snd;
333 elsif addr = x"0008" then
334 status_data(31 downto 0) <= status_state_build_p;
335 elsif addr = x"0009" then
336 status_data(31 downto 0) <= cnt_back_p;
337 elsif addr = x"000A" then
338 status_data(31 downto 0) <= version;
339 elsif addr = x"000B" then
340 status_data(31 downto 0) <= Serdes_status;
341 elsif addr = x"000C" then
342 status_data(31 downto 0) <= Retransmit_counter;
343 elsif addr = x"000D" then
344 status_data(31 downto 0) <= FED_CRC_error_cnt;
345 elsif addr = x"000E" then
346 status_data(31 downto 0) <= freq_measure_reg;
351 -- retransmit counter
352 process(Greset_CLK,clock)
354 if Greset_CLK = '0' then
355 Retransmit_counter <= (others => '0');
356 elsif rising_edge(clock) then
357 if retransmit_ena = '1' then
358 Retransmit_counter <= Retransmit_counter + '1';
363 -- local Event generator used to test the link
364 generator_inst:if generator generate
368 low_clk => clock,
-- frequency of ??? Mhz
370 PCIe_func => func
(15 downto 0),
373 PCIe_dto => PCIe_dto,
374 PCIe_cs => sel_test_mode,
379 Back_p => backpressure_mux
384 --******************************************************************************
385 -- multiplexer for event DATA
386 -- mux external (FED) and local data path (Event generator) ********************
388 wen_mux <= wen_tm when rsyc_test_mode(1) = '1' and generator else not(LinkWe);
389 data_mux <= data_tm when rsyc_test_mode(1) = '1' and generator else LinkData;
390 uctrl_mux <= uctrl_tm when rsyc_test_mode(1) = '1' and generator else LinkCtrl;
392 --******************************************************************************
393 process(Greset_sysCLK,sys_clk)
395 if Greset_sysCLK = '0' then
396 data_counter <= (others => '0');
397 elsif rising_edge(sys_clk) then
398 if wen_mux = '1' then
399 data_counter <= data_counter + '1';
404 --indicate the last word of the EVENT
405 end_frag <= '1' when data_mux(63 downto 60) = x"A" and uctrl_mux = '0' else '0';
407 -- pulse to count the number of event dicover
408 process(Greset_sysCLK,sys_clk)
410 if Greset_sysCLK = '0' then
412 elsif rising_edge(sys_clk) then
414 if end_frag = '1' then
420 -- internal FIFO used to chnage the DATA clock domaine
424 aclr => Greset_sysCLK,
427 dataw
(63 downto 0) => data_mux,
428 dataw
(64) => uctrl_mux,
429 dataw
(65) => end_frag,
430 almost_f => backpressure_mux,
438 -- LinkAlmostFull LFF is valid only in no TEST mode otherwise ALLTIME active (low)
439 Backpressure <= '0' when rsyc_test_mode(1) = '1' else backpressure_mux;
440 LinkAlmostFull <= Backpressure;
442 --******************************************************************************
443 -- -******* This state machine is used to read the FIFO and fill the blocks in the CORE_LOGIC.VHD file
444 --state machine clock
445 FED_itf_state_clk:
process(Greset_CLK,clock)
447 if Greset_CLK = '0' then
449 elsif rising_edge(clock) then
450 fill_blk <= fill_blkNext;
454 FED_itf_state_machine:
process(fill_blk,empt_ff,block_free,blk_full,last_word)
456 fill_blkNext <= fill_blk;
457 state_machine_status <= (others => '0');
459 -- wait data and free block in CORE_LOGIC.VHD
462 state_machine_status(0) <='1';
463 if empt_ff = '0' and block_free = '1' then
464 fill_blkNext <= read_fifo;
467 -- continue until the last word of the EVENT or until no free BLOCK
469 state_machine_status(1) <='1';
470 if blk_full = '1' or last_word = '1' then --stop_evt_mem = '1' then
471 fill_blkNext <= update_para;
474 -- unpdate flags and indicate end of block (block full or end_of_event)
476 state_machine_status(2) <='1';
477 fill_blkNext <= dummy_a;
480 fill_blkNext <= dummy_b;
483 fill_blkNext <= dummy_c;
-- take 3 clock
to finish
to clsoe the
buffer,
if no the block_free value can be wrong
486 fill_blkNext <= idle;
489 fill_blkNext <= idle;
492 --******************************************************************************
494 last_word <= '1' when rd_ff_reg = '1' and datar(65) = '1' else '0';
496 G_rst_rd <= '0' when Greset_CLK = '0' or empt_ff = '1' or blk_full = '1' else '1';
498 -- automatic read FIFO until the the last word of the EVENT or end of block (change state FILL_BLK)
499 process(G_rst_rd,clock)
501 if G_rst_rd = '0' then
503 elsif rising_edge(clock) then
505 if fill_blk = read_fifo and last_word = '0' then
511 --******************************************************************************
513 process(Greset_CLK,clock)
515 if Greset_CLK = '0' then
518 event_counter <= (others => '0');
523 track_evt_num <= (others => '0');
524 elsif rising_edge(clock) then
526 if datar(64) = '0' and datar(63 downto 60) = x"A" and rd_ff_reg = '1' then -- UCTRL= 0 + trailer + DATA_valid
527 -- remove the CRC in the trailer to compute the CRC
528 data_r_crc(63 downto 32) <= datar(63 downto 32);
529 data_r_crc(31 downto 16) <= (others => '0');
530 data_r_crc(15 downto 0) <= datar(15 downto 0);
532 data_r_crc <= datar(63 downto 00);
535 datar_reg <= datar(63 downto 00);
537 -- create the envelop of the event + counter status
538 if datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
539 event_counter <= event_counter + '1';
541 if evt_ongoing = '1' then
544 if track_evt_num = datar(55 downto 32) then
547 track_evt_num <= datar(55 downto 32);
550 -- specify the place of the Trailer
551 ena_CRC_reg <= ena_CRC;
554 if datar(64) = '0' and datar(63 downto 60) = x"A" and rd_ff_reg = '1' then
556 crc_frag <= datar(31 downto 16);
558 if evt_ongoing = '0' then
563 -- reset the CRC machine between 2 fragments
564 if ena_crc = '1' then -- execute a reset when a Trailer appears
566 elsif datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
583 -- compare the CRC received and the CRC computed
584 crc_check <= '0' when crc_cmp = crc_frag else '1';
586 -- count number of FED crc error
587 process(Greset_CLK,clock)
589 if Greset_CLK = '0' then
590 FED_CRC_error_cnt <= (others => '0');
591 elsif rising_edge(clock) then
592 if ena_CRC_reg = '1' and crc_check = '1' then
593 FED_CRC_error_cnt <= FED_CRC_error_cnt + '1';
598 -- generate FLAG to indicate the beginning and the end of the event for each BLOCK
599 process(Greset_CLK,clock)
601 if Greset_CLK = '0' then
602 start_evt_mem <= '0';
604 elsif rising_edge(clock) then
605 if datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
606 start_evt_mem <= '1';
607 elsif last_word = '1' then
609 elsif fill_blk = update_para then --finish_blk = '1' then
610 start_evt_mem <= '0';
616 -- compute the size of valid data in the BLOCK
617 process(Greset_CLK,clock)
619 if Greset_CLK = '0' then
620 blk_size <= (others => '0');
621 elsif rising_edge(clock) then
622 if fill_blk = idle then
623 blk_size <= (others => '0');
624 elsif rd_ff_reg = '1' and blk_full = '0' then
625 blk_size <= blk_size + '1';
630 -- count the number of block used
631 process(Greset_CLK,clock)
633 if Greset_CLK = '0' then
634 block_counter <= (others => '0');
635 elsif rising_edge(clock) then
636 if blk_full = '1' or last_word = '1' then
637 block_counter <= block_counter + '1';
642 --flag when the BLOCK is full
643 process(Greset_CLK,clock)
645 if Greset_CLK = '0' then
647 elsif rising_edge(clock) then
648 if blk_size = x"01FF" and rd_ff_reg = '1' then --blk_size = 0x200
650 elsif End_pckt_lgc = '1' then
656 End_pckt_lgc <= '1' when fill_blk = update_para else '0';
658 --Pipe data for the CRC check
662 if rising_edge(clock) then
663 datar_rreg(63 downto 0) <= datar_reg(63 downto 0);
664 blk_size_reg <= blk_size;
665 start_evt_mem_reg <= start_evt_mem;
666 stop_evt_mem_reg <= stop_evt_mem;
667 End_pckt_lgc_reg <= End_pckt_lgc;
672 data_out(63 downto 32) <= datar_rreg(63 downto 32);
673 data_out(31 downto 16) <= crc_cmp when ena_CRC_reg = '1' else datar_rreg(31 downto 16);
674 data_out(15 downto 3) <= datar_rreg(15 downto 3);
675 data_out(2) <= crc_check when ena_CRC_reg = '1' else datar_rreg(2);
676 data_out(1 downto 0) <= datar_rreg(1 downto 0) ;
680 if rising_edge(clock) then
681 del_rd_ff(1) <= del_rd_ff(0);
682 del_rd_ff(0) <= rd_ff_reg;
686 --Output value to Optical interface
687 block_sz_fed <= blk_size_reg;
-- number of data in the block ready to send
688 data_fed <= data_out;
689 wr_ena <= del_rd_ff(1);
690 start_evt <= start_evt_mem_reg;
-- flag is set if this block is the first of the event
691 stop_evt <= stop_evt_mem_reg;
-- flag is set if this block is the last of the event
692 end_blk_fed <= End_pckt_lgc_reg;
-- flag is set at the end of the event