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)
74 architecture behavioral
of fed_itf is
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 --***********************************************************
200 --********************** BEGIN ****************************
201 --***********************************************************
205 -- Set the TEST mode and DAQ_ON with function (6)
206 -- this function will come from optical link send by DAQ side
207 process(Greset_CLK,clock)
209 if Greset_CLK = '0' then
210 sel_test_mode <= '0';
211 LINKDOWN_cell <= '0';
212 elsif rising_edge(clock) then
213 if func(6) = '1' and wr_cmd = '1' then
214 sel_test_mode <= data_wr(31);
215 LINKDOWN_cell <= data_wr(30);
222 if rising_edge(sys_clk) then
223 rsyc_test_mode(1) <= rsyc_test_mode(0);
224 rsyc_test_mode(0) <= sel_test_mode;
229 local_reg(
31) <= sel_test_mode;
230 local_reg(
30) <= LINKDOWN_cell;
231 local_reg(
29) <= Backpressure;
232 local_reg(
28) <= '1'
when block_free = '1'
else '0';
233 local_reg(
27 downto 3) <= (
others => '0');
234 local_reg(
2 downto 0) <= state_machine_status(
2 downto 0);
236 process(Greset_sysCLK,sys_clk)
238 if rising_edge(sys_clk) then
239 rsyc_DAQON(1) <= rsyc_DAQON(0);
240 rsyc_DAQON(0) <= LINKDOWN_cell;
244 LinkDown <= rsyc_DAQON(1);
246 -- measure the frequency used by the fed to send data
249 reset => Greset_sysCLK,
250 sysclk => sys_clk,
-- clock used by the FED to send data and to measure the backpressure
252 frequency => freq_measure_reg
-- measure of the frequency)
255 process(Greset_sysCLK,sys_clk)
257 if Greset_sysCLK = '0' then
258 cnt_back_p <= (others => '0');
259 elsif rising_edge(sys_clk) then
260 if backpressure_mux = '0' then
261 cnt_back_p <= cnt_back_p + '1';
266 --multiplex data local and Event_gen status/data for read command coming from optical link send by DAQ side
270 if rising_edge(clock) then
271 data_rd(63 downto 32) <= (others => '0');
272 if func(6) = '1' then
273 data_rd(31 downto 0) <= local_reg;
274 elsif func(7) = '1' then
275 data_rd <= data_counter;
276 elsif func(8) = '1' then
277 data_rd(31 downto 0) <= event_counter;
278 elsif func(9) = '1' then
279 data_rd(31 downto 0) <= block_counter;
280 elsif func(10) = '1' then
281 data_rd(31 downto 0) <= cnt_pckt_rcv;
282 elsif func(11) = '1' then
283 data_rd(31 downto 0) <= status_state_core;
284 elsif func(12) = '1' then
285 data_rd(31 downto 0) <= cnt_pckt_snd;
286 elsif func(13) = '1' then
287 data_rd(31 downto 0) <= status_state_build_p;
288 elsif func(14) = '1' then
289 data_rd(31 downto 0) <= cnt_back_p;
290 elsif func(15) = '1' then
291 data_rd(31 downto 0) <= version;
292 elsif func(16) = '1' then
293 data_rd(31 downto 0) <= Serdes_status;
294 elsif func(17) = '1' then
295 data_rd(31 downto 0) <= Retransmit_counter;
296 elsif func(18) = '1' then
297 data_rd(31 downto 0) <= freq_measure_reg;
299 data_rd(31 downto 0) <= PCIe_dto;
304 -- status going back to FED side
307 if rising_edge(sys_clk) then
308 status_data(63 downto 00) <= (others => '0');
309 if addr = x"0001" then
310 status_data(31 downto 0) <= local_reg;
311 elsif addr = x"0002" then
312 status_data <= data_counter;
313 elsif addr = x"0003" then
314 status_data(31 downto 0) <= event_counter;
315 elsif addr = x"0004" then
316 status_data(31 downto 0) <= block_counter;
317 elsif addr = x"0005" then
318 status_data(31 downto 0) <= cnt_pckt_rcv;
319 elsif addr = x"0006" then
320 status_data(31 downto 0) <= status_state_core;
321 elsif addr = x"0007" then
322 status_data(31 downto 0) <= cnt_pckt_snd;
323 elsif addr = x"0008" then
324 status_data(31 downto 0) <= status_state_build_p;
325 elsif addr = x"0009" then
326 status_data(31 downto 0) <= cnt_back_p;
327 elsif addr = x"000A" then
328 status_data(31 downto 0) <= version;
329 elsif addr = x"000B" then
330 status_data(31 downto 0) <= Serdes_status;
331 elsif addr = x"000C" then
332 status_data(31 downto 0) <= Retransmit_counter;
333 elsif addr = x"000D" then
334 status_data(31 downto 0) <= FED_CRC_error_cnt;
339 -- retransmit counter
340 process(Greset_CLK,clock)
342 if Greset_CLK = '0' then
343 Retransmit_counter <= (others => '0');
344 elsif rising_edge(clock) then
345 if retransmit_ena = '1' then
346 Retransmit_counter <= Retransmit_counter + '1';
351 -- local Event generator used to test the link
352 generator_inst:if generator generate
356 low_clk => clock,
-- frequency of ??? Mhz
358 PCIe_func => func
(15 downto 0),
361 PCIe_dto => PCIe_dto,
362 PCIe_cs => sel_test_mode,
367 Back_p => backpressure_mux
372 --******************************************************************************
373 -- multiplexer for event DATA
374 -- mux external (FED) and local data path (Event generator) ********************
376 wen_mux <= wen_tm when rsyc_test_mode(1) = '1' and generator else not(LinkWe);
377 data_mux <= data_tm when rsyc_test_mode(1) = '1' and generator else LinkData;
378 uctrl_mux <= uctrl_tm when rsyc_test_mode(1) = '1' and generator else LinkCtrl;
380 --******************************************************************************
381 process(Greset_sysCLK,sys_clk)
383 if Greset_sysCLK = '0' then
384 data_counter <= (others => '0');
385 elsif rising_edge(sys_clk) then
386 if wen_mux = '1' then
387 data_counter <= data_counter + '1';
392 --indicate the last word of the EVENT
393 end_frag <= '1' when data_mux(63 downto 60) = x"A" and uctrl_mux = '0' else '0';
395 -- pulse to count the number of event dicover
396 process(Greset_sysCLK,sys_clk)
398 if Greset_sysCLK = '0' then
400 elsif rising_edge(sys_clk) then
402 if end_frag = '1' then
408 -- internal FIFO used to chnage the DATA clock domaine
412 aclr => Greset_sysCLK,
415 dataw
(63 downto 0) => data_mux,
416 dataw
(64) => uctrl_mux ,
417 dataw
(65) => end_frag ,
418 almost_f => backpressure_mux ,
426 -- LinkAlmostFull LFF is valid only in no TEST mode otherwise ALLTIME active (low)
427 Backpressure <= '0' when rsyc_test_mode(1) = '1' else backpressure_mux;
428 LinkAlmostFull <= Backpressure;
430 --******************************************************************************
431 -- -******* This state machine is used to read the FIFO and fill the blocks in the CORE_LOGIC.VHD file
432 --state machine clock
433 FED_itf_state_clk:
process(Greset_CLK,clock)
435 if Greset_CLK = '0' then
437 elsif rising_edge(clock) then
438 fill_blk <= fill_blkNext;
442 FED_itf_state_machine:
process(fill_blk,empt_ff,block_free,blk_full,last_word)
444 fill_blkNext <= fill_blk;
445 state_machine_status <= (others => '0');
447 -- wait data and free block in CORE_LOGIC.VHD
450 state_machine_status(0) <='1';
451 if empt_ff = '0' and block_free = '1' then
452 fill_blkNext <= read_fifo;
455 -- continue until the last word of the EVENT or until no free BLOCK
457 state_machine_status(1) <='1';
458 if blk_full = '1' or last_word = '1' then --stop_evt_mem = '1' then
459 fill_blkNext <= update_para;
462 -- unpdate flags and indicate end of block (block full or end_of_event)
464 state_machine_status(2) <='1';
465 fill_blkNext <= dummy_a;
468 fill_blkNext <= dummy_b;
471 fill_blkNext <= dummy_c;
-- take 3 clock
to finish
to clsoe the
buffer,
if no the block_free value can be wrong
474 fill_blkNext <= idle;
477 fill_blkNext <= idle;
480 --******************************************************************************
482 last_word <= '1' when rd_ff_reg = '1' and datar(65) = '1' else '0';
484 G_rst_rd <= '0' when Greset_CLK = '0' or empt_ff = '1' or blk_full = '1' else '1';
486 -- automatic read FIFO until the the last word of the EVENT or end of block (change state FILL_BLK)
487 process(G_rst_rd,clock)
489 if G_rst_rd = '0' then
491 elsif rising_edge(clock) then
493 if fill_blk = read_fifo and last_word = '0' then
499 --******************************************************************************
501 process(Greset_CLK,clock)
503 if Greset_CLK = '0' then
506 event_counter <= (others => '0');
507 elsif rising_edge(clock) then
509 if datar(64) = '0' and datar(63 downto 60) = x"A" and rd_ff_reg = '1' then -- UCTRL= 0 + trailer + DATA_valid
510 -- remove the CRC in the trailer to compute the CRC
511 data_r_crc(63 downto 32) <= datar(63 downto 32);
512 data_r_crc(31 downto 16) <= (others => '0');
513 data_r_crc(15 downto 0) <= datar(15 downto 0);
515 data_r_crc <= datar(63 downto 00);
518 datar_reg <= datar(63 downto 00);
520 -- create the envelop of the event + counter status
521 if datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
522 event_counter <= event_counter + '1';
525 -- specify the place of the Trailer
526 ena_CRC_reg <= ena_CRC;
529 if datar(64) = '0' and datar(63 downto 60) = x"A" and rd_ff_reg = '1' then
531 crc_frag <= datar(31 downto 16);
534 -- reset the CRC machine between 2 fragments
535 if ena_crc = '1' then
537 elsif datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
554 -- compare the CRC received and the CRC computed
555 crc_check <= '0' when crc_cmp = crc_frag else '1';
557 -- count number of FED crc error
558 process(Greset_CLK,clock)
560 if Greset_CLK = '0' then
561 FED_CRC_error_cnt <= (others => '0');
562 elsif rising_edge(clock) then
563 if ena_CRC_reg = '1' and crc_check = '1' then
564 FED_CRC_error_cnt <= FED_CRC_error_cnt + '1';
569 -- generate FLAG to indicate the beginning and the end of the event for each BLOCK
570 process(Greset_CLK,clock)
572 if Greset_CLK = '0' then
573 start_evt_mem <= '0';
575 elsif rising_edge(clock) then
576 if datar(64) = '0' and datar(63 downto 60) = x"5" and rd_ff_reg = '1' then
577 start_evt_mem <= '1';
578 elsif last_word = '1' then
580 elsif fill_blk = update_para then --finish_blk = '1' then
581 start_evt_mem <= '0';
587 -- compute the size of valid data in the BLOCK
588 process(Greset_CLK,clock)
590 if Greset_CLK = '0' then
591 blk_size <= (others => '0');
592 elsif rising_edge(clock) then
593 if fill_blk = idle then
594 blk_size <= (others => '0');
595 elsif rd_ff_reg = '1' and blk_full = '0' then
596 blk_size <= blk_size + '1';
601 -- count the number of block used
602 process(Greset_CLK,clock)
604 if Greset_CLK = '0' then
605 block_counter <= (others => '0');
606 elsif rising_edge(clock) then
607 if blk_full = '1' or last_word = '1' then
608 block_counter <= block_counter + '1';
613 --flag when the BLOCK is full
614 process(Greset_CLK,clock)
616 if Greset_CLK = '0' then
618 elsif rising_edge(clock) then
619 if blk_size = x"01FF" and rd_ff_reg = '1' then --blk_size = 0x200
621 elsif End_pckt_lgc = '1' then
627 End_pckt_lgc <= '1' when fill_blk = update_para else '0';
629 --Pipe data for the CRC check
633 if rising_edge(clock) then
634 datar_rreg(63 downto 0) <= datar_reg(63 downto 0);
635 blk_size_reg <= blk_size;
636 start_evt_mem_reg <= start_evt_mem;
637 stop_evt_mem_reg <= stop_evt_mem;
638 End_pckt_lgc_reg <= End_pckt_lgc;
643 data_out(63 downto 32) <= datar_rreg(63 downto 32);
644 data_out(31 downto 16) <= crc_cmp when ena_CRC_reg = '1' else datar_rreg(31 downto 16);
645 data_out(15 downto 3) <= datar_rreg(15 downto 3);
646 data_out(2) <= crc_check when ena_CRC_reg = '1' else datar_rreg(2);
647 data_out(1 downto 0) <= datar_rreg(1 downto 0) ;
651 if rising_edge(clock) then
652 del_rd_ff(1) <= del_rd_ff(0);
653 del_rd_ff(0) <= rd_ff_reg;
657 --Output value to Optical interface
658 block_sz_fed <= blk_size_reg;
-- number of data in the block ready to send
659 data_fed <= data_out;
660 wr_ena <= del_rd_ff(1);
661 start_evt <= start_evt_mem_reg;
-- flag is set if this block is the first of the event
662 stop_evt <= stop_evt_mem_reg;
-- flag is set if this block is the last of the event
663 end_blk_fed <= End_pckt_lgc_reg;
-- flag is set at the end of the event