1 ------------------------------------------------------------------------------- 2 -- File : SsiPrbsRx.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2014-04-02 5 -- Last update: 2016-10-25 6 ------------------------------------------------------------------------------- 7 -- Description: This module generates 8 -- PseudoRandom Binary Sequence (PRBS) on Virtual Channel Lane. 9 ------------------------------------------------------------------------------- 10 -- This file is part of 'SLAC Firmware Standard Library'. 11 -- It is subject to the license terms in the LICENSE.txt file found in the 12 -- top-level directory of this distribution and at: 13 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 14 -- No part of 'SLAC Firmware Standard Library', including this file, 15 -- may be copied, modified, propagated, or distributed except according to 16 -- the terms contained in the LICENSE.txt file. 17 ------------------------------------------------------------------------------- 20 use ieee.std_logic_1164.
all;
21 use ieee.std_logic_unsigned.
all;
22 use ieee.std_logic_arith.
all;
30 --! @ingroup protocols_ssi 33 -- General Configurations 37 -- FIFO configurations 50 -- AXI Stream IO Config 56 -- Streaming RX Data Interface (sAxisClk domain) 62 -- Optional: Streaming TX Data Interface (mAxisClk domain) 63 mAxisClk : in sl;
-- Note: a clock must always be applied to this port 67 -- Optional: AXI-Lite Register Interface (axiClk domain) 74 -- Error Detection Signals (sAxisClk domain) 90 constant MAX_CNT_C : slv(31 downto 0) := (others => '1');
92 constant SLAVE_PRBS_SSI_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(PRBS_BYTES_C, TKEEP_COMP_C);
93 constant MASTER_PRBS_SSI_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(PRBS_BYTES_C, TKEEP_COMP_C);
102 type RegType is record 114 txCnt : slv(3 downto 0);
121 dataCnt : slv(31 downto 0);
122 stopTime : slv(31 downto 0);
123 startTime : slv(31 downto 0);
130 constant REG_INIT_C : RegType := ( 157 signal r : RegType := REG_INIT_C;
158 signal rin : RegType;
168 constant STATUS_SIZE_C : positive := 10;
170 type LocRegType is record 172 dummy : slv(31 downto 0);
173 rollOverEn : slv(STATUS_SIZE_C-1 downto 0);
178 constant LOC_REG_INIT_C : LocRegType := ( 185 signal rAxiLite : LocRegType := LOC_REG_INIT_C;
186 signal rinAxiLite : LocRegType;
188 signal errBitStrbSync, 193 errMissedPacketSync : sl;
200 signal packetLengthSync, 203 errWordCntSync : slv(31 downto 0);
218 -- assert (PRBS_SEED_SIZE_G mod 8 = 0) report "PRBS_SEED_SIZE_G must be a multiple of 8" severity failure; 224 -- General Configurations 228 -- FIFO configurations 239 -- AXI Stream Port Configurations 256 comb :
process (r, rxAxisMaster,
sAxisRst, txAxisSlave)
is 258 variable v : RegType;
260 -- Latch the current value 263 -- Set the AXIS configurations 264 v.txAxisMaster.tKeep := (others => '0');
265 v.txAxisMaster.tStrb := (others => '0');
267 v.txAxisMaster.tKeep(i) := '1';
268 v.txAxisMaster.tStrb(i) := '1';
271 -- Reset strobe signals 273 v.txAxisMaster.tValid := '0';
274 v.txAxisMaster.tLast := '0';
275 v.txAxisMaster.tUser := (others => '0');
276 v.errWordStrb := '0';
279 -- Check for roll over 280 if r.stopTime /= r.startTime then 281 -- Increment the rate counter 282 v.stopTime := r.stopTime + 1;
286 ---------------------------------------------------------------------- 291 -- Ready to receive data 292 v.rxAxisSlave.tReady := '1';
293 -- Check for a FIFO read 294 if (rxAxisMaster.tvalid = '1') and (r.rxAxisSlave.tReady = '1') then 295 -- Calculate the time between this packet and the previous one 296 if (r.stopTime = r.startTime) then 297 v.stopTime := r.stopTime + 1;
300 v.startTime := r.stopTime;
301 -- Reset the error counters 309 -- Check if we have missed a packet 311 -- Set the error flags 315 -- Align the event counter to the next packet 317 -- Latch the SEED for the randomization 319 -- Check for a data bus error 320 -- for i in 4 to AXI_STREAM_CONFIG_G.TDATA_BYTES_C-1 loop 321 -- if anyBits(rxAxisMaster.tData(i*8+7 downto i*8), '1') then 322 -- v.errDataBus := '1'; 323 -- v.errorDet := '1'; 328 -- Increment the counter 329 v.dataCnt := r.dataCnt + 1;
333 ---------------------------------------------------------------------- 335 -- Check for a FIFO read 336 if (rxAxisMaster.tvalid = '1') and (r.rxAxisSlave.tReady = '1') then 337 -- Calculate the next data word 338 v.randomData := lfsrShift(r.randomData, PRBS_TAPS_G);
339 -- Latch the packetLength value 341 -- Check for a data bus error 343 if not allBits(rxAxisMaster.tData(i*8+7 downto i*8), '0') then 348 -- Increment the counter 349 v.dataCnt := r.dataCnt + 1;
353 ---------------------------------------------------------------------- 355 -- Check for a FIFO read 356 if (rxAxisMaster.tvalid = '1') and (r.rxAxisSlave.tReady = '1') then 357 -- Check for a data bus error 358 -- for i in 0 to (AXI_STREAM_CONFIG_G.TDATA_BYTES_C/4)-1 loop 359 -- if rxAxisMaster.tData(31 downto 0) /= rxAxisMaster.tData(i*32+31 downto i*32) then 360 -- v.errDataBus := '1'; 361 -- v.errorDet := '1'; 364 -- Calculate the next data word 365 v.randomData := lfsrShift(r.randomData, PRBS_TAPS_G);
366 -- Check for end of frame 367 if rxAxisMaster.tLast = '1' then 368 -- Set the local eof flag 370 -- Latch the packets eofe flag 371 v.eofe := ssiGetUserEofe(SLAVE_PRBS_SSI_CONFIG_C, rxAxisMaster);
376 -- Check the data packet length 378 -- Wrong length detected 382 v.dataCnt := (others => '0');
383 -- Stop reading the FIFO 384 v.rxAxisSlave.tReady := '0';
386 v.state := SEND_RESULT_S;
387 elsif r.dataCnt /= MAX_CNT_C then 388 -- Increment the counter 389 v.dataCnt := r.dataCnt + 1;
391 -- Compare the data word to calculated data word 393 -- Check for roll over 396 v.errWordStrb := '1';
398 -- Increment the word error counter 401 -- Latch the bits with error 403 -- Stop reading the FIFO 404 v.rxAxisSlave.tReady := '0';
406 v.state := BIT_ERR_S;
409 ---------------------------------------------------------------------- 411 -- Increment the counter 412 v.bitPntr := r.bitPntr + 1;
413 -- Check for an error bit 414 if r.errorBits(conv_integer(r.bitPntr)) = '1' then 415 -- Check for roll over 420 -- Increment the bit error counter 424 -- Check the bit pointer 427 v.bitPntr := (others => '0');
428 -- Check if there was an eof flag 431 v.state := SEND_RESULT_S;
433 -- Ready for more data 434 v.rxAxisSlave.tReady := '1';
439 ---------------------------------------------------------------------- 440 when SEND_RESULT_S => 441 -- Check the upstream buffer status 442 if txAxisSlave.tReady = '1' then 444 v.txAxisMaster.tValid := '1';
445 -- Increment the data counter 446 v.txCnt := r.txCnt + 1;
447 -- Send data w.r.t. the counter 450 -- Update strobe for the results 452 -- Write the data to the TX virtual channel 453 v.txAxisMaster.tData(31 downto 16) := x"FFFF";
-- static pattern for software alignment 454 v.txAxisMaster.tData(15 downto 0) := (others => '0');
465 v.txCnt := (others => '0');
466 -- Send the last word 467 v.txAxisMaster.tLast := '1';
468 v.txAxisMaster.tData(31 downto 4) := (others => '0');
473 -- Ready to receive data 474 v.rxAxisSlave.tReady := '1';
475 -- Reset the busy flag 481 ---------------------------------------------------------------------- 489 -- Register the variable for next clock cycle 493 rxAxisSlave <= r.rxAxisSlave;
494 txAxisMaster <= r.txAxisMaster;
512 r <= rin after TPD_G;
518 -- General Configurations 522 -- FIFO configurations 533 -- AXI Stream Port Configurations 554 wr_en => r.updatedResults,
556 din
(31 downto 0) => r.packetLength,
557 din
(63 downto 32) => r.packetRate,
558 din
(95 downto 64) => r.errbitCnt,
559 din
(127 downto 96) => r.errWordCnt,
561 dout
(31 downto 0) => packetLengthSync,
562 dout
(63 downto 32) => packetRateSync,
563 dout
(95 downto 64) => errbitCntSync,
564 dout
(127 downto 96) => errWordCntSync
);
575 -- Input Status bit Signals (wrClk domain) 576 statusIn
(9) => axisCtrl
(1).
pause,
577 statusIn
(8) => axisCtrl
(1).
overflow,
578 statusIn
(7) => axisCtrl
(0).
pause,
579 statusIn
(6) => axisCtrl
(0).
overflow,
580 statusIn
(5) => r.errBitStrb,
581 statusIn
(4) => r.errWordStrb,
582 statusIn
(3) => r.errDataBus,
583 statusIn
(2) => r.eofe,
584 statusIn
(1) => r.errLength,
585 statusIn
(0) => r.errMissedPacket,
586 -- Output Status bit Signals (rdClk domain) 587 statusOut
(9) =>
pause(1),
589 statusOut
(7) =>
pause(0),
591 statusOut
(5) => errBitStrbSync,
592 statusOut
(4) => errWordStrbSync,
593 statusOut
(3) => errDataBusSync,
594 statusOut
(2) => errEofeSync,
595 statusOut
(1) => errLengthSync,
596 statusOut
(0) => errMissedPacketSync,
597 -- Status Bit Counters Signals (rdClk domain) 601 -- Clocks and Reset Ports 605 pause1Cnt <= muxSlVectorArray(cntOut, 9);
606 overflow1Cnt <= muxSlVectorArray(cntOut, 8);
607 pause0Cnt <= muxSlVectorArray(cntOut, 7);
608 overflow0Cnt <= muxSlVectorArray(cntOut, 6);
609 errBitStrbCnt <= muxSlVectorArray(cntOut, 5);
610 errWordStrbCnt <= muxSlVectorArray(cntOut, 4);
611 errDataBusCnt <= muxSlVectorArray(cntOut, 3);
612 errEofeCnt <= muxSlVectorArray(cntOut, 2);
613 errLengthCnt <= muxSlVectorArray(cntOut, 1);
614 errMissedPacketCnt <= muxSlVectorArray(cntOut, 0);
616 ------------------------------- 617 -- Configuration Register 618 ------------------------------- 620 errDataBusCnt, errDataBusSync, errEofeCnt, errEofeSync, errLengthCnt,
621 errLengthSync, errMissedPacketCnt, errMissedPacketSync, errWordCntSync,
622 errWordStrbCnt, errWordStrbSync, errbitCntSync,
overflow, overflow0Cnt,
623 overflow1Cnt, packetLengthSync, packetRateSync,
pause, pause0Cnt,
624 pause1Cnt, rAxiLite)
is 625 variable v : LocRegType;
627 variable axiWriteResp : slv(1 downto 0);
628 variable axiReadResp : slv(1 downto 0);
630 -- Latch the current value 633 -- Determine the transaction type 636 -- Reset strobe signals 640 -- Check for an out of 32 bit aligned address 642 -- Decode address and perform write 658 -- Check for an out of 32 bit aligned address 660 -- Decode address and assign read data 718 -- Register the variable for next clock cycle 725 end process combAxiLite;
727 seqAxiLite :
process (
axiClk)
is 729 if rising_edge(axiClk) then 730 rAxiLite <= rinAxiLite after TPD_G;
732 end process seqAxiLite;
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
CASCADE_SIZE_Gnatural range 1 to ( 2** 24):= 1
out sAxisCtrlAxiStreamCtrlType
ALTERA_RAM_Gstring := "M9K"
FIFO_ADDR_WIDTH_Gnatural range 4 to 48:= 9
PIPE_STAGES_Gnatural range 0 to 16:= 1
AxiStreamMasterType :=(tValid => '0',tData =>( others => '0'),tStrb =>( others => '1'),tKeep =>( others => '1'),tLast => '0',tDest =>( others => '0'),tId =>( others => '0'),tUser =>( others => '0')) AXI_STREAM_MASTER_INIT_C
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
USE_BUILT_IN_Gboolean := false
array(natural range <> ,natural range <> ) of sl SlVectorArray
STATUS_CNT_WIDTH_Gnatural range 1 to 32:= 32
SLAVE_AXI_PIPE_STAGES_Gnatural range 0 to 16:= 0
FIFO_FIXED_THRESH_Gboolean := true
FIFO_PAUSE_THRESH_Gnatural range 1 to ( 2** 24):= 2** 8
MASTER_AXI_PIPE_STAGES_Gnatural range 0 to 16:= 0
out axiWriteSlaveAxiLiteWriteSlaveType
natural range 1 to 16 TDATA_BYTES_C
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
GEN_SYNC_FIFO_Gboolean := false
COMMON_CLK_Gboolean := false
out cntOutSlVectorArray ( WIDTH_G- 1 downto 0, CNT_WIDTH_G- 1 downto 0)
XIL_DEVICE_Gstring := "7SERIES"
AxiLiteStatusType axiStatus
out sAxisSlaveAxiStreamSlaveType
out packetLengthslv( 31 downto 0)
CNT_WIDTH_Gpositive := 32
out mAxisMasterAxiStreamMasterType
in sAxisMasterAxiStreamMasterType
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
in mAxisSlaveAxiStreamSlaveType := AXI_STREAM_SLAVE_FORCE_C
ALTERA_RAM_Gstring := "M9K"
out packetRateslv( 31 downto 0)
ALTERA_SYN_Gboolean := false
INT_PIPE_STAGES_Gnatural range 0 to 16:= 0
GEN_SYNC_FIFO_Gboolean := false
array(natural range <> ) of natural NaturalArray
in rollOverEnInslv( WIDTH_G- 1 downto 0) :=( others => '0')
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
in axiWriteMasterAxiLiteWriteMasterType := AXI_LITE_WRITE_MASTER_INIT_C
PRBS_SEED_SIZE_Gnatural range 8 to 128:= 32
out axiReadSlaveAxiLiteReadSlaveType
out errWordCntslv( 31 downto 0)
array(natural range <> ) of AxiStreamCtrlType AxiStreamCtrlArray
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
SLAVE_AXI_STREAM_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 4)
out sAxisCtrlAxiStreamCtrlType
out sAxisSlaveAxiStreamSlaveType
ALTERA_SYN_Gboolean := false
CNT_RST_EDGE_Gboolean := true
AxiLiteReadMasterType :=(araddr =>( others => '0'),arprot =>( others => '0'),arvalid => '0',rready => '1') AXI_LITE_READ_MASTER_INIT_C
PRBS_TAPS_GNaturalArray :=( 0=> 31, 1=> 6, 2=> 2, 3=> 1)
AxiLiteWriteMasterType :=(awaddr =>( others => '0'),awprot =>( others => '0'),awvalid => '0',wdata =>( others => '0'),wstrb =>( others => '1'),wvalid => '0',bready => '1') AXI_LITE_WRITE_MASTER_INIT_C
in sAxisMasterAxiStreamMasterType
out mAxisMasterAxiStreamMasterType
slv( 1 downto 0) := "00" AXI_RESP_OK_C
AxiStreamSlaveType :=(tReady => '1') AXI_STREAM_SLAVE_FORCE_C
out errbitCntslv( 31 downto 0)
in mAxisSlaveAxiStreamSlaveType
CASCADE_SIZE_Ginteger range 1 to ( 2** 24):= 1
USE_BUILT_IN_Gboolean := false
FIFO_PAUSE_THRESH_Ginteger range 1 to ( 2** 24):= 1
in axiReadMasterAxiLiteReadMasterType := AXI_LITE_READ_MASTER_INIT_C
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
XIL_DEVICE_Gstring := "7SERIES"
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
MASTER_AXI_STREAM_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 4)