From 0d29f9370a3a6005debdadeb41ca88ccdd9bde68 Mon Sep 17 00:00:00 2001 From: mmishra9 Date: Mon, 9 Dec 2024 07:46:55 -0800 Subject: [PATCH 01/17] added overflow bit to meta data --- axi/dma/rtl/v2/AxiStreamDmaV2Write.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axi/dma/rtl/v2/AxiStreamDmaV2Write.vhd b/axi/dma/rtl/v2/AxiStreamDmaV2Write.vhd index 7110b2b435..f0e958027a 100644 --- a/axi/dma/rtl/v2/AxiStreamDmaV2Write.vhd +++ b/axi/dma/rtl/v2/AxiStreamDmaV2Write.vhd @@ -443,7 +443,7 @@ begin v.wMaster.wdata(23 downto 16) := r.lastUser; v.wMaster.wdata(15 downto 4) := (others => '0'); v.wMaster.wdata(3) := r.continue; - v.wMaster.wdata(2) := '0'; + v.wMaster.wdata(2) := r.dmaWrTrack.overflow; v.wMaster.wdata(1 downto 0) := r.result; v.wMaster.wstrb := resize(x"FF", 128); From 329c929e85a0ce33176e46b9bf3d79902656766b Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Sun, 22 Dec 2024 13:57:32 -0800 Subject: [PATCH 02/17] exposing gtClkOut for XauiGtyUltraScaleWrapper.vhd --- .../XauiCore/gtyUltraScale+/rtl/XauiGtyUltraScaleWrapper.vhd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ethernet/XauiCore/gtyUltraScale+/rtl/XauiGtyUltraScaleWrapper.vhd b/ethernet/XauiCore/gtyUltraScale+/rtl/XauiGtyUltraScaleWrapper.vhd index 7d46424337..c5532611be 100644 --- a/ethernet/XauiCore/gtyUltraScale+/rtl/XauiGtyUltraScaleWrapper.vhd +++ b/ethernet/XauiCore/gtyUltraScale+/rtl/XauiGtyUltraScaleWrapper.vhd @@ -70,6 +70,7 @@ entity XauiGtyUltraScaleWrapper is -- MGT Clock Port (156.25MHz or 312.5MHz) gtClkP : in sl; gtClkN : in sl; + refClkOut : out sl; -- MGT Ports gtTxP : out slv(3 downto 0); gtTxN : out slv(3 downto 0); @@ -88,6 +89,7 @@ architecture mapping of XauiGtyUltraScaleWrapper is begin phyReady <= linkUp; + gtClkOut <= refClk; U_refClk : IBUFDS_GTE4 port map ( From 4a6b8e9a638ca9e059edea6a6c908c91b32225a4 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Sun, 22 Dec 2024 13:57:49 -0800 Subject: [PATCH 03/17] exposing gtClkOut for GigEthGtyUltraScaleWrapper.vhd --- .../gtyUltraScale+/rtl/GigEthGtyUltraScaleWrapper.vhd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ethernet/GigEthCore/gtyUltraScale+/rtl/GigEthGtyUltraScaleWrapper.vhd b/ethernet/GigEthCore/gtyUltraScale+/rtl/GigEthGtyUltraScaleWrapper.vhd index dacd36c573..601e269566 100644 --- a/ethernet/GigEthCore/gtyUltraScale+/rtl/GigEthGtyUltraScaleWrapper.vhd +++ b/ethernet/GigEthCore/gtyUltraScale+/rtl/GigEthGtyUltraScaleWrapper.vhd @@ -77,6 +77,7 @@ entity GigEthGtyUltraScaleWrapper is gtRefClk : in sl := '0'; gtClkP : in sl := '1'; gtClkN : in sl := '0'; + gtClkOut : out sl; -- Copy of internal MMCM reference clock and Reset refClkOut : out sl; refRstOut : out sl; @@ -122,7 +123,7 @@ begin IB => gtClkN, CEB => '0', ODIV2 => gtClk, - O => open); + O => gtClkOut); BUFG_GT_Inst : BUFG_GT port map ( From 85eb2ad025fcde6c8553717247b7a5797cde5133 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Sun, 22 Dec 2024 19:23:41 -0800 Subject: [PATCH 04/17] bug fix --- .../XauiCore/gtyUltraScale+/rtl/XauiGtyUltraScaleWrapper.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethernet/XauiCore/gtyUltraScale+/rtl/XauiGtyUltraScaleWrapper.vhd b/ethernet/XauiCore/gtyUltraScale+/rtl/XauiGtyUltraScaleWrapper.vhd index c5532611be..968aac668e 100644 --- a/ethernet/XauiCore/gtyUltraScale+/rtl/XauiGtyUltraScaleWrapper.vhd +++ b/ethernet/XauiCore/gtyUltraScale+/rtl/XauiGtyUltraScaleWrapper.vhd @@ -70,7 +70,7 @@ entity XauiGtyUltraScaleWrapper is -- MGT Clock Port (156.25MHz or 312.5MHz) gtClkP : in sl; gtClkN : in sl; - refClkOut : out sl; + gtClkOut : out sl; -- MGT Ports gtTxP : out slv(3 downto 0); gtTxN : out slv(3 downto 0); From 964207398b781675e7c6ca6979ebe75292d2a001 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 6 Jan 2025 08:06:19 -0800 Subject: [PATCH 05/17] Update LICENSE.txt ### Description - Updating for CY2025 --- LICENSE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.txt b/LICENSE.txt index 9aa129c6fb..8b0998b142 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,5 +1,5 @@ -Copyright (c) 2024, The Board of Trustees of the Leland Stanford Junior +Copyright (c) 2025, The Board of Trustees of the Leland Stanford Junior University, through SLAC National Accelerator Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. Redistribution and use in source and binary forms, with or without From 5d91117ef7a997b2048a8609c0e1ddee32737244 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Tue, 7 Jan 2025 19:43:29 -0800 Subject: [PATCH 06/17] adding EventFrameSequencerMux.vhd --- .../rtl/EventFrameSequencerMux.vhd | 500 ++++++++++++++++++ protocols/event-frame-sequencer/ruckus.tcl | 5 + protocols/ruckus.tcl | 1 + 3 files changed, 506 insertions(+) create mode 100755 protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd create mode 100755 protocols/event-frame-sequencer/ruckus.tcl diff --git a/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd b/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd new file mode 100755 index 0000000000..eaa83f3319 --- /dev/null +++ b/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd @@ -0,0 +1,500 @@ +------------------------------------------------------------------------------- +-- Title : AxiStream BatcherV1 Protocol: https://confluence.slac.stanford.edu/x/hCRXI +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Wrapper on AxiStreamBatcher for multi-AXI stream event building +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiLitePkg.all; +use surf.AxiStreamPkg.all; +use surf.SsiPkg.all; + +entity EventFrameSequencerMux is + generic ( + TPD_G : time := 1 ns; + + -- Number of Inbound AXIS stream SLAVES + NUM_SLAVES_G : positive := 2; + + -- In INDEXED mode, the output TDEST is set based on the selected slave index + -- In ROUTED mode, TDEST is set according to the TDEST_ROUTES_G table + MODE_G : string := "INDEXED"; + + -- In ROUTED mode, an array mapping how TDEST should be assigned for each slave port + -- Each TDEST bit can be set to '0', '1' or '-' for passthrough from slave TDEST. + TDEST_ROUTES_G : Slv8Array := (0 => "--------"); + + -- In INDEXED mode, assign slave index to TDEST at this bit offset + TDEST_LOW_G : integer range 0 to 7 := 0; + + -- Set the TDEST to detect for transition frame + TRANS_TDEST_G : slv(7 downto 0) := x"FF"; + + AXIS_CONFIG_G : AxiStreamConfigType; + INPUT_PIPE_STAGES_G : natural := 0; + OUTPUT_PIPE_STAGES_G : natural := 0); + port ( + -- Clock and Reset + axisClk : in sl; + axisRst : in sl; + -- Misc + blowoffExt : in sl := '0'; + -- AXI-Lite Interface + axilReadMaster : in AxiLiteReadMasterType := AXI_LITE_READ_MASTER_INIT_C; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType := AXI_LITE_WRITE_MASTER_INIT_C; + axilWriteSlave : out AxiLiteWriteSlaveType; + -- AXIS Interfaces + sAxisMasters : in AxiStreamMasterArray(NUM_SLAVES_G-1 downto 0); + sAxisSlaves : out AxiStreamSlaveArray(NUM_SLAVES_G-1 downto 0); + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType); +end entity EventFrameSequencerMux; + +architecture rtl of EventFrameSequencerMux is + + constant DEST_SIZE_C : integer := bitSize(NUM_SLAVES_G-1); + + type StateType is ( + IDLE_S, + MOVE_S); + + type RegType is record + softRst : sl; + hardRst : sl; + blowoffReg : sl; + blowoff : sl; + cntRst : sl; + ready : sl; + sof : sl; + frameCnt : slv(7 downto 0); + numFrames : slv(7 downto 0); + seqCnt : slv(15 downto 0); + bypass : slv(NUM_SLAVES_G-1 downto 0); + dataCnt : Slv32Array(NUM_SLAVES_G-1 downto 0); + transCnt : slv(31 downto 0); + accept : slv(NUM_SLAVES_G-1 downto 0); + transDet : slv(NUM_SLAVES_G-1 downto 0); + skipCh : slv(NUM_SLAVES_G-1 downto 0); + index : natural range 0 to NUM_SLAVES_G-1; + axilReadSlave : AxiLiteReadSlaveType; + axilWriteSlave : AxiLiteWriteSlaveType; + rxSlaves : AxiStreamSlaveArray(NUM_SLAVES_G-1 downto 0); + txMaster : AxiStreamMasterType; + state : StateType; + end record RegType; + + constant REG_INIT_C : RegType := ( + softRst => '0', + hardRst => '0', + blowoffReg => '0', + blowoff => '0', + cntRst => '0', + ready => '0', + sof => '1', + frameCnt => (others => '0'), + numFrames => (others => '0'), + seqCnt => (others => '0'), + bypass => (others => '0'), + dataCnt => (others => (others => '0')), + transCnt => (others => '0'), + accept => (others => '0'), + transDet => (others => '0'), + skipCh => (others => '0'), + index => 0, + axilReadSlave => AXI_LITE_READ_SLAVE_INIT_C, + axilWriteSlave => AXI_LITE_WRITE_SLAVE_INIT_C, + rxSlaves => (others => AXI_STREAM_SLAVE_INIT_C), + txMaster => AXI_STREAM_MASTER_INIT_C, + state => IDLE_S); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal sAxisMastersTmp : AxiStreamMasterArray(NUM_SLAVES_G-1 downto 0); + signal rxMasters : AxiStreamMasterArray(NUM_SLAVES_G-1 downto 0); + signal rxSlaves : AxiStreamSlaveArray(NUM_SLAVES_G-1 downto 0); + signal txMaster : AxiStreamMasterType; + signal txSlave : AxiStreamSlaveType; + +begin + + assert (AXIS_CONFIG_G.TDATA_BYTES_C >= 8) + report "AXIS_CONFIG_G.TDATA_BYTES_C must be >= 8" severity error; + + ------------------------- + -- Override Inbound TDEST + ------------------------- + TDEST_REMAP : process (sAxisMasters) is + variable tmp : AxiStreamMasterArray(NUM_SLAVES_G-1 downto 0); + variable i : natural; + variable j : natural; + begin + tmp := sAxisMasters; + for i in NUM_SLAVES_G-1 downto 0 loop + if MODE_G = "ROUTED" then + for j in 7 downto 0 loop + if (TDEST_ROUTES_G(i)(j) = '1') then + tmp(i).tDest(j) := '1'; + elsif(TDEST_ROUTES_G(i)(j) = '0') then + tmp(i).tDest(j) := '0'; + else + tmp(i).tDest(j) := sAxisMasters(i).tDest(j); + end if; + end loop; + else + tmp(i).tDest(7 downto TDEST_LOW_G) := (others => '0'); + tmp(i).tDest(DEST_SIZE_C+TDEST_LOW_G-1 downto TDEST_LOW_G) := toSlv(i, DEST_SIZE_C); + end if; + end loop; + sAxisMastersTmp <= tmp; + end process; + + ----------------- + -- Input pipeline + ----------------- + GEN_VEC : + for i in (NUM_SLAVES_G-1) downto 0 generate + U_Input : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + PIPE_STAGES_G => INPUT_PIPE_STAGES_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => sAxisMastersTmp(i), + sAxisSlave => sAxisSlaves(i), + mAxisMaster => rxMasters(i), + mAxisSlave => rxSlaves(i)); + end generate GEN_VEC; + + comb : process (axilReadMaster, axilWriteMaster, axisRst, blowoffExt, r, + rxMasters, txSlave) is + variable v : RegType; + variable axilEp : AxiLiteEndPointType; + variable i : natural; + variable dbg : slv(7 downto 0); + begin + -- Latch the current value + v := r; + + -- Update the local variable + dbg := x"00"; + if (v.state = IDLE_S) then + dbg(0) := '0'; + else + dbg(0) := '1'; + end if; + + -- Reset strobes + v.cntRst := '0'; + v.hardRst := '0'; + v.softRst := '0'; + + -- Check for hard reset or soft reset + if (r.hardRst = '1') or (r.softRst = '1') then + -- Reset the register + v := REG_INIT_C; + + -- Preserve the resister configurations + v.bypass := r.bypass; + v.blowoffReg := r.blowoffReg; + + -- Preserve the state of AXI-Lite + v.axilWriteSlave := r.axilWriteSlave; + v.axilReadSlave := r.axilReadSlave; + + end if; + + -- Determine the transaction type + axiSlaveWaitTxn(axilEp, axilWriteMaster, axilReadMaster, v.axilWriteSlave, v.axilReadSlave); + + -- Map the registers + for i in (NUM_SLAVES_G-1) downto 0 loop + axiSlaveRegisterR(axilEp, toSlv(4*i + 0, 12), 0, r.dataCnt(i)); + end loop; + axiSlaveRegisterR(axilEp, x"FBC", 0, r.seqCnt); + axiSlaveRegisterR(axilEp, x"FC0", 0, r.transCnt); + axiSlaveRegisterR(axilEp, x"FC4", 0, TRANS_TDEST_G); + axiSlaveRegister (axilEp, x"FD0", 0, v.bypass); + axiSlaveRegisterR(axilEp, x"FF4", 0, toSlv(NUM_SLAVES_G, 8)); + axiSlaveRegisterR(axilEp, x"FF4", 8, dbg); + axiSlaveRegisterR(axilEp, X"FF4", 16, blowoffExt); + axiSlaveRegister (axilEp, x"FF8", 0, v.blowoffReg); + axiSlaveRegister (axilEp, x"FFC", 0, v.cntRst); + axiSlaveRegister (axilEp, x"FFC", 2, v.hardRst); + axiSlaveRegister (axilEp, x"FFC", 3, v.softRst); + + -- Closeout the transaction + axiSlaveDefault(axilEp, v.axilWriteSlave, v.axilReadSlave, AXI_RESP_DECERR_C); + + -- Combine the external and internal blowoff together + v.blowoff := v.blowoffReg or blowoffExt; + + -- Check for any change to bypass or blowoff 1->0 transition + if (r.bypass /= v.bypass) or ((r.blowoff = '1') and (v.blowoff = '0')) then + -- Perform a soft-reset + v.softRst := '1'; + end if; + + -- Reset the flow control strobes + for i in (NUM_SLAVES_G-1) downto 0 loop + v.rxSlaves(i).tReady := r.bypass(i); + end loop; + if (txSlave.tReady = '1') then + v.txMaster.tValid := '0'; + end if; + + -- State machine + case r.state is + ---------------------------------------------------------------------- + when IDLE_S => + -- Arm the flag + v.ready := '1'; + v.sof := '1'; + + -- Loop through RX channels + for i in (NUM_SLAVES_G-1) downto 0 loop + + -- Check if no data and not bypassing + if (rxMasters(i).tValid = '0') and (r.bypass(i) = '0') then + -- Reset the flags + v.ready := '0'; + v.accept(i) := '0'; + v.transDet(i) := '0'; + else + -- Check if not a transition TDEST + if (rxMasters(i).tDest /= TRANS_TDEST_G) then + -- Normal frame detected + v.accept(i) := not(r.bypass(i)); + v.transDet(i) := '0'; + + -- Else a transitions TDEST + else + -- Transitions frame detected + v.accept(i) := '0'; + v.transDet(i) := not(r.bypass(i)); + + end if; + + end if; + end loop; + + + -- Check if transition detected + if (v.transDet /= 0) then + -- Set the flag + v.ready := '1'; + end if; + + -- Check if ready to move data and not blowing off the data + if (r.ready = '1') and (r.blowoff = '0') then + + -- Check for transition + if (r.transDet /= 0) then + + -- Increment transition counter + v.transCnt := r.transCnt + 1; + + -- Set the number of event frame (zero inclusive) + v.numFrames := x"00"; + + -- Re-write the accept mask + v.accept := r.transDet; + v.skipCh := not(r.transDet); + + else + + for i in (NUM_SLAVES_G-1) downto 0 loop + + -- Increment data counter + if (r.accept(i) = '1') then + v.dataCnt(i) := r.dataCnt(i) + 1; + end if; + + end loop; + + -- Set the number of event frame (zero inclusive) + v.numFrames := resize(onesCount(r.accept), 8) - 1; + + end if; + + -- Next state + v.state := MOVE_S; + + -- Check for blowoff flag + elsif (r.blowoff = '1') then + + -- Blow off the inbound data + for i in (NUM_SLAVES_G-1) downto 0 loop + v.rxSlaves(i).tReady := '1'; + end loop; + + -- Reset the flags + v.ready := '0'; + v.accept := (others => '0'); + v.transDet := (others => '0'); + v.skipCh := (others => '0'); + v.seqCnt := (others => '0'); + + end if; + ---------------------------------------------------------------------- + when MOVE_S => + -- Check for skip channel or bypass on the channel + if (r.skipCh(r.index) = '1') or (r.bypass(r.index) = '1') then + + -- Check for last channel + if (r.index = NUM_SLAVES_G-1) then + -- Next state + v.state := IDLE_S; + else + -- Increment the counter + v.index := r.index + 1; + end if; + + -- Check if ready to move data + elsif (rxMasters(r.index).tValid = '1') and (v.txMaster.tValid = '0') then + + -- Move the data + v.rxSlaves(r.index).tReady := not(r.sof); + v.txMaster := rxMasters(r.index); + + -- Only forward the accepted frames + v.txMaster.tValid := r.accept(r.index); + + -- Check if sending the Event Frame Sequence Header + if (r.sof = '1') then + + -- Reset the flag + v.sof := '0'; + + -- Update the meta-data for a HEADER + v.txMaster.tLast := '0'; + v.txMaster.tKeep := (others => '1'); + v.txMaster.tUser := (others => '0'); + + -- Set SOF flag + ssiSetUserSof(AXIS_CONFIG_G, v.txMaster, '1'); + + -- HEADER context + v.txMaster.tData(7 downto 0) := x"01"; -- Version Field + v.txMaster.tData(15 downto 8) := rxMasters(r.index).tUser(7 downto 0); -- TUSER_FIRST + v.txMaster.tData(23 downto 16) := rxMasters(r.index).tDest; -- TDEST + v.txMaster.tData(31 downto 24) := rxMasters(r.index).tId; -- TID + v.txMaster.tData(39 downto 32) := r.frameCnt; -- Event frame index + v.txMaster.tData(47 downto 40) := r.numFrames; -- Event frame Size (zero inclusive) + v.txMaster.tData(63 downto 48) := r.seqCnt; -- Sequence Counter + + -- Increment frame counter + if (r.accept(r.index) = '1') then + v.frameCnt := r.frameCnt + 1; + end if; + + -- Check for the last transfer + elsif (rxMasters(r.index).tLast = '1') then + + -- Rearm the flag + v.sof := '1'; + + -- Check for last channel + if (r.index = NUM_SLAVES_G-1) then + -- Next state + v.state := IDLE_S; + else + -- Increment the counter + v.index := r.index + 1; + end if; + + end if; + + end if; + ---------------------------------------------------------------------- + end case; + + -- Mask off the TDEST/TID (encoded in header) + v.txMaster.tDest := x"00"; + v.txMaster.tId := x"00"; + + -- Check for state transitioning from MOVE_S to IDLE_S + if (r.state = MOVE_S) and (v.state = IDLE_S) then + + -- Reset the index pointer + v.index := 0; + + -- Reset the flags + v.ready := '0'; + v.accept := (others => '0'); + v.transDet := (others => '0'); + v.skipCh := (others => '0'); + + -- Reset the counter + v.frameCnt := (others => '0'); + + -- Increment frame counter + v.seqCnt := r.seqCnt + 1; + + end if; + + -- Check if reseting counters + if (r.cntRst = '1') then + v.dataCnt := (others => (others => '0')); + v.transCnt := (others => '0'); + end if; + + -- Outputs + rxSlaves <= v.rxSlaves; + txMaster <= r.txMaster; + axilWriteSlave <= r.axilWriteSlave; + axilReadSlave <= r.axilReadSlave; + + -- Reset + if (axisRst = '1') then + v := REG_INIT_C; + end if; + + -- Register the variable for next clock cycle + rin <= v; + + end process comb; + + seq : process (axisClk) is + begin + if (rising_edge(axisClk)) then + r <= rin after TPD_G; + end if; + end process seq; + + ------------------ + -- Output pipeline + ------------------ + U_Output : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + PIPE_STAGES_G => OUTPUT_PIPE_STAGES_G) + port map ( + -- Clock and Reset + axisClk => axisClk, + axisRst => axisRst, + -- AXIS Interfaces + sAxisMaster => txMaster, + sAxisSlave => txSlave, + mAxisMaster => mAxisMaster, + mAxisSlave => mAxisSlave); + +end rtl; diff --git a/protocols/event-frame-sequencer/ruckus.tcl b/protocols/event-frame-sequencer/ruckus.tcl new file mode 100755 index 0000000000..e3e79e21f3 --- /dev/null +++ b/protocols/event-frame-sequencer/ruckus.tcl @@ -0,0 +1,5 @@ +# Load RUCKUS library +source $::env(RUCKUS_PROC_TCL) + +# Load Source Code +loadSource -lib surf -dir "$::DIR_PATH/rtl" diff --git a/protocols/ruckus.tcl b/protocols/ruckus.tcl index f1947918ab..c5af8b74cc 100644 --- a/protocols/ruckus.tcl +++ b/protocols/ruckus.tcl @@ -3,6 +3,7 @@ source $::env(RUCKUS_PROC_TCL) # Load ruckus files loadRuckusTcl "$::DIR_PATH/batcher" +loadRuckusTcl "$::DIR_PATH/event-frame-sequencer" loadRuckusTcl "$::DIR_PATH/hamming-ecc" loadRuckusTcl "$::DIR_PATH/i2c" loadRuckusTcl "$::DIR_PATH/jesd204b" From ed6b10fff1d7401d6ea3badb31399195e619cb76 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Sun, 12 Jan 2025 16:39:26 -0800 Subject: [PATCH 07/17] adding EventFrameSequencerDemux.vhd --- .../rtl/EventFrameSequencerDemux.vhd | 373 ++++++++++++++++++ .../rtl/EventFrameSequencerMux.vhd | 14 +- 2 files changed, 380 insertions(+), 7 deletions(-) create mode 100755 protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd diff --git a/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd b/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd new file mode 100755 index 0000000000..0a6edfd4ee --- /dev/null +++ b/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd @@ -0,0 +1,373 @@ +------------------------------------------------------------------------------- +-- Title : Event Frame Sequencer Protocol: https://confluence.slac.stanford.edu/x/hCRXI +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Event Frame Sequencer DEUX +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiLitePkg.all; +use surf.AxiStreamPkg.all; +use surf.SsiPkg.all; + +entity EventFrameSequencerDemux is + generic ( + TPD_G : time := 1 ns; + NUM_MASTERS_G : positive := 2; + AXIS_CONFIG_G : AxiStreamConfigType; + INPUT_PIPE_STAGES_G : natural := 0; + OUTPUT_PIPE_STAGES_G : natural := 0); + port ( + -- Clock and Reset + axisClk : in sl; + axisRst : in sl; + -- Misc + blowoffExt : in sl := '0'; + -- AXI-Lite Interface + axilReadMaster : in AxiLiteReadMasterType := AXI_LITE_READ_MASTER_INIT_C; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType := AXI_LITE_WRITE_MASTER_INIT_C; + axilWriteSlave : out AxiLiteWriteSlaveType; + -- AXIS Interfaces + sAxisMaster : in AxiStreamMasterType; + sAxisSlave : out AxiStreamSlaveType; + mAxisMasters : out AxiStreamMasterArray(NUM_MASTERS_G-1 downto 0); + mAxisSlaves : in AxiStreamSlaveArray(NUM_MASTERS_G-1 downto 0)); +end entity EventFrameSequencerDemux; + +architecture rtl of EventFrameSequencerDemux is + + type StateType is ( + IDLE_S, + MOVE_S); + + type RegType is record + softRst : sl; + hardRst : sl; + blowoffReg : sl; + blowoff : sl; + cntRst : sl; + sof : sl; + frameCnt : slv(7 downto 0); + numFrames : slv(7 downto 0); + seqCnt : slv(15 downto 0); + dataCnt : Slv32Array(NUM_MASTERS_G-1 downto 0); + dropCnt : slv(31 downto 0); + index : natural range 0 to NUM_MASTERS_G-1; + tUserFirst : slv(7 downto 0); + tDest : slv(7 downto 0); + axilReadSlave : AxiLiteReadSlaveType; + axilWriteSlave : AxiLiteWriteSlaveType; + rxSlave : AxiStreamSlaveType; + txMasters : AxiStreamMasterArray(NUM_MASTERS_G-1 downto 0); + state : StateType; + end record RegType; + + constant REG_INIT_C : RegType := ( + softRst => '0', + hardRst => '0', + blowoffReg => '0', + blowoff => '0', + cntRst => '0', + sof => '1', + frameCnt => (others => '0'), + numFrames => (others => '0'), + seqCnt => (others => '0'), + dataCnt => (others => (others => '0')), + dropCnt => (others => '0'), + index => 0, + tUserFirst => (others => '0'), + tDest => (others => '0'), + axilReadSlave => AXI_LITE_READ_SLAVE_INIT_C, + axilWriteSlave => AXI_LITE_WRITE_SLAVE_INIT_C, + rxSlave => AXI_STREAM_SLAVE_INIT_C, + txMasters => (others => AXI_STREAM_MASTER_INIT_C), + state => IDLE_S); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal rxMaster : AxiStreamMasterType; + signal rxSlave : AxiStreamSlaveType; + signal txMasters : AxiStreamMasterArray(NUM_MASTERS_G-1 downto 0); + signal txSlaves : AxiStreamSlaveArray(NUM_MASTERS_G-1 downto 0); + +begin + + assert (AXIS_CONFIG_G.TDATA_BYTES_C >= 8) + report "AXIS_CONFIG_G.TDATA_BYTES_C must be >= 8" severity error; + + ----------------- + -- Input pipeline + ----------------- + U_Input : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + PIPE_STAGES_G => INPUT_PIPE_STAGES_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => sAxisMaster, + sAxisSlave => sAxisSlave, + mAxisMaster => rxMaster, + mAxisSlave => rxSlave); + + comb : process (axilReadMaster, axilWriteMaster, axisRst, blowoffExt, r, + rxMaster, txSlaves) is + variable v : RegType; + variable axilEp : AxiLiteEndPointType; + variable validHdr : sl; + variable dbg : slv(7 downto 0); + begin + -- Latch the current value + v := r; + + -- Update the local variable + dbg := x"00"; + if (v.state = IDLE_S) then + dbg(0) := '0'; + else + dbg(0) := '1'; + end if; + + -- Reset strobes + v.cntRst := '0'; + v.hardRst := '0'; + v.softRst := '0'; + + -- Check for hard reset or soft reset + if (r.hardRst = '1') or (r.softRst = '1') then + -- Reset the register + v := REG_INIT_C; + + -- Preserve the resister configurations + v.blowoffReg := r.blowoffReg; + + -- Preserve the state of AXI-Lite + v.axilWriteSlave := r.axilWriteSlave; + v.axilReadSlave := r.axilReadSlave; + + end if; + + -- Determine the transaction type + axiSlaveWaitTxn(axilEp, axilWriteMaster, axilReadMaster, v.axilWriteSlave, v.axilReadSlave); + + -- Map the registers + for i in (NUM_MASTERS_G-1) downto 0 loop + axiSlaveRegisterR(axilEp, toSlv(4*i + 0, 12), 0, r.dataCnt(i)); + end loop; + axiSlaveRegisterR(axilEp, x"FBC", 0, r.seqCnt); + axiSlaveRegisterR(axilEp, x"FC0", 0, r.dropCnt); + axiSlaveRegisterR(axilEp, x"FF4", 0, toSlv(NUM_MASTERS_G, 8)); + axiSlaveRegisterR(axilEp, x"FF4", 8, dbg); + axiSlaveRegisterR(axilEp, X"FF4", 16, blowoffExt); + axiSlaveRegister (axilEp, x"FF8", 0, v.blowoffReg); + axiSlaveRegister (axilEp, x"FFC", 0, v.cntRst); + axiSlaveRegister (axilEp, x"FFC", 2, v.hardRst); + axiSlaveRegister (axilEp, x"FFC", 3, v.softRst); + + -- Closeout the transaction + axiSlaveDefault(axilEp, v.axilWriteSlave, v.axilReadSlave, AXI_RESP_DECERR_C); + + -- Combine the external and internal blowoff together + v.blowoff := v.blowoffReg or blowoffExt; + + -- Check for any change to blowoff 1->0 transition + if (r.blowoff = '1') and (v.blowoff = '0') then + -- Perform a soft-reset + v.softRst := '1'; + end if; + + -- AXIS flow control + v.rxSlave.tReady := r.blowoff; + for i in (NUM_MASTERS_G-1) downto 0 loop + if (txSlaves(i).tReady = '1') then + v.txMasters(i).tValid := '0'; + end if; + end loop; + + -- Check for SOF + validHdr := ssiGetUserSof(AXIS_CONFIG_G, rxMaster); + + -- Check for EOF + if (rxMaster.tLast = '1') then + validHdr := '0'; + end if; + + -- Check for valid version field + if (rxMaster.tData(7 downto 0) /= x"01") then + validHdr := '0'; + end if; + + if (rxMaster.tData(15 downto 8) >= NUM_MASTERS_G) then + validHdr := '0'; + end if; + + -- Check for valid event frame index + if (rxMaster.tData(24 downto 16) /= r.frameCnt) then + validHdr := '0'; + end if; + + -- Check for valid event frame index + if (rxMaster.tData(63 downto 48) /= r.seqCnt) then + validHdr := '0'; + end if; + + -- State machine + case r.state is + ---------------------------------------------------------------------- + when IDLE_S => + -- Arm the flag + v.sof := '1'; + + -- Check for blowoff flag + if (r.blowoff = '1') then + + -- Reset the flags + v.frameCnt := (others => '0'); + v.seqCnt := (others => '0'); + + elsif (rxMaster.tValid = '1') then + + -- Accept the data + v.rxSlave.tReady := '1'; + + -- Check for valid header + if (validHdr = '1') then + + -- Save the meta-data + v.index := conv_integer(rxMaster.tData(15 downto 8)); + v.numFrames := rxMaster.tData(31 downto 24); + v.tUserFirst := rxMaster.tData(39 downto 32); + v.tDest := rxMaster.tData(47 downto 40); + + -- Next state + v.state := MOVE_S; + + -- Check for the EOF of the dropped frame + elsif (rxMaster.tLast = '1') then + + -- Increment the counter + v.dropCnt := r.dropCnt + 1; + + -- Reset the flags + v.frameCnt := (others => '0'); + v.seqCnt := (others => '0'); + + end if; + + end if; + ---------------------------------------------------------------------- + when MOVE_S => + if (rxMaster.tValid = '1') and (v.txMasters(r.index).tValid = '0') then + + -- Move the data + v.rxSlave.tReady := '1'; + v.txMasters(r.index) := rxMaster; + + -- Update the TDEST field + v.txMasters(r.index).tDest := r.tDest; + + -- Check if sending the TUSER_FIRST + if (r.sof = '1') then + + -- Reset the flag + v.sof := '0'; + + -- Update the tUser for 1st byte + v.txMasters(r.index).tUser(7 downto 0) := r.tUserFirst; + + end if; + + -- Check for the last transfer + if (rxMaster.tLast = '1') then + + -- Next state + v.state := IDLE_S; + + end if; + + end if; + ---------------------------------------------------------------------- + end case; + + -- Check for state transitioning from MOVE_S to IDLE_S + if (r.state = MOVE_S) and (v.state = IDLE_S) then + + -- Increment frame counter + v.frameCnt := r.frameCnt + 1; + v.seqCnt := r.seqCnt + 1; + v.dataCnt(r.index) := r.dataCnt(r.index) + 1; + + -- Check if reseting frame counters + if (r.numFrames = r.frameCnt) then + v.frameCnt := (others => '0'); + end if; + + end if; + + -- Check if reseting status counters + if (r.cntRst = '1') then + v.dataCnt := (others => (others => '0')); + v.dropCnt := (others => '0'); + end if; + + -- Outputs + rxSlave <= v.rxSlave; + txMasters <= r.txMasters; + axilWriteSlave <= r.axilWriteSlave; + axilReadSlave <= r.axilReadSlave; + + -- Reset + if (axisRst = '1') then + v := REG_INIT_C; + end if; + + -- Register the variable for next clock cycle + rin <= v; + + end process comb; + + seq : process (axisClk) is + begin + if (rising_edge(axisClk)) then + r <= rin after TPD_G; + end if; + end process seq; + + ------------------ + -- Output pipeline + ------------------ + GEN_VEC : + for i in (NUM_MASTERS_G-1) downto 0 generate + U_Output : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + PIPE_STAGES_G => OUTPUT_PIPE_STAGES_G) + port map ( + -- Clock and Reset + axisClk => axisClk, + axisRst => axisRst, + -- AXIS Interfaces + sAxisMaster => txMasters(i), + sAxisSlave => txSlaves(i), + mAxisMaster => mAxisMasters(i), + mAxisSlave => mAxisSlaves(i)); + end generate GEN_VEC; + +end rtl; diff --git a/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd b/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd index eaa83f3319..2ee9d834c5 100755 --- a/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd +++ b/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd @@ -1,9 +1,9 @@ ------------------------------------------------------------------------------- --- Title : AxiStream BatcherV1 Protocol: https://confluence.slac.stanford.edu/x/hCRXI +-- Title : Event Frame Sequencer Protocol: https://confluence.slac.stanford.edu/x/hCRXI ------------------------------------------------------------------------------- -- Company : SLAC National Accelerator Laboratory ------------------------------------------------------------------------------- --- Description: Wrapper on AxiStreamBatcher for multi-AXI stream event building +-- Description: Event Frame Sequencer MUX ------------------------------------------------------------------------------- -- This file is part of 'SLAC Firmware Standard Library'. -- It is subject to the license terms in the LICENSE.txt file found in the @@ -394,11 +394,11 @@ begin -- HEADER context v.txMaster.tData(7 downto 0) := x"01"; -- Version Field - v.txMaster.tData(15 downto 8) := rxMasters(r.index).tUser(7 downto 0); -- TUSER_FIRST - v.txMaster.tData(23 downto 16) := rxMasters(r.index).tDest; -- TDEST - v.txMaster.tData(31 downto 24) := rxMasters(r.index).tId; -- TID - v.txMaster.tData(39 downto 32) := r.frameCnt; -- Event frame index - v.txMaster.tData(47 downto 40) := r.numFrames; -- Event frame Size (zero inclusive) + v.txMaster.tData(15 downto 8) := toSlv(r.index, 8); -- MUX Index + v.txMaster.tData(23 downto 16) := r.frameCnt; -- Event frame index + v.txMaster.tData(31 downto 24) := r.numFrames; -- Event frame Size (zero inclusive) + v.txMaster.tData(39 downto 32) := rxMasters(r.index).tUser(7 downto 0); -- TUSER_FIRST + v.txMaster.tData(47 downto 40) := rxMasters(r.index).tDest; -- TDEST v.txMaster.tData(63 downto 48) := r.seqCnt; -- Sequence Counter -- Increment frame counter From f70e5409f3472c682788fbdd1f442b724da5eafe Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 15 Jan 2025 13:24:22 -0800 Subject: [PATCH 08/17] reorg of jtag and Makefile dcp bug fixes --- protocols/ruckus.tcl | 1 - protocols/xvc-udp/dcp/7Series/Makefile | 7 +++++-- protocols/xvc-udp/dcp/7Series/ruckus.tcl | 5 +++-- protocols/xvc-udp/dcp/UltraScale/Makefile | 7 +++++-- protocols/xvc-udp/dcp/UltraScale/ruckus.tcl | 5 +++-- protocols/xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd | 2 +- protocols/{ => xvc-udp}/jtag/rtl/AxiStreamSelector.vhd | 0 protocols/{ => xvc-udp}/jtag/rtl/AxisJtagDebugBridge.vhd | 0 protocols/{ => xvc-udp}/jtag/rtl/AxisToJtag.vhd | 0 protocols/{ => xvc-udp}/jtag/rtl/AxisToJtagCore.vhd | 0 protocols/{ => xvc-udp}/jtag/rtl/AxisToJtagPkg.vhd | 0 protocols/{ => xvc-udp}/jtag/rtl/JtagSerDesCore.vhd | 0 protocols/{ => xvc-udp}/jtag/ruckus.tcl | 0 protocols/{ => xvc-udp}/jtag/tb/AxiStreamSelectorTb.vhd | 0 protocols/{ => xvc-udp}/jtag/tb/AxisToJtagCoreTb.vhd | 0 protocols/{ => xvc-udp}/jtag/tb/AxisToJtagStubTb.vhd | 0 protocols/{ => xvc-udp}/jtag/tb/AxisToJtagTb.vhd | 0 protocols/{ => xvc-udp}/jtag/tb/JtagSerDesCoreTb.vhd | 0 protocols/xvc-udp/ruckus.tcl | 3 +++ 19 files changed, 20 insertions(+), 10 deletions(-) rename protocols/{ => xvc-udp}/jtag/rtl/AxiStreamSelector.vhd (100%) rename protocols/{ => xvc-udp}/jtag/rtl/AxisJtagDebugBridge.vhd (100%) rename protocols/{ => xvc-udp}/jtag/rtl/AxisToJtag.vhd (100%) rename protocols/{ => xvc-udp}/jtag/rtl/AxisToJtagCore.vhd (100%) rename protocols/{ => xvc-udp}/jtag/rtl/AxisToJtagPkg.vhd (100%) rename protocols/{ => xvc-udp}/jtag/rtl/JtagSerDesCore.vhd (100%) rename protocols/{ => xvc-udp}/jtag/ruckus.tcl (100%) rename protocols/{ => xvc-udp}/jtag/tb/AxiStreamSelectorTb.vhd (100%) rename protocols/{ => xvc-udp}/jtag/tb/AxisToJtagCoreTb.vhd (100%) rename protocols/{ => xvc-udp}/jtag/tb/AxisToJtagStubTb.vhd (100%) rename protocols/{ => xvc-udp}/jtag/tb/AxisToJtagTb.vhd (100%) rename protocols/{ => xvc-udp}/jtag/tb/JtagSerDesCoreTb.vhd (100%) diff --git a/protocols/ruckus.tcl b/protocols/ruckus.tcl index f1947918ab..e4b56d4667 100644 --- a/protocols/ruckus.tcl +++ b/protocols/ruckus.tcl @@ -6,7 +6,6 @@ loadRuckusTcl "$::DIR_PATH/batcher" loadRuckusTcl "$::DIR_PATH/hamming-ecc" loadRuckusTcl "$::DIR_PATH/i2c" loadRuckusTcl "$::DIR_PATH/jesd204b" -loadRuckusTcl "$::DIR_PATH/jtag" loadRuckusTcl "$::DIR_PATH/line-codes" loadRuckusTcl "$::DIR_PATH/mdio" loadRuckusTcl "$::DIR_PATH/packetizer" diff --git a/protocols/xvc-udp/dcp/7Series/Makefile b/protocols/xvc-udp/dcp/7Series/Makefile index ae4eab9f7f..9e67e4df61 100644 --- a/protocols/xvc-udp/dcp/7Series/Makefile +++ b/protocols/xvc-udp/dcp/7Series/Makefile @@ -14,6 +14,9 @@ ifeq ($(filter $(VALID_VARIANTS),$(VARIANT)),) $(error "Invalid variant '$(VARIANT)' -- valid variants are: $(VALID_VARIANTS)") endif +# Bypass the XVC_DEBUG during surf/ruckus.tcl loading +export BYPASS_XVC_DEBUG = 1 + # Define Firmware Version Number export PRJ_VERSION = 0x00000001 @@ -26,10 +29,10 @@ export PRJ_PART = XC7Z045FFG900-2 export PROJECT = UdpDebugBridge$(VARIANT) # Override the defaults -export TOP_DIR = $(abspath $(PROJ_DIR)/../../../../) +export TOP_DIR = $(abspath $(PROJ_DIR)/../../../../../../) # Use top level makefile -include ../../../ruckus/system_vivado.mk +include ../../../../../ruckus/system_vivado.mk IMAGES_DIR=$(PROJ_DIR)/$(VARIANT)/images endif diff --git a/protocols/xvc-udp/dcp/7Series/ruckus.tcl b/protocols/xvc-udp/dcp/7Series/ruckus.tcl index bc6d85f11e..36fd2605db 100644 --- a/protocols/xvc-udp/dcp/7Series/ruckus.tcl +++ b/protocols/xvc-udp/dcp/7Series/ruckus.tcl @@ -3,7 +3,8 @@ source $::env(RUCKUS_PROC_TCL) # Load submodules' code and constraints loadRuckusTcl $::env(MODULES)/surf +loadRuckusTcl $::DIR_PATH/../../jtag # Load target's source code and constraints -loadSource -path "$::DIR_PATH/../core/UdpDebugBridgePkg.vhd" -loadSource -path "$::DIR_PATH/../core/UdpDebugBridge$::env(VARIANT)Wrapper.vhd" +loadSource -lib surf -path "$::DIR_PATH/../core/UdpDebugBridgePkg.vhd" +loadSource -lib surf -path "$::DIR_PATH/../core/UdpDebugBridge$::env(VARIANT)Wrapper.vhd" diff --git a/protocols/xvc-udp/dcp/UltraScale/Makefile b/protocols/xvc-udp/dcp/UltraScale/Makefile index 0e2b744743..953e95824c 100644 --- a/protocols/xvc-udp/dcp/UltraScale/Makefile +++ b/protocols/xvc-udp/dcp/UltraScale/Makefile @@ -14,6 +14,9 @@ ifeq ($(filter $(VALID_VARIANTS),$(VARIANT)),) $(error "Invalid variant '$(VARIANT)' -- valid variants are: $(VALID_VARIANTS)") endif +# Bypass the XVC_DEBUG during surf/ruckus.tcl loading +export BYPASS_XVC_DEBUG = 1 + # Define Firmware Version Number export PRJ_VERSION = 0x00000001 @@ -26,10 +29,10 @@ export PRJ_PART = XCKU040-FFVA1156-2-E export PROJECT = UdpDebugBridge$(VARIANT) # Override the defaults -export TOP_DIR = $(abspath $(PROJ_DIR)/../../../../) +export TOP_DIR = $(abspath $(PROJ_DIR)/../../../../../../) # Use top level makefile -include ../../../ruckus/system_vivado.mk +include ../../../../../ruckus/system_vivado.mk IMAGES_DIR=$(PROJ_DIR)/$(VARIANT)/images endif diff --git a/protocols/xvc-udp/dcp/UltraScale/ruckus.tcl b/protocols/xvc-udp/dcp/UltraScale/ruckus.tcl index bc6d85f11e..36fd2605db 100644 --- a/protocols/xvc-udp/dcp/UltraScale/ruckus.tcl +++ b/protocols/xvc-udp/dcp/UltraScale/ruckus.tcl @@ -3,7 +3,8 @@ source $::env(RUCKUS_PROC_TCL) # Load submodules' code and constraints loadRuckusTcl $::env(MODULES)/surf +loadRuckusTcl $::DIR_PATH/../../jtag # Load target's source code and constraints -loadSource -path "$::DIR_PATH/../core/UdpDebugBridgePkg.vhd" -loadSource -path "$::DIR_PATH/../core/UdpDebugBridge$::env(VARIANT)Wrapper.vhd" +loadSource -lib surf -path "$::DIR_PATH/../core/UdpDebugBridgePkg.vhd" +loadSource -lib surf -path "$::DIR_PATH/../core/UdpDebugBridge$::env(VARIANT)Wrapper.vhd" diff --git a/protocols/xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd b/protocols/xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd index 7863d22d1c..c13472cda6 100644 --- a/protocols/xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd +++ b/protocols/xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd @@ -47,7 +47,7 @@ begin U_AxisJtagDebugBridge : entity surf.AxisJtagDebugBridge(AxisJtagDebugBridgeStub) generic map ( - AXIS_FREQ_G => AXIS_CLK_FREQ_C, + AXIS_FREQ_G => AXIS_CLK_FREQ_G, CLK_DIV2_G => XVC_TCLK_DIV2_C, AXIS_WIDTH_G => XVC_AXIS_WIDTH_C, MEM_DEPTH_G => XVC_MEM_DEPTH_C, diff --git a/protocols/jtag/rtl/AxiStreamSelector.vhd b/protocols/xvc-udp/jtag/rtl/AxiStreamSelector.vhd similarity index 100% rename from protocols/jtag/rtl/AxiStreamSelector.vhd rename to protocols/xvc-udp/jtag/rtl/AxiStreamSelector.vhd diff --git a/protocols/jtag/rtl/AxisJtagDebugBridge.vhd b/protocols/xvc-udp/jtag/rtl/AxisJtagDebugBridge.vhd similarity index 100% rename from protocols/jtag/rtl/AxisJtagDebugBridge.vhd rename to protocols/xvc-udp/jtag/rtl/AxisJtagDebugBridge.vhd diff --git a/protocols/jtag/rtl/AxisToJtag.vhd b/protocols/xvc-udp/jtag/rtl/AxisToJtag.vhd similarity index 100% rename from protocols/jtag/rtl/AxisToJtag.vhd rename to protocols/xvc-udp/jtag/rtl/AxisToJtag.vhd diff --git a/protocols/jtag/rtl/AxisToJtagCore.vhd b/protocols/xvc-udp/jtag/rtl/AxisToJtagCore.vhd similarity index 100% rename from protocols/jtag/rtl/AxisToJtagCore.vhd rename to protocols/xvc-udp/jtag/rtl/AxisToJtagCore.vhd diff --git a/protocols/jtag/rtl/AxisToJtagPkg.vhd b/protocols/xvc-udp/jtag/rtl/AxisToJtagPkg.vhd similarity index 100% rename from protocols/jtag/rtl/AxisToJtagPkg.vhd rename to protocols/xvc-udp/jtag/rtl/AxisToJtagPkg.vhd diff --git a/protocols/jtag/rtl/JtagSerDesCore.vhd b/protocols/xvc-udp/jtag/rtl/JtagSerDesCore.vhd similarity index 100% rename from protocols/jtag/rtl/JtagSerDesCore.vhd rename to protocols/xvc-udp/jtag/rtl/JtagSerDesCore.vhd diff --git a/protocols/jtag/ruckus.tcl b/protocols/xvc-udp/jtag/ruckus.tcl similarity index 100% rename from protocols/jtag/ruckus.tcl rename to protocols/xvc-udp/jtag/ruckus.tcl diff --git a/protocols/jtag/tb/AxiStreamSelectorTb.vhd b/protocols/xvc-udp/jtag/tb/AxiStreamSelectorTb.vhd similarity index 100% rename from protocols/jtag/tb/AxiStreamSelectorTb.vhd rename to protocols/xvc-udp/jtag/tb/AxiStreamSelectorTb.vhd diff --git a/protocols/jtag/tb/AxisToJtagCoreTb.vhd b/protocols/xvc-udp/jtag/tb/AxisToJtagCoreTb.vhd similarity index 100% rename from protocols/jtag/tb/AxisToJtagCoreTb.vhd rename to protocols/xvc-udp/jtag/tb/AxisToJtagCoreTb.vhd diff --git a/protocols/jtag/tb/AxisToJtagStubTb.vhd b/protocols/xvc-udp/jtag/tb/AxisToJtagStubTb.vhd similarity index 100% rename from protocols/jtag/tb/AxisToJtagStubTb.vhd rename to protocols/xvc-udp/jtag/tb/AxisToJtagStubTb.vhd diff --git a/protocols/jtag/tb/AxisToJtagTb.vhd b/protocols/xvc-udp/jtag/tb/AxisToJtagTb.vhd similarity index 100% rename from protocols/jtag/tb/AxisToJtagTb.vhd rename to protocols/xvc-udp/jtag/tb/AxisToJtagTb.vhd diff --git a/protocols/jtag/tb/JtagSerDesCoreTb.vhd b/protocols/xvc-udp/jtag/tb/JtagSerDesCoreTb.vhd similarity index 100% rename from protocols/jtag/tb/JtagSerDesCoreTb.vhd rename to protocols/xvc-udp/jtag/tb/JtagSerDesCoreTb.vhd diff --git a/protocols/xvc-udp/ruckus.tcl b/protocols/xvc-udp/ruckus.tcl index 73c8578d5e..69e87ec99d 100644 --- a/protocols/xvc-udp/ruckus.tcl +++ b/protocols/xvc-udp/ruckus.tcl @@ -4,6 +4,9 @@ source $::env(RUCKUS_PROC_TCL) if { [isVersal] == true } { set versalType true +} elseif { [info exists ::env(BYPASS_XVC_DEBUG)] == 1 && $::env(BYPASS_XVC_DEBUG) == 1 } { + puts "Note: BYPASS_XVC_DEBUG = 1" + # Check for version 2018.3 of Vivado (or later) } elseif { $::env(VIVADO_VERSION) >= 2018.3 } { From cb84530f497eff4f4976a41ec8f8812cc34e00ac Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 15 Jan 2025 18:22:59 -0800 Subject: [PATCH 09/17] adding a USE_XVC_DEBUG_IP_CORE option --- .../dcp/core/UdpDebugBridgeWrapper.vhd | 100 ++++++++++++++++++ .../xvc-udp/rtl/UdpDebugBridgeWrapper.vhd | 4 +- protocols/xvc-udp/ruckus.tcl | 17 ++- 3 files changed, 116 insertions(+), 5 deletions(-) create mode 100755 protocols/xvc-udp/dcp/core/UdpDebugBridgeWrapper.vhd diff --git a/protocols/xvc-udp/dcp/core/UdpDebugBridgeWrapper.vhd b/protocols/xvc-udp/dcp/core/UdpDebugBridgeWrapper.vhd new file mode 100755 index 0000000000..c2ac2dc28d --- /dev/null +++ b/protocols/xvc-udp/dcp/core/UdpDebugBridgeWrapper.vhd @@ -0,0 +1,100 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Wrapper for UDP 'XVC' Server +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiStreamPkg.all; +use surf.SsiPkg.all; +use surf.EthMacPkg.all; + +entity UdpDebugBridgeWrapper is + generic ( + TPD_G : time := 1 ns; + AXIS_CLK_FREQ_G : real := 156.25e6); + port ( + -- Clock and Reset + clk : in sl; + rst : in sl; + -- UDP XVC Interface + obServerMaster : in AxiStreamMasterType; + obServerSlave : out AxiStreamSlaveType; + ibServerMaster : out AxiStreamMasterType; + ibServerSlave : in AxiStreamSlaveType); +end UdpDebugBridgeWrapper; + +architecture rtl of UdpDebugBridgeWrapper is + + type SofRegType is record + sof : sl; + end record SofRegType; + + constant SOF_REG_INIT_C : SofRegType := (sof => '1'); + + signal rSof : SofRegType := SOF_REG_INIT_C; + signal rinSof : SofRegType; + + signal mXvcServerTdo : AxiStreamMasterType; + +begin + + ---------------------------- + -- 'XVC' Server @2542 (modified protocol to work over UDP) + ---------------------------- + P_SOF_COMB : process(ibServerSlave, mXvcServerTdo, rSof) is + variable v : SofRegType; + begin + v := rSof; + if ((mXvcServerTdo.tValid and ibServerSlave.tReady) = '1') then + v.sof := mXvcServerTdo.tLast; + end if; + rinSof <= v; + end process P_SOF_COMB; + + P_SOF_SEQ : process(clk) is + begin + if (rising_edge(clk)) then + if (rst = '1') then + rSof <= SOF_REG_INIT_C after TPD_G; + else + rSof <= rinSof after TPD_G; + end if; + end if; + end process P_SOF_SEQ; + + -- splice in the SOF bit + P_SOF_SPLICE : process(mXvcServerTdo, rSof) is + variable v : AxiStreamMasterType; + begin + v := mXvcServerTdo; + ssiSetUserSof(EMAC_AXIS_CONFIG_C, v, rSof.sof); + ibServerMaster <= v; + end process P_SOF_SPLICE; + + U_XvcServer : entity surf.UdpDebugBridge + generic map ( + AXIS_CLK_FREQ_G => AXIS_CLK_FREQ_G) + port map ( + axisClk => clk, + axisRst => rst, + mAxisReq => obServerMaster, + sAxisReq => obServerSlave, + mAxisTdo => mXvcServerTdo, + sAxisTdo => ibServerSlave); + +end rtl; diff --git a/protocols/xvc-udp/rtl/UdpDebugBridgeWrapper.vhd b/protocols/xvc-udp/rtl/UdpDebugBridgeWrapper.vhd index 39e48f835f..25023a9cbd 100644 --- a/protocols/xvc-udp/rtl/UdpDebugBridgeWrapper.vhd +++ b/protocols/xvc-udp/rtl/UdpDebugBridgeWrapper.vhd @@ -3,11 +3,11 @@ ------------------------------------------------------------------------------- -- Description: Wrapper for UDP 'XVC' Server ------------------------------------------------------------------------------- --- This file is part of 'xvc-udp-debug-bridge'. +-- This file is part of 'SLAC Firmware Standard Library'. -- It is subject to the license terms in the LICENSE.txt file found in the -- top-level directory of this distribution and at: -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. --- No part of 'xvc-udp-debug-bridge', including this file, +-- No part of 'SLAC Firmware Standard Library', including this file, -- may be copied, modified, propagated, or distributed except according to -- the terms contained in the LICENSE.txt file. ------------------------------------------------------------------------------- diff --git a/protocols/xvc-udp/ruckus.tcl b/protocols/xvc-udp/ruckus.tcl index 69e87ec99d..03ed459125 100644 --- a/protocols/xvc-udp/ruckus.tcl +++ b/protocols/xvc-udp/ruckus.tcl @@ -10,8 +10,8 @@ if { [isVersal] == true } { # Check for version 2018.3 of Vivado (or later) } elseif { $::env(VIVADO_VERSION) >= 2018.3 } { - # Load the wrapper source code - loadSource -lib surf -dir "$::DIR_PATH/rtl" + # Load the DMA wrapper source code + loadSource -lib surf -path "$::DIR_PATH/rtl/DmaXvcWrapper.vhd" # Get the family type set family [getFpgaArch] @@ -34,6 +34,7 @@ if { [isVersal] == true } { } if { [info exists ::env(USE_XVC_DEBUG)] != 1 || $::env(USE_XVC_DEBUG) == 0 } { + loadSource -lib surf -path "$::DIR_PATH/rtl/UdpDebugBridgeWrapper.vhd" loadSource -lib surf -path "$::DIR_PATH/dcp/${dirType}/Stub/images/UdpDebugBridge.dcp" } elseif { $::env(USE_XVC_DEBUG) == -1 } { @@ -42,8 +43,18 @@ if { [isVersal] == true } { puts "and it is the application's responsibility" puts "to define a suitable implementation." - } else { + } elseif { [info exists ::env(USE_XVC_DEBUG_IP_CORE)] != 1 || $::env(USE_XVC_DEBUG_IP_CORE) == 0 } { + + loadSource -lib surf -path "$::DIR_PATH/rtl/UdpDebugBridgeWrapper.vhd" loadSource -lib surf -path "$::DIR_PATH/dcp/${dirType}/Impl/images/UdpDebugBridge.dcp" + + } else { + + loadRuckusTcl $::DIR_PATH/jtag + loadSource -lib surf -path "$::DIR_PATH/dcp/core/UdpDebugBridgePkg.vhd" + loadSource -lib surf -path "$::DIR_PATH/dcp/core/UdpDebugBridgeImplWrapper.vhd" + loadSource -lib surf -path "$::DIR_PATH/dcp/core/UdpDebugBridgeWrapper.vhd" + } } else { From 8bb0f14a0190128ce647a81cb65d97dc773b9806 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 15 Jan 2025 19:09:17 -0800 Subject: [PATCH 10/17] moving xvc-udp from protocols to xilinx dir because xilinx specific code --- protocols/ruckus.tcl | 3 +-- xilinx/ruckus.tcl | 1 + {protocols => xilinx}/xvc-udp/README.md | 0 .../xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge.dcp | 0 .../xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.v | 0 .../xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vhd | 0 .../xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vho | 0 {protocols => xilinx}/xvc-udp/dcp/7Series/Makefile | 0 .../xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge.dcp | 0 .../xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.v | 0 .../xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vhd | 0 .../xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vho | 0 {protocols => xilinx}/xvc-udp/dcp/7Series/ruckus.tcl | 0 {protocols => xilinx}/xvc-udp/dcp/7Series/vivado/sources.tcl | 0 .../xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge.dcp | 0 .../xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.v | 0 .../xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vhd | 0 .../xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vho | 0 {protocols => xilinx}/xvc-udp/dcp/UltraScale/Makefile | 0 .../xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge.dcp | 0 .../xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.v | 0 .../xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vhd | 0 .../xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vho | 0 {protocols => xilinx}/xvc-udp/dcp/UltraScale/ruckus.tcl | 0 .../xvc-udp/dcp/UltraScale/vivado/sources.tcl | 0 .../xvc-udp/dcp/core/UdpDebugBridgeImplWrapper.vhd | 0 {protocols => xilinx}/xvc-udp/dcp/core/UdpDebugBridgePkg.vhd | 0 .../xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd | 0 .../xvc-udp/dcp/core/UdpDebugBridgeWrapper.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/rtl/AxiStreamSelector.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/rtl/AxisJtagDebugBridge.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/rtl/AxisToJtag.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/rtl/AxisToJtagCore.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/rtl/AxisToJtagPkg.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/rtl/JtagSerDesCore.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/ruckus.tcl | 0 {protocols => xilinx}/xvc-udp/jtag/tb/AxiStreamSelectorTb.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/tb/AxisToJtagCoreTb.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/tb/AxisToJtagStubTb.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/tb/AxisToJtagTb.vhd | 0 {protocols => xilinx}/xvc-udp/jtag/tb/JtagSerDesCoreTb.vhd | 0 {protocols => xilinx}/xvc-udp/rtl/DmaXvcWrapper.vhd | 0 {protocols => xilinx}/xvc-udp/rtl/UdpDebugBridgeWrapper.vhd | 0 {protocols => xilinx}/xvc-udp/ruckus.tcl | 0 44 files changed, 2 insertions(+), 2 deletions(-) rename {protocols => xilinx}/xvc-udp/README.md (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge.dcp (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.v (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vhd (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vho (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/Makefile (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge.dcp (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.v (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vhd (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vho (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/ruckus.tcl (100%) rename {protocols => xilinx}/xvc-udp/dcp/7Series/vivado/sources.tcl (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge.dcp (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.v (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vhd (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vho (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/Makefile (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge.dcp (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.v (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vhd (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vho (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/ruckus.tcl (100%) rename {protocols => xilinx}/xvc-udp/dcp/UltraScale/vivado/sources.tcl (100%) rename {protocols => xilinx}/xvc-udp/dcp/core/UdpDebugBridgeImplWrapper.vhd (100%) rename {protocols => xilinx}/xvc-udp/dcp/core/UdpDebugBridgePkg.vhd (100%) rename {protocols => xilinx}/xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd (100%) rename {protocols => xilinx}/xvc-udp/dcp/core/UdpDebugBridgeWrapper.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/rtl/AxiStreamSelector.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/rtl/AxisJtagDebugBridge.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/rtl/AxisToJtag.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/rtl/AxisToJtagCore.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/rtl/AxisToJtagPkg.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/rtl/JtagSerDesCore.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/ruckus.tcl (100%) rename {protocols => xilinx}/xvc-udp/jtag/tb/AxiStreamSelectorTb.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/tb/AxisToJtagCoreTb.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/tb/AxisToJtagStubTb.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/tb/AxisToJtagTb.vhd (100%) rename {protocols => xilinx}/xvc-udp/jtag/tb/JtagSerDesCoreTb.vhd (100%) rename {protocols => xilinx}/xvc-udp/rtl/DmaXvcWrapper.vhd (100%) rename {protocols => xilinx}/xvc-udp/rtl/UdpDebugBridgeWrapper.vhd (100%) rename {protocols => xilinx}/xvc-udp/ruckus.tcl (100%) diff --git a/protocols/ruckus.tcl b/protocols/ruckus.tcl index e4b56d4667..f083d0d5ca 100644 --- a/protocols/ruckus.tcl +++ b/protocols/ruckus.tcl @@ -28,5 +28,4 @@ if { $::env(VIVADO_VERSION) > 0.0} { loadRuckusTcl "$::DIR_PATH/pmbus" loadRuckusTcl "$::DIR_PATH/salt" loadRuckusTcl "$::DIR_PATH/spi" - loadRuckusTcl "$::DIR_PATH/xvc-udp" -} \ No newline at end of file +} diff --git a/xilinx/ruckus.tcl b/xilinx/ruckus.tcl index 471bb69da7..541a84ed26 100644 --- a/xilinx/ruckus.tcl +++ b/xilinx/ruckus.tcl @@ -5,6 +5,7 @@ source $::env(RUCKUS_PROC_TCL) if { $::env(VIVADO_VERSION) > 0.0} { # Load the Core loadRuckusTcl "$::DIR_PATH/general" + loadRuckusTcl "$::DIR_PATH/xvc-udp" } else { loadSource -lib surf -path "$::DIR_PATH/general/rtl/SelectIoRxGearboxAligner.vhd" loadSource -lib surf -dir "$::DIR_PATH/dummy" diff --git a/protocols/xvc-udp/README.md b/xilinx/xvc-udp/README.md similarity index 100% rename from protocols/xvc-udp/README.md rename to xilinx/xvc-udp/README.md diff --git a/protocols/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge.dcp b/xilinx/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge.dcp similarity index 100% rename from protocols/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge.dcp rename to xilinx/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge.dcp diff --git a/protocols/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.v b/xilinx/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.v similarity index 100% rename from protocols/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.v rename to xilinx/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.v diff --git a/protocols/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vhd b/xilinx/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vhd similarity index 100% rename from protocols/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vhd rename to xilinx/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vhd diff --git a/protocols/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vho b/xilinx/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vho similarity index 100% rename from protocols/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vho rename to xilinx/xvc-udp/dcp/7Series/Impl/images/UdpDebugBridge_stub.vho diff --git a/protocols/xvc-udp/dcp/7Series/Makefile b/xilinx/xvc-udp/dcp/7Series/Makefile similarity index 100% rename from protocols/xvc-udp/dcp/7Series/Makefile rename to xilinx/xvc-udp/dcp/7Series/Makefile diff --git a/protocols/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge.dcp b/xilinx/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge.dcp similarity index 100% rename from protocols/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge.dcp rename to xilinx/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge.dcp diff --git a/protocols/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.v b/xilinx/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.v similarity index 100% rename from protocols/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.v rename to xilinx/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.v diff --git a/protocols/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vhd b/xilinx/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vhd similarity index 100% rename from protocols/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vhd rename to xilinx/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vhd diff --git a/protocols/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vho b/xilinx/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vho similarity index 100% rename from protocols/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vho rename to xilinx/xvc-udp/dcp/7Series/Stub/images/UdpDebugBridge_stub.vho diff --git a/protocols/xvc-udp/dcp/7Series/ruckus.tcl b/xilinx/xvc-udp/dcp/7Series/ruckus.tcl similarity index 100% rename from protocols/xvc-udp/dcp/7Series/ruckus.tcl rename to xilinx/xvc-udp/dcp/7Series/ruckus.tcl diff --git a/protocols/xvc-udp/dcp/7Series/vivado/sources.tcl b/xilinx/xvc-udp/dcp/7Series/vivado/sources.tcl similarity index 100% rename from protocols/xvc-udp/dcp/7Series/vivado/sources.tcl rename to xilinx/xvc-udp/dcp/7Series/vivado/sources.tcl diff --git a/protocols/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge.dcp b/xilinx/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge.dcp similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge.dcp rename to xilinx/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge.dcp diff --git a/protocols/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.v b/xilinx/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.v similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.v rename to xilinx/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.v diff --git a/protocols/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vhd b/xilinx/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vhd similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vhd rename to xilinx/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vhd diff --git a/protocols/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vho b/xilinx/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vho similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vho rename to xilinx/xvc-udp/dcp/UltraScale/Impl/images/UdpDebugBridge_stub.vho diff --git a/protocols/xvc-udp/dcp/UltraScale/Makefile b/xilinx/xvc-udp/dcp/UltraScale/Makefile similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/Makefile rename to xilinx/xvc-udp/dcp/UltraScale/Makefile diff --git a/protocols/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge.dcp b/xilinx/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge.dcp similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge.dcp rename to xilinx/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge.dcp diff --git a/protocols/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.v b/xilinx/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.v similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.v rename to xilinx/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.v diff --git a/protocols/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vhd b/xilinx/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vhd similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vhd rename to xilinx/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vhd diff --git a/protocols/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vho b/xilinx/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vho similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vho rename to xilinx/xvc-udp/dcp/UltraScale/Stub/images/UdpDebugBridge_stub.vho diff --git a/protocols/xvc-udp/dcp/UltraScale/ruckus.tcl b/xilinx/xvc-udp/dcp/UltraScale/ruckus.tcl similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/ruckus.tcl rename to xilinx/xvc-udp/dcp/UltraScale/ruckus.tcl diff --git a/protocols/xvc-udp/dcp/UltraScale/vivado/sources.tcl b/xilinx/xvc-udp/dcp/UltraScale/vivado/sources.tcl similarity index 100% rename from protocols/xvc-udp/dcp/UltraScale/vivado/sources.tcl rename to xilinx/xvc-udp/dcp/UltraScale/vivado/sources.tcl diff --git a/protocols/xvc-udp/dcp/core/UdpDebugBridgeImplWrapper.vhd b/xilinx/xvc-udp/dcp/core/UdpDebugBridgeImplWrapper.vhd similarity index 100% rename from protocols/xvc-udp/dcp/core/UdpDebugBridgeImplWrapper.vhd rename to xilinx/xvc-udp/dcp/core/UdpDebugBridgeImplWrapper.vhd diff --git a/protocols/xvc-udp/dcp/core/UdpDebugBridgePkg.vhd b/xilinx/xvc-udp/dcp/core/UdpDebugBridgePkg.vhd similarity index 100% rename from protocols/xvc-udp/dcp/core/UdpDebugBridgePkg.vhd rename to xilinx/xvc-udp/dcp/core/UdpDebugBridgePkg.vhd diff --git a/protocols/xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd b/xilinx/xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd similarity index 100% rename from protocols/xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd rename to xilinx/xvc-udp/dcp/core/UdpDebugBridgeStubWrapper.vhd diff --git a/protocols/xvc-udp/dcp/core/UdpDebugBridgeWrapper.vhd b/xilinx/xvc-udp/dcp/core/UdpDebugBridgeWrapper.vhd similarity index 100% rename from protocols/xvc-udp/dcp/core/UdpDebugBridgeWrapper.vhd rename to xilinx/xvc-udp/dcp/core/UdpDebugBridgeWrapper.vhd diff --git a/protocols/xvc-udp/jtag/rtl/AxiStreamSelector.vhd b/xilinx/xvc-udp/jtag/rtl/AxiStreamSelector.vhd similarity index 100% rename from protocols/xvc-udp/jtag/rtl/AxiStreamSelector.vhd rename to xilinx/xvc-udp/jtag/rtl/AxiStreamSelector.vhd diff --git a/protocols/xvc-udp/jtag/rtl/AxisJtagDebugBridge.vhd b/xilinx/xvc-udp/jtag/rtl/AxisJtagDebugBridge.vhd similarity index 100% rename from protocols/xvc-udp/jtag/rtl/AxisJtagDebugBridge.vhd rename to xilinx/xvc-udp/jtag/rtl/AxisJtagDebugBridge.vhd diff --git a/protocols/xvc-udp/jtag/rtl/AxisToJtag.vhd b/xilinx/xvc-udp/jtag/rtl/AxisToJtag.vhd similarity index 100% rename from protocols/xvc-udp/jtag/rtl/AxisToJtag.vhd rename to xilinx/xvc-udp/jtag/rtl/AxisToJtag.vhd diff --git a/protocols/xvc-udp/jtag/rtl/AxisToJtagCore.vhd b/xilinx/xvc-udp/jtag/rtl/AxisToJtagCore.vhd similarity index 100% rename from protocols/xvc-udp/jtag/rtl/AxisToJtagCore.vhd rename to xilinx/xvc-udp/jtag/rtl/AxisToJtagCore.vhd diff --git a/protocols/xvc-udp/jtag/rtl/AxisToJtagPkg.vhd b/xilinx/xvc-udp/jtag/rtl/AxisToJtagPkg.vhd similarity index 100% rename from protocols/xvc-udp/jtag/rtl/AxisToJtagPkg.vhd rename to xilinx/xvc-udp/jtag/rtl/AxisToJtagPkg.vhd diff --git a/protocols/xvc-udp/jtag/rtl/JtagSerDesCore.vhd b/xilinx/xvc-udp/jtag/rtl/JtagSerDesCore.vhd similarity index 100% rename from protocols/xvc-udp/jtag/rtl/JtagSerDesCore.vhd rename to xilinx/xvc-udp/jtag/rtl/JtagSerDesCore.vhd diff --git a/protocols/xvc-udp/jtag/ruckus.tcl b/xilinx/xvc-udp/jtag/ruckus.tcl similarity index 100% rename from protocols/xvc-udp/jtag/ruckus.tcl rename to xilinx/xvc-udp/jtag/ruckus.tcl diff --git a/protocols/xvc-udp/jtag/tb/AxiStreamSelectorTb.vhd b/xilinx/xvc-udp/jtag/tb/AxiStreamSelectorTb.vhd similarity index 100% rename from protocols/xvc-udp/jtag/tb/AxiStreamSelectorTb.vhd rename to xilinx/xvc-udp/jtag/tb/AxiStreamSelectorTb.vhd diff --git a/protocols/xvc-udp/jtag/tb/AxisToJtagCoreTb.vhd b/xilinx/xvc-udp/jtag/tb/AxisToJtagCoreTb.vhd similarity index 100% rename from protocols/xvc-udp/jtag/tb/AxisToJtagCoreTb.vhd rename to xilinx/xvc-udp/jtag/tb/AxisToJtagCoreTb.vhd diff --git a/protocols/xvc-udp/jtag/tb/AxisToJtagStubTb.vhd b/xilinx/xvc-udp/jtag/tb/AxisToJtagStubTb.vhd similarity index 100% rename from protocols/xvc-udp/jtag/tb/AxisToJtagStubTb.vhd rename to xilinx/xvc-udp/jtag/tb/AxisToJtagStubTb.vhd diff --git a/protocols/xvc-udp/jtag/tb/AxisToJtagTb.vhd b/xilinx/xvc-udp/jtag/tb/AxisToJtagTb.vhd similarity index 100% rename from protocols/xvc-udp/jtag/tb/AxisToJtagTb.vhd rename to xilinx/xvc-udp/jtag/tb/AxisToJtagTb.vhd diff --git a/protocols/xvc-udp/jtag/tb/JtagSerDesCoreTb.vhd b/xilinx/xvc-udp/jtag/tb/JtagSerDesCoreTb.vhd similarity index 100% rename from protocols/xvc-udp/jtag/tb/JtagSerDesCoreTb.vhd rename to xilinx/xvc-udp/jtag/tb/JtagSerDesCoreTb.vhd diff --git a/protocols/xvc-udp/rtl/DmaXvcWrapper.vhd b/xilinx/xvc-udp/rtl/DmaXvcWrapper.vhd similarity index 100% rename from protocols/xvc-udp/rtl/DmaXvcWrapper.vhd rename to xilinx/xvc-udp/rtl/DmaXvcWrapper.vhd diff --git a/protocols/xvc-udp/rtl/UdpDebugBridgeWrapper.vhd b/xilinx/xvc-udp/rtl/UdpDebugBridgeWrapper.vhd similarity index 100% rename from protocols/xvc-udp/rtl/UdpDebugBridgeWrapper.vhd rename to xilinx/xvc-udp/rtl/UdpDebugBridgeWrapper.vhd diff --git a/protocols/xvc-udp/ruckus.tcl b/xilinx/xvc-udp/ruckus.tcl similarity index 100% rename from protocols/xvc-udp/ruckus.tcl rename to xilinx/xvc-udp/ruckus.tcl From b6763cee2f0b4513e863ea5ab00ce394fd864a87 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 16 Jan 2025 10:31:24 -0800 Subject: [PATCH 11/17] bug fixes and more diagnostics --- .../rtl/EventFrameSequencerDemux.vhd | 35 +- .../rtl/EventFrameSequencerMux.vhd | 12 +- protocols/event-frame-sequencer/ruckus.tcl | 3 + .../tb/EventFrameSequencerTb.vhd | 365 ++++++++++++++++++ tests/test_EventFrameSequencerTb.py | 199 ++++++++++ 5 files changed, 598 insertions(+), 16 deletions(-) create mode 100755 protocols/event-frame-sequencer/tb/EventFrameSequencerTb.vhd create mode 100755 tests/test_EventFrameSequencerTb.py diff --git a/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd b/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd index 0a6edfd4ee..fc969926d5 100755 --- a/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd +++ b/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd @@ -68,6 +68,7 @@ architecture rtl of EventFrameSequencerDemux is seqCnt : slv(15 downto 0); dataCnt : Slv32Array(NUM_MASTERS_G-1 downto 0); dropCnt : slv(31 downto 0); + simDebug : slv(7 downto 0); index : natural range 0 to NUM_MASTERS_G-1; tUserFirst : slv(7 downto 0); tDest : slv(7 downto 0); @@ -90,6 +91,7 @@ architecture rtl of EventFrameSequencerDemux is seqCnt => (others => '0'), dataCnt => (others => (others => '0')), dropCnt => (others => '0'), + simDebug => (others => '0'), index => 0, tUserFirst => (others => '0'), tDest => (others => '0'), @@ -132,13 +134,15 @@ begin variable v : RegType; variable axilEp : AxiLiteEndPointType; variable validHdr : sl; - variable dbg : slv(7 downto 0); + variable sofDet : sl; + variable dbg : slv(7 downto 0); begin -- Latch the current value v := r; -- Update the local variable - dbg := x"00"; + v.simDebug := (others => '0'); + dbg := (others => '0'); if (v.state = IDLE_S) then dbg(0) := '0'; else @@ -203,29 +207,35 @@ begin -- Check for SOF validHdr := ssiGetUserSof(AXIS_CONFIG_G, rxMaster); + sofDet := ssiGetUserSof(AXIS_CONFIG_G, rxMaster); -- Check for EOF if (rxMaster.tLast = '1') then - validHdr := '0'; + validHdr := '0'; + v.simDebug(0) := ite(r.state = IDLE_S, sofDet, '0'); end if; -- Check for valid version field if (rxMaster.tData(7 downto 0) /= x"01") then - validHdr := '0'; + validHdr := '0'; + v.simDebug(1) := ite(r.state = IDLE_S, sofDet, '0'); end if; if (rxMaster.tData(15 downto 8) >= NUM_MASTERS_G) then - validHdr := '0'; + validHdr := '0'; + v.simDebug(2) := ite(r.state = IDLE_S, sofDet, '0'); end if; -- Check for valid event frame index - if (rxMaster.tData(24 downto 16) /= r.frameCnt) then - validHdr := '0'; + if (rxMaster.tData(23 downto 16) /= r.frameCnt) then + validHdr := '0'; + v.simDebug(3) := ite(r.state = IDLE_S, sofDet, '0'); end if; -- Check for valid event frame index if (rxMaster.tData(63 downto 48) /= r.seqCnt) then - validHdr := '0'; + validHdr := '0'; + v.simDebug(4) := ite(r.state = IDLE_S, sofDet, '0'); end if; -- State machine @@ -309,14 +319,19 @@ begin -- Check for state transitioning from MOVE_S to IDLE_S if (r.state = MOVE_S) and (v.state = IDLE_S) then - -- Increment frame counter + -- Increment counters v.frameCnt := r.frameCnt + 1; - v.seqCnt := r.seqCnt + 1; v.dataCnt(r.index) := r.dataCnt(r.index) + 1; -- Check if reseting frame counters if (r.numFrames = r.frameCnt) then + + -- Increment counter + v.seqCnt := r.seqCnt + 1; + + -- Reset the counter v.frameCnt := (others => '0'); + end if; end if; diff --git a/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd b/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd index 2ee9d834c5..333fe98e31 100755 --- a/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd +++ b/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd @@ -394,24 +394,24 @@ begin -- HEADER context v.txMaster.tData(7 downto 0) := x"01"; -- Version Field - v.txMaster.tData(15 downto 8) := toSlv(r.index, 8); -- MUX Index + v.txMaster.tData(15 downto 8) := toSlv(r.index, 8); -- MUX Index v.txMaster.tData(23 downto 16) := r.frameCnt; -- Event frame index v.txMaster.tData(31 downto 24) := r.numFrames; -- Event frame Size (zero inclusive) v.txMaster.tData(39 downto 32) := rxMasters(r.index).tUser(7 downto 0); -- TUSER_FIRST v.txMaster.tData(47 downto 40) := rxMasters(r.index).tDest; -- TDEST v.txMaster.tData(63 downto 48) := r.seqCnt; -- Sequence Counter - -- Increment frame counter - if (r.accept(r.index) = '1') then - v.frameCnt := r.frameCnt + 1; - end if; - -- Check for the last transfer elsif (rxMasters(r.index).tLast = '1') then -- Rearm the flag v.sof := '1'; + -- Increment frame counter + if (r.accept(r.index) = '1') then + v.frameCnt := r.frameCnt + 1; + end if; + -- Check for last channel if (r.index = NUM_SLAVES_G-1) then -- Next state diff --git a/protocols/event-frame-sequencer/ruckus.tcl b/protocols/event-frame-sequencer/ruckus.tcl index e3e79e21f3..7e52f14a5b 100755 --- a/protocols/event-frame-sequencer/ruckus.tcl +++ b/protocols/event-frame-sequencer/ruckus.tcl @@ -3,3 +3,6 @@ source $::env(RUCKUS_PROC_TCL) # Load Source Code loadSource -lib surf -dir "$::DIR_PATH/rtl" + +# Load Simulation +loadSource -lib surf -sim_only -dir "$::DIR_PATH/tb" diff --git a/protocols/event-frame-sequencer/tb/EventFrameSequencerTb.vhd b/protocols/event-frame-sequencer/tb/EventFrameSequencerTb.vhd new file mode 100755 index 0000000000..081441fa69 --- /dev/null +++ b/protocols/event-frame-sequencer/tb/EventFrameSequencerTb.vhd @@ -0,0 +1,365 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: surf.EventFrameSequencerMux/surf.EventFrameSequencerDemux cocoTB testbed +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiLitePkg.all; +use surf.AxiStreamPkg.all; + +entity EventFrameSequencerTb is + generic ( + -- AXI Stream Configuration + TUSER_WIDTH_G : positive range 8 to 8 := 8; + TID_WIDTH_G : positive range 8 to 8 := 8; + TDEST_WIDTH_G : positive range 8 to 8 := 8; + TDATA_NUM_BYTES_G : positive range 8 to 128 := 8); + port ( + -- Clock and Reset + AXIS_ACLK : in std_logic := '0'; + AXIS_ARESETN : in std_logic := '0'; + -- IP Integrator Slave AXI Stream Interface + S_AXIS0_TVALID : in std_logic := '0'; + S_AXIS0_TDATA : in std_logic_vector((8*TDATA_NUM_BYTES_G)-1 downto 0) := (others => '0'); + S_AXIS0_TSTRB : in std_logic_vector(TDATA_NUM_BYTES_G-1 downto 0) := (others => '0'); + S_AXIS0_TKEEP : in std_logic_vector(TDATA_NUM_BYTES_G-1 downto 0) := (others => '0'); + S_AXIS0_TLAST : in std_logic := '0'; + S_AXIS0_TDEST : in std_logic_vector(TDEST_WIDTH_G-1 downto 0) := (others => '0'); + S_AXIS0_TID : in std_logic_vector(TID_WIDTH_G-1 downto 0) := (others => '0'); + S_AXIS0_TUSER : in std_logic_vector(TUSER_WIDTH_G-1 downto 0) := (others => '0'); + S_AXIS0_TREADY : out std_logic; + -- IP Integrator Slave AXI Stream Interface + S_AXIS1_TVALID : in std_logic := '0'; + S_AXIS1_TDATA : in std_logic_vector((8*TDATA_NUM_BYTES_G)-1 downto 0) := (others => '0'); + S_AXIS1_TSTRB : in std_logic_vector(TDATA_NUM_BYTES_G-1 downto 0) := (others => '0'); + S_AXIS1_TKEEP : in std_logic_vector(TDATA_NUM_BYTES_G-1 downto 0) := (others => '0'); + S_AXIS1_TLAST : in std_logic := '0'; + S_AXIS1_TDEST : in std_logic_vector(TDEST_WIDTH_G-1 downto 0) := (others => '0'); + S_AXIS1_TID : in std_logic_vector(TID_WIDTH_G-1 downto 0) := (others => '0'); + S_AXIS1_TUSER : in std_logic_vector(TUSER_WIDTH_G-1 downto 0) := (others => '0'); + S_AXIS1_TREADY : out std_logic; + -- IP Integrator Master AXI Stream Interface + M_AXIS0_TVALID : out std_logic; + M_AXIS0_TDATA : out std_logic_vector((8*TDATA_NUM_BYTES_G)-1 downto 0); + M_AXIS0_TSTRB : out std_logic_vector(TDATA_NUM_BYTES_G-1 downto 0); + M_AXIS0_TKEEP : out std_logic_vector(TDATA_NUM_BYTES_G-1 downto 0); + M_AXIS0_TLAST : out std_logic; + M_AXIS0_TDEST : out std_logic_vector(TDEST_WIDTH_G-1 downto 0); + M_AXIS0_TID : out std_logic_vector(TID_WIDTH_G-1 downto 0); + M_AXIS0_TUSER : out std_logic_vector(TUSER_WIDTH_G-1 downto 0); + M_AXIS0_TREADY : in std_logic; + -- IP Integrator Master AXI Stream Interface + M_AXIS1_TVALID : out std_logic; + M_AXIS1_TDATA : out std_logic_vector((8*TDATA_NUM_BYTES_G)-1 downto 0); + M_AXIS1_TSTRB : out std_logic_vector(TDATA_NUM_BYTES_G-1 downto 0); + M_AXIS1_TKEEP : out std_logic_vector(TDATA_NUM_BYTES_G-1 downto 0); + M_AXIS1_TLAST : out std_logic; + M_AXIS1_TDEST : out std_logic_vector(TDEST_WIDTH_G-1 downto 0); + M_AXIS1_TID : out std_logic_vector(TID_WIDTH_G-1 downto 0); + M_AXIS1_TUSER : out std_logic_vector(TUSER_WIDTH_G-1 downto 0); + M_AXIS1_TREADY : in std_logic; + -- AXI-Lite Interface + S_AXIL_AWADDR : in std_logic_vector(31 downto 0); + S_AXIL_AWPROT : in std_logic_vector(2 downto 0); + S_AXIL_AWVALID : in std_logic; + S_AXIL_AWREADY : out std_logic; + S_AXIL_WDATA : in std_logic_vector(31 downto 0); + S_AXIL_WSTRB : in std_logic_vector(3 downto 0); + S_AXIL_WVALID : in std_logic; + S_AXIL_WREADY : out std_logic; + S_AXIL_BRESP : out std_logic_vector(1 downto 0); + S_AXIL_BVALID : out std_logic; + S_AXIL_BREADY : in std_logic; + S_AXIL_ARADDR : in std_logic_vector(31 downto 0); + S_AXIL_ARPROT : in std_logic_vector(2 downto 0); + S_AXIL_ARVALID : in std_logic; + S_AXIL_ARREADY : out std_logic; + S_AXIL_RDATA : out std_logic_vector(31 downto 0); + S_AXIL_RRESP : out std_logic_vector(1 downto 0); + S_AXIL_RVALID : out std_logic; + S_AXIL_RREADY : in std_logic); +end EventFrameSequencerTb; + +architecture mapping of EventFrameSequencerTb is + + constant TPD_C : time := 3 ns; + + constant AXIS_CONFIG_C : AxiStreamConfigType := ( + TSTRB_EN_C => true, + TDATA_BYTES_C => TDATA_NUM_BYTES_G, + TDEST_BITS_C => TDEST_WIDTH_G, + TID_BITS_C => TID_WIDTH_G, + TKEEP_MODE_C => TKEEP_COMP_C, + TUSER_BITS_C => TUSER_WIDTH_G, + TUSER_MODE_C => TUSER_FIRST_LAST_C); + + constant AXIL_CONFIG_C : AxiLiteCrossbarMasterConfigArray(1 downto 0) := genAxiLiteConfig(2, x"0000_0000", 20, 16); + + signal axilReadMaster : AxiLiteReadMasterType; + signal axilReadSlave : AxiLiteReadSlaveType; + signal axilWriteMaster : AxiLiteWriteMasterType; + signal axilWriteSlave : AxiLiteWriteSlaveType; + + signal axilReadMasters : AxiLiteReadMasterArray(1 downto 0); + signal axilReadSlaves : AxiLiteReadSlaveArray(1 downto 0); + signal axilWriteMasters : AxiLiteWriteMasterArray(1 downto 0); + signal axilWriteSlaves : AxiLiteWriteSlaveArray(1 downto 0); + + signal axisClk : sl := '0'; + signal axisRst : sl := '0'; + + signal sAxisMasters : AxiStreamMasterArray(1 downto 0) := (others => AXI_STREAM_MASTER_INIT_C); + signal sAxisSlaves : AxiStreamSlaveArray(1 downto 0) := (others => AXI_STREAM_SLAVE_FORCE_C); + + signal axisMaster : AxiStreamMasterType := AXI_STREAM_MASTER_INIT_C; + signal axisSlave : AxiStreamSlaveType := AXI_STREAM_SLAVE_FORCE_C; + + signal mAxisMasters : AxiStreamMasterArray(1 downto 0) := (others => AXI_STREAM_MASTER_INIT_C); + signal mAxisSlaves : AxiStreamSlaveArray(1 downto 0) := (others => AXI_STREAM_SLAVE_FORCE_C); + +begin + + --------------------------------------------------------------------------- + -- Adding Shim Layers for translating between cocoTB and local record types + --------------------------------------------------------------------------- + U_ShimLayerSlave_0 : entity surf.SlaveAxiStreamIpIntegrator + generic map ( + INTERFACENAME => "S_AXIS", + HAS_TLAST => 1, + HAS_TKEEP => 1, + HAS_TSTRB => 1, + HAS_TREADY => 1, + TUSER_WIDTH => TUSER_WIDTH_G, + TID_WIDTH => TID_WIDTH_G, + TDEST_WIDTH => TDEST_WIDTH_G, + TDATA_NUM_BYTES => TDATA_NUM_BYTES_G) + port map ( + -- IP Integrator AXI Stream Interface + S_AXIS_ACLK => AXIS_ACLK, + S_AXIS_ARESETN => AXIS_ARESETN, + S_AXIS_TVALID => S_AXIS0_TVALID, + S_AXIS_TDATA => S_AXIS0_TDATA, + S_AXIS_TSTRB => S_AXIS0_TSTRB, + S_AXIS_TKEEP => S_AXIS0_TKEEP, + S_AXIS_TLAST => S_AXIS0_TLAST, + S_AXIS_TDEST => S_AXIS0_TDEST, + S_AXIS_TID => S_AXIS0_TID, + S_AXIS_TUSER => S_AXIS0_TUSER, + S_AXIS_TREADY => S_AXIS0_TREADY, + -- SURF AXI Stream Interface + axisClk => axisClk, + axisRst => axisRst, + axisMaster => sAxisMasters(0), + axisSlave => sAxisSlaves(0)); + + U_ShimLayerSlave_1 : entity surf.SlaveAxiStreamIpIntegrator + generic map ( + INTERFACENAME => "S_AXIS", + HAS_TLAST => 1, + HAS_TKEEP => 1, + HAS_TSTRB => 1, + HAS_TREADY => 1, + TUSER_WIDTH => TUSER_WIDTH_G, + TID_WIDTH => TID_WIDTH_G, + TDEST_WIDTH => TDEST_WIDTH_G, + TDATA_NUM_BYTES => TDATA_NUM_BYTES_G) + port map ( + -- IP Integrator AXI Stream Interface + S_AXIS_ACLK => AXIS_ACLK, + S_AXIS_ARESETN => AXIS_ARESETN, + S_AXIS_TVALID => S_AXIS1_TVALID, + S_AXIS_TDATA => S_AXIS1_TDATA, + S_AXIS_TSTRB => S_AXIS1_TSTRB, + S_AXIS_TKEEP => S_AXIS1_TKEEP, + S_AXIS_TLAST => S_AXIS1_TLAST, + S_AXIS_TDEST => S_AXIS1_TDEST, + S_AXIS_TID => S_AXIS1_TID, + S_AXIS_TUSER => S_AXIS1_TUSER, + S_AXIS_TREADY => S_AXIS1_TREADY, + -- SURF AXI Stream Interface + axisClk => open, + axisRst => open, + axisMaster => sAxisMasters(1), + axisSlave => sAxisSlaves(1)); + + U_ShimLayerMaster_0 : entity surf.MasterAxiStreamIpIntegrator + generic map ( + INTERFACENAME => "M_AXIS", + HAS_TLAST => 1, + HAS_TKEEP => 1, + HAS_TSTRB => 1, + HAS_TREADY => 1, + TUSER_WIDTH => TUSER_WIDTH_G, + TID_WIDTH => TID_WIDTH_G, + TDEST_WIDTH => TDEST_WIDTH_G, + TDATA_NUM_BYTES => TDATA_NUM_BYTES_G) + port map ( + -- IP Integrator AXI Stream Interface + M_AXIS_ACLK => AXIS_ACLK, + M_AXIS_ARESETN => AXIS_ARESETN, + M_AXIS_TVALID => M_AXIS0_TVALID, + M_AXIS_TDATA => M_AXIS0_TDATA, + M_AXIS_TSTRB => M_AXIS0_TSTRB, + M_AXIS_TKEEP => M_AXIS0_TKEEP, + M_AXIS_TLAST => M_AXIS0_TLAST, + M_AXIS_TDEST => M_AXIS0_TDEST, + M_AXIS_TID => M_AXIS0_TID, + M_AXIS_TUSER => M_AXIS0_TUSER, + M_AXIS_TREADY => M_AXIS0_TREADY, + -- SURF AXI Stream Interface + axisClk => open, + axisRst => open, + axisMaster => mAxisMasters(0), + axisSlave => mAxisSlaves(0)); + + U_ShimLayerMaster_1 : entity surf.MasterAxiStreamIpIntegrator + generic map ( + INTERFACENAME => "M_AXIS", + HAS_TLAST => 1, + HAS_TKEEP => 1, + HAS_TSTRB => 1, + HAS_TREADY => 1, + TUSER_WIDTH => TUSER_WIDTH_G, + TID_WIDTH => TID_WIDTH_G, + TDEST_WIDTH => TDEST_WIDTH_G, + TDATA_NUM_BYTES => TDATA_NUM_BYTES_G) + port map ( + -- IP Integrator AXI Stream Interface + M_AXIS_ACLK => AXIS_ACLK, + M_AXIS_ARESETN => AXIS_ARESETN, + M_AXIS_TVALID => M_AXIS1_TVALID, + M_AXIS_TDATA => M_AXIS1_TDATA, + M_AXIS_TSTRB => M_AXIS1_TSTRB, + M_AXIS_TKEEP => M_AXIS1_TKEEP, + M_AXIS_TLAST => M_AXIS1_TLAST, + M_AXIS_TDEST => M_AXIS1_TDEST, + M_AXIS_TID => M_AXIS1_TID, + M_AXIS_TUSER => M_AXIS1_TUSER, + M_AXIS_TREADY => M_AXIS1_TREADY, + -- SURF AXI Stream Interface + axisClk => open, + axisRst => open, + axisMaster => mAxisMasters(1), + axisSlave => mAxisSlaves(1)); + + U_ShimLayer : entity surf.SlaveAxiLiteIpIntegrator + generic map ( + EN_ERROR_RESP => true, + FREQ_HZ => 100000000, + ADDR_WIDTH => 32) + port map ( + -- IP Integrator AXI-Lite Interface + S_AXI_ACLK => AXIS_ACLK, + S_AXI_ARESETN => AXIS_ARESETN, + S_AXI_AWADDR => S_AXIL_AWADDR, + S_AXI_AWPROT => S_AXIL_AWPROT, + S_AXI_AWVALID => S_AXIL_AWVALID, + S_AXI_AWREADY => S_AXIL_AWREADY, + S_AXI_WDATA => S_AXIL_WDATA, + S_AXI_WSTRB => S_AXIL_WSTRB, + S_AXI_WVALID => S_AXIL_WVALID, + S_AXI_WREADY => S_AXIL_WREADY, + S_AXI_BRESP => S_AXIL_BRESP, + S_AXI_BVALID => S_AXIL_BVALID, + S_AXI_BREADY => S_AXIL_BREADY, + S_AXI_ARADDR => S_AXIL_ARADDR, + S_AXI_ARPROT => S_AXIL_ARPROT, + S_AXI_ARVALID => S_AXIL_ARVALID, + S_AXI_ARREADY => S_AXIL_ARREADY, + S_AXI_RDATA => S_AXIL_RDATA, + S_AXI_RRESP => S_AXIL_RRESP, + S_AXI_RVALID => S_AXIL_RVALID, + S_AXI_RREADY => S_AXIL_RREADY, + -- SURF AXI-Lite Interface + axilClk => open, + axilRst => open, + axilReadMaster => axilReadMaster, + axilReadSlave => axilReadSlave, + axilWriteMaster => axilWriteMaster, + axilWriteSlave => axilWriteSlave); + + U_AXIL_XBAR : entity surf.AxiLiteCrossbar + generic map ( + TPD_G => TPD_C, + NUM_SLAVE_SLOTS_G => 1, + NUM_MASTER_SLOTS_G => 2, + MASTERS_CONFIG_G => AXIL_CONFIG_C) + port map ( + axiClk => axisClk, + axiClkRst => axisRst, + sAxiWriteMasters(0) => axilWriteMaster, + sAxiWriteSlaves(0) => axilWriteSlave, + sAxiReadMasters(0) => axilReadMaster, + sAxiReadSlaves(0) => axilReadSlave, + mAxiWriteMasters => axilWriteMasters, + mAxiWriteSlaves => axilWriteSlaves, + mAxiReadMasters => axilReadMasters, + mAxiReadSlaves => axilReadSlaves); + + --------------------------------------------------------------------------- + -- Design Under Testing (DUT) Modules + --------------------------------------------------------------------------- + + -- Module used on the front end board for sequencing the frames to back end + U_DUT_MUX : entity surf.EventFrameSequencerMux + generic map ( + TPD_G => TPD_C, + NUM_SLAVES_G => 2, + MODE_G => "ROUTED", + TDEST_ROUTES_G => ( + 0 => "0000000-", -- Trig on 0x1, Event on 0x0 + 1 => "00000010"), -- Map PGP[tap] to TDEST 0x2 + TRANS_TDEST_G => X"00", + AXIS_CONFIG_G => AXIS_CONFIG_C) + port map ( + -- Clock and Reset + axisClk => axisClk, + axisRst => axisRst, + -- AXI-Lite Interface (axisClk domain) + axilReadMaster => axilReadMasters(0), + axilReadSlave => axilReadSlaves(0), + axilWriteMaster => axilWriteMasters(0), + axilWriteSlave => axilWriteSlaves(0), + -- AXIS Interfaces + sAxisMasters => sAxisMasters, + sAxisSlaves => sAxisSlaves, + mAxisMaster => axisMaster, + mAxisSlave => axisSlave); + + -- Module used on the back end board (e.g. FPGA PCIe) for decoding + U_DUT_DEMUX : entity surf.EventFrameSequencerDemux + generic map ( + TPD_G => TPD_C, + NUM_MASTERS_G => 2, + AXIS_CONFIG_G => AXIS_CONFIG_C) + port map ( + -- Clock and Reset + axisClk => axisClk, + axisRst => axisRst, + -- AXI-Lite Interface + axilReadMaster => axilReadMasters(1), + axilReadSlave => axilReadSlaves(1), + axilWriteMaster => axilWriteMasters(1), + axilWriteSlave => axilWriteSlaves(1), + -- AXIS Interfaces + sAxisMaster => axisMaster, + sAxisSlave => axisSlave, + mAxisMasters => mAxisMasters, + mAxisSlaves => mAxisSlaves); + +end mapping; diff --git a/tests/test_EventFrameSequencerTb.py b/tests/test_EventFrameSequencerTb.py new file mode 100755 index 0000000000..5add8bee48 --- /dev/null +++ b/tests/test_EventFrameSequencerTb.py @@ -0,0 +1,199 @@ +############################################################################## +## This file is part of 'SLAC Firmware Standard Library'. +## It is subject to the license terms in the LICENSE.txt file found in the +## top-level directory of this distribution and at: +## https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +## No part of 'SLAC Firmware Standard Library', including this file, +## may be copied, modified, propagated, or distributed except according to +## the terms contained in the LICENSE.txt file. +############################################################################## + +# dut_tb +import itertools +import logging +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge +from cocotb.regression import TestFactory + +from cocotbext.axi import AxiStreamFrame, AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiLiteBus, AxiLiteMaster + +# test_EventFrameSequencerTb +from cocotb_test.simulator import run +import pytest +import glob +import os + +# Define a new log level +CUSTOM_LEVEL = 60 +logging.addLevelName(CUSTOM_LEVEL, "CUSTOM") + +def custom(self, message, *args, **kwargs): + if self.isEnabledFor(CUSTOM_LEVEL): + self._log(CUSTOM_LEVEL, message, args, **kwargs) + +# Add the custom level to the logging.Logger class +logging.Logger.custom = custom + +class TB: + def __init__(self, dut): + + # Pointer to DUT object + self.dut = dut + + self.log = logging.getLogger('cocotb.tb') + self.log.setLevel(logging.DEBUG) + + # Start AXIS_ACLK clock (100 MHz) in a separate thread + cocotb.start_soon(Clock(dut.AXIS_ACLK, 10.0, units='ns').start()) + + # Setup the AXI stream source + self.sources = [None for _ in range(2)] + for i in range(2): + self.sources[i] = AxiStreamSource( + bus = AxiStreamBus.from_prefix(dut, f'S_AXIS{i}'), + clock = dut.AXIS_ACLK, + reset = dut.AXIS_ARESETN, + reset_active_level = False, + ) + + # Setup the AXI stream sink + self.sinks = [None for _ in range(2)] + for i in range(2): + self.sinks[i] = AxiStreamSink( + bus = AxiStreamBus.from_prefix(dut, f'M_AXIS{i}'), + clock = dut.AXIS_ACLK, + reset = dut.AXIS_ARESETN, + reset_active_level = False, + ) + + # Create the AXI-Lite Master + self.axil_master = AxiLiteMaster( + bus = AxiLiteBus.from_prefix(dut, 'S_AXIL'), + clock = dut.AXIS_ACLK, + reset = dut.AXIS_ARESETN, + reset_active_level=False) + + async def cycle_reset(self): + self.dut.AXIS_ARESETN.setimmediatevalue(0) + await RisingEdge(self.dut.AXIS_ACLK) + await RisingEdge(self.dut.AXIS_ACLK) + self.dut.AXIS_ARESETN.value = 0 + await RisingEdge(self.dut.AXIS_ACLK) + await RisingEdge(self.dut.AXIS_ACLK) + self.dut.AXIS_ARESETN.value = 1 + await RisingEdge(self.dut.AXIS_ACLK) + await RisingEdge(self.dut.AXIS_ACLK) + +async def run_test(dut): + + tb = TB(dut) + await tb.cycle_reset() + + # Byte sweeping to check for corner cases + for x in range(8): + + # Generate the transition data frame + trans_frame = AxiStreamFrame(bytearray(list(range(0+x, 16)))) + trans_frame.tdest = 0x0 + trans_frame.tuser = x + + # Generate the payload data frames + test_frames = [None for _ in range(2)] + for i in range(2): + test_frames[i] = AxiStreamFrame(bytearray(list(range(1+i+x, 16+1)))) + test_frames[i].tdest = i+1 + test_frames[i].tuser = x + + # Send the transition frame + await tb.sources[0].send(trans_frame) + tb.log.custom( f'trans_frame.tdata={trans_frame.tdata}' ) + tb.log.custom( f'trans_frame.tdest={trans_frame.tdest}' ) + tb.log.custom( f'trans_frame.tuser={trans_frame.tuser}' ) + + # Received the transition frame + rx_frame = await tb.sinks[0].recv() + tb.log.custom( f'rx_frame.tdata={rx_frame.tdata}' ) + tb.log.custom( f'rx_frame.tdest={rx_frame.tdest}' ) + tb.log.custom( f'rx_frame.tuser={rx_frame.tuser}' ) + assert rx_frame.tdata == trans_frame.tdata + assert rx_frame.tdest == trans_frame.tdest + assert rx_frame.tuser == trans_frame.tuser + assert tb.sinks[0].empty() + + # Send the payload data frames + for i in range(2): + tb.log.custom( f'test_frames[{i}].tdata={test_frames[i].tdata}' ) + tb.log.custom( f'test_frames[{i}].tdest={test_frames[i].tdest}' ) + tb.log.custom( f'test_frames[{i}].tuser={test_frames[i].tuser}' ) + await tb.sources[i].send(test_frames[i]) + + # Received the payload data frame + for i in range(2): + rx_frame = await tb.sinks[i].recv() + tb.log.custom( f'rx_frame.tdata={rx_frame.tdata}' ) + tb.log.custom( f'rx_frame.tdest={rx_frame.tdest}' ) + tb.log.custom( f'rx_frame.tuser={rx_frame.tuser}' ) + assert rx_frame.tdata == test_frames[i].tdata + assert rx_frame.tdest == test_frames[i].tdest + assert rx_frame.tuser == test_frames[i].tuser + assert tb.sinks[i].empty() + +if cocotb.SIM_NAME: + factory = TestFactory(run_test) + factory.generate_tests() + +tests_dir = os.path.dirname(__file__) +tests_module = 'EventFrameSequencerTb' + +############################################################################## + +@pytest.mark.parametrize( + "parameters", [ + None + ]) +def test_EventFrameSequencerTb(parameters): + + # https://github.com/themperek/cocotb-test#arguments-for-simulatorrun + # https://github.com/themperek/cocotb-test/blob/master/cocotb_test/simulator.py + run( + # top level HDL + toplevel = f'surf.{tests_module}'.lower(), + + # name of the file that contains @cocotb.test() -- this file + # https://docs.cocotb.org/en/stable/building.html?#envvar-MODULE + module = f'test_{tests_module}', + + # https://docs.cocotb.org/en/stable/building.html?#var-TOPLEVEL_LANG + toplevel_lang = 'vhdl', + + # VHDL source files to include. + # Can be specified as a list or as a dict of lists with the library name as key, + # if the simulator supports named libraries. + vhdl_sources = { + 'surf' : glob.glob(f'{tests_dir}/../build/SRC_VHDL/surf/*'), + 'ruckus' : glob.glob(f'{tests_dir}/../build/SRC_VHDL/ruckus/*'), + }, + + # A dictionary of top-level parameters/generics. + parameters = parameters, + + # The directory used to compile the tests. (default: sim_build) + sim_build = f'{tests_dir}/sim_build/{tests_module}', + + # A dictionary of extra environment variables set in simulator process. + extra_env=parameters, + + # Select a simulator + simulator="ghdl", + + # use of synopsys package "std_logic_arith" needs the -fsynopsys option + # -frelaxed-rules option to allow IP integrator attributes + # When two operators are overloaded, give preference to the explicit declaration (-fexplicit) + vhdl_compile_args = ['-fsynopsys','-frelaxed-rules', '-fexplicit'], + + ######################################################################## + # Dump waveform to file ($ gtkwave sim_build/path/To/{tests_module}.ghw) + ######################################################################## + sim_args =[f'--wave={tests_module}.ghw'], + ) From 0136605a6432a6fb704784ce169cc684dcc88ad2 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 16 Jan 2025 10:45:23 -0800 Subject: [PATCH 12/17] linter fix --- tests/test_EventFrameSequencerTb.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_EventFrameSequencerTb.py b/tests/test_EventFrameSequencerTb.py index 5add8bee48..9acafdac95 100755 --- a/tests/test_EventFrameSequencerTb.py +++ b/tests/test_EventFrameSequencerTb.py @@ -9,7 +9,6 @@ ############################################################################## # dut_tb -import itertools import logging import cocotb from cocotb.clock import Clock From b5c7175313790aece16e3a45244b5bfde8a1b1c4 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 16 Jan 2025 11:44:38 -0800 Subject: [PATCH 13/17] updating the HDR defination --- .../rtl/EventFrameSequencerDemux.vhd | 110 ++++++++++-------- .../rtl/EventFrameSequencerMux.vhd | 20 ++-- 2 files changed, 74 insertions(+), 56 deletions(-) diff --git a/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd b/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd index fc969926d5..f1652758f2 100755 --- a/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd +++ b/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd @@ -52,6 +52,8 @@ end entity EventFrameSequencerDemux; architecture rtl of EventFrameSequencerDemux is + constant LOG2_WIDTH_C : slv(3 downto 0) := toSlv(log2(AXIS_CONFIG_G.TDATA_BYTES_C), 4); + type StateType is ( IDLE_S, MOVE_S); @@ -65,10 +67,10 @@ architecture rtl of EventFrameSequencerDemux is sof : sl; frameCnt : slv(7 downto 0); numFrames : slv(7 downto 0); - seqCnt : slv(15 downto 0); + seqCnt : slv(7 downto 0); dataCnt : Slv32Array(NUM_MASTERS_G-1 downto 0); dropCnt : slv(31 downto 0); - simDebug : slv(7 downto 0); + hdrError : slv(7 downto 0); index : natural range 0 to NUM_MASTERS_G-1; tUserFirst : slv(7 downto 0); tDest : slv(7 downto 0); @@ -91,7 +93,7 @@ architecture rtl of EventFrameSequencerDemux is seqCnt => (others => '0'), dataCnt => (others => (others => '0')), dropCnt => (others => '0'), - simDebug => (others => '0'), + hdrError => (others => '0'), index => 0, tUserFirst => (others => '0'), tDest => (others => '0'), @@ -131,18 +133,16 @@ begin comb : process (axilReadMaster, axilWriteMaster, axisRst, blowoffExt, r, rxMaster, txSlaves) is - variable v : RegType; - variable axilEp : AxiLiteEndPointType; - variable validHdr : sl; - variable sofDet : sl; - variable dbg : slv(7 downto 0); + variable v : RegType; + variable axilEp : AxiLiteEndPointType; + variable dbg : slv(7 downto 0); + variable sofDet : sl; begin -- Latch the current value v := r; -- Update the local variable - v.simDebug := (others => '0'); - dbg := (others => '0'); + dbg := (others => '0'); if (v.state = IDLE_S) then dbg(0) := '0'; else @@ -180,6 +180,7 @@ begin axiSlaveRegisterR(axilEp, x"FF4", 0, toSlv(NUM_MASTERS_G, 8)); axiSlaveRegisterR(axilEp, x"FF4", 8, dbg); axiSlaveRegisterR(axilEp, X"FF4", 16, blowoffExt); + axiSlaveRegisterR(axilEp, x"FF4", 24, r.hdrError); axiSlaveRegister (axilEp, x"FF8", 0, v.blowoffReg); axiSlaveRegister (axilEp, x"FFC", 0, v.cntRst); axiSlaveRegister (axilEp, x"FFC", 2, v.hardRst); @@ -197,46 +198,59 @@ begin v.softRst := '1'; end if; - -- AXIS flow control - v.rxSlave.tReady := r.blowoff; - for i in (NUM_MASTERS_G-1) downto 0 loop - if (txSlaves(i).tReady = '1') then - v.txMasters(i).tValid := '0'; + ---------------------------------------------------------------------- + -- Check for valid SOF + sofDet := ssiGetUserSof(AXIS_CONFIG_G, rxMaster); + if (rxMaster.tValid = '1') and (sofDet = '1') then + + -- Reset the flag + v.hdrError := (others => '0'); + + -- Check for EOF + if (rxMaster.tLast = '1') then + v.hdrError(0) := '1'; end if; - end loop; - -- Check for SOF - validHdr := ssiGetUserSof(AXIS_CONFIG_G, rxMaster); - sofDet := ssiGetUserSof(AXIS_CONFIG_G, rxMaster); + -- Check for valid version field + if (rxMaster.tData(3 downto 0) /= x"1") then + v.hdrError(1) := '1'; + end if; - -- Check for EOF - if (rxMaster.tLast = '1') then - validHdr := '0'; - v.simDebug(0) := ite(r.state = IDLE_S, sofDet, '0'); - end if; + -- Check for valid log2(TDATA_BYTES_C) + if (rxMaster.tData(7 downto 4) /= LOG2_WIDTH_C) then + v.hdrError(2) := '1'; + end if; - -- Check for valid version field - if (rxMaster.tData(7 downto 0) /= x"01") then - validHdr := '0'; - v.simDebug(1) := ite(r.state = IDLE_S, sofDet, '0'); - end if; + -- Check for valid event frame index + if (rxMaster.tData(15 downto 8) /= r.seqCnt) then + v.hdrError(3) := '1'; + end if; - if (rxMaster.tData(15 downto 8) >= NUM_MASTERS_G) then - validHdr := '0'; - v.simDebug(2) := ite(r.state = IDLE_S, sofDet, '0'); - end if; + -- Check for valid number of streams (zero inclusive) + if (rxMaster.tData(39 downto 32) /= NUM_MASTERS_G) then + v.hdrError(4) := '1'; + end if; - -- Check for valid event frame index - if (rxMaster.tData(23 downto 16) /= r.frameCnt) then - validHdr := '0'; - v.simDebug(3) := ite(r.state = IDLE_S, sofDet, '0'); - end if; + -- Check that index in valid range + if (rxMaster.tData(47 downto 40) >= NUM_MASTERS_G) then + v.hdrError(5) := '1'; + end if; + + -- Check for valid event frame index + if (rxMaster.tData(55 downto 48) /= r.frameCnt) then + v.hdrError(6) := '1'; + end if; - -- Check for valid event frame index - if (rxMaster.tData(63 downto 48) /= r.seqCnt) then - validHdr := '0'; - v.simDebug(4) := ite(r.state = IDLE_S, sofDet, '0'); end if; + ---------------------------------------------------------------------- + + -- AXIS flow control + v.rxSlave.tReady := r.blowoff; + for i in (NUM_MASTERS_G-1) downto 0 loop + if (txSlaves(i).tReady = '1') then + v.txMasters(i).tValid := '0'; + end if; + end loop; -- State machine case r.state is @@ -257,14 +271,14 @@ begin -- Accept the data v.rxSlave.tReady := '1'; - -- Check for valid header - if (validHdr = '1') then + -- Check for valid header and SOF + if (v.hdrError = 0) and (sofDet = '1') then -- Save the meta-data - v.index := conv_integer(rxMaster.tData(15 downto 8)); - v.numFrames := rxMaster.tData(31 downto 24); - v.tUserFirst := rxMaster.tData(39 downto 32); - v.tDest := rxMaster.tData(47 downto 40); + v.index := conv_integer(rxMaster.tData(47 downto 40)); + v.numFrames := rxMaster.tData(63 downto 56); + v.tUserFirst := rxMaster.tData(23 downto 16); + v.tDest := rxMaster.tData(31 downto 24); -- Next state v.state := MOVE_S; diff --git a/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd b/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd index 333fe98e31..a10124d96a 100755 --- a/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd +++ b/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd @@ -69,6 +69,8 @@ end entity EventFrameSequencerMux; architecture rtl of EventFrameSequencerMux is + constant LOG2_WIDTH_C : slv(3 downto 0) := toSlv(log2(AXIS_CONFIG_G.TDATA_BYTES_C), 4); + constant DEST_SIZE_C : integer := bitSize(NUM_SLAVES_G-1); type StateType is ( @@ -85,7 +87,7 @@ architecture rtl of EventFrameSequencerMux is sof : sl; frameCnt : slv(7 downto 0); numFrames : slv(7 downto 0); - seqCnt : slv(15 downto 0); + seqCnt : slv(7 downto 0); bypass : slv(NUM_SLAVES_G-1 downto 0); dataCnt : Slv32Array(NUM_SLAVES_G-1 downto 0); transCnt : slv(31 downto 0); @@ -393,13 +395,15 @@ begin ssiSetUserSof(AXIS_CONFIG_G, v.txMaster, '1'); -- HEADER context - v.txMaster.tData(7 downto 0) := x"01"; -- Version Field - v.txMaster.tData(15 downto 8) := toSlv(r.index, 8); -- MUX Index - v.txMaster.tData(23 downto 16) := r.frameCnt; -- Event frame index - v.txMaster.tData(31 downto 24) := r.numFrames; -- Event frame Size (zero inclusive) - v.txMaster.tData(39 downto 32) := rxMasters(r.index).tUser(7 downto 0); -- TUSER_FIRST - v.txMaster.tData(47 downto 40) := rxMasters(r.index).tDest; -- TDEST - v.txMaster.tData(63 downto 48) := r.seqCnt; -- Sequence Counter + v.txMaster.tData(3 downto 0) := x"1"; -- Version Field + v.txMaster.tData(7 downto 4) := LOG2_WIDTH_C; -- log2(TDATA_BYTES_C) + v.txMaster.tData(15 downto 8) := r.seqCnt; -- Sequence Counter + v.txMaster.tData(23 downto 16) := rxMasters(r.index).tUser(7 downto 0); -- TUSER_FIRST + v.txMaster.tData(31 downto 24) := rxMasters(r.index).tDest; -- TDEST + v.txMaster.tData(39 downto 32) := toSlv(NUM_SLAVES_G, 8); -- Number of streams + v.txMaster.tData(47 downto 40) := toSlv(r.index, 8); -- MUX Index + v.txMaster.tData(55 downto 48) := r.frameCnt; -- Event frame index + v.txMaster.tData(63 downto 56) := r.numFrames; -- Event frame Size (zero inclusive) -- Check for the last transfer elsif (rxMasters(r.index).tLast = '1') then From 347b98679b3e62fda1a6562dd4d821a9cdd0c481 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 16 Jan 2025 11:58:45 -0800 Subject: [PATCH 14/17] enforce AXIS_CONFIG_G.TDATA_BYTES_C be power of 2 --- .../event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd | 3 +++ .../event-frame-sequencer/rtl/EventFrameSequencerMux.vhd | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd b/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd index f1652758f2..e78e0cfd7a 100755 --- a/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd +++ b/protocols/event-frame-sequencer/rtl/EventFrameSequencerDemux.vhd @@ -116,6 +116,9 @@ begin assert (AXIS_CONFIG_G.TDATA_BYTES_C >= 8) report "AXIS_CONFIG_G.TDATA_BYTES_C must be >= 8" severity error; + assert (isPowerOf2(AXIS_CONFIG_G.TDATA_BYTES_C) = true) + report "AXIS_CONFIG_G.TDATA_BYTES_C must be power of 2" severity failure; + ----------------- -- Input pipeline ----------------- diff --git a/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd b/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd index a10124d96a..75fc79a575 100755 --- a/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd +++ b/protocols/event-frame-sequencer/rtl/EventFrameSequencerMux.vhd @@ -140,6 +140,9 @@ begin assert (AXIS_CONFIG_G.TDATA_BYTES_C >= 8) report "AXIS_CONFIG_G.TDATA_BYTES_C must be >= 8" severity error; + assert (isPowerOf2(AXIS_CONFIG_G.TDATA_BYTES_C) = true) + report "AXIS_CONFIG_G.TDATA_BYTES_C must be power of 2" severity failure; + ------------------------- -- Override Inbound TDEST ------------------------- @@ -402,7 +405,7 @@ begin v.txMaster.tData(31 downto 24) := rxMasters(r.index).tDest; -- TDEST v.txMaster.tData(39 downto 32) := toSlv(NUM_SLAVES_G, 8); -- Number of streams v.txMaster.tData(47 downto 40) := toSlv(r.index, 8); -- MUX Index - v.txMaster.tData(55 downto 48) := r.frameCnt; -- Event frame index + v.txMaster.tData(55 downto 48) := r.frameCnt; -- Event frame count v.txMaster.tData(63 downto 56) := r.numFrames; -- Event frame Size (zero inclusive) -- Check for the last transfer From 3741b6e245fe768c757f6654e16a05249847d57c Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 16 Jan 2025 12:08:40 -0800 Subject: [PATCH 15/17] SW reg map bug fix --- python/surf/protocols/batcher/_AxiStreamBatcherEventBuilder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/surf/protocols/batcher/_AxiStreamBatcherEventBuilder.py b/python/surf/protocols/batcher/_AxiStreamBatcherEventBuilder.py index 7eff167f25..f0bddcb377 100644 --- a/python/surf/protocols/batcher/_AxiStreamBatcherEventBuilder.py +++ b/python/surf/protocols/batcher/_AxiStreamBatcherEventBuilder.py @@ -102,7 +102,7 @@ def __init__( self.add(pr.RemoteVariable( name = "State", description = "current state of FSM (for debugging)", - offset = 0xFF8, + offset = 0xFF4, bitSize = 1, bitOffset = 8, mode = "RO", From 2784ca1248e2c0489e86fe5f90054fec6f3e643f Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 16 Jan 2025 12:15:06 -0800 Subject: [PATCH 16/17] adding EventFrameSequencer SW --- .../_EventFrameSequencerDemux.py | 146 +++++++++++++++++ .../_EventFrameSequencerMux.py | 152 ++++++++++++++++++ .../event_frame_sequencer/__init__.py | 2 + 3 files changed, 300 insertions(+) create mode 100755 python/surf/protocols/event_frame_sequencer/_EventFrameSequencerDemux.py create mode 100755 python/surf/protocols/event_frame_sequencer/_EventFrameSequencerMux.py create mode 100755 python/surf/protocols/event_frame_sequencer/__init__.py diff --git a/python/surf/protocols/event_frame_sequencer/_EventFrameSequencerDemux.py b/python/surf/protocols/event_frame_sequencer/_EventFrameSequencerDemux.py new file mode 100755 index 0000000000..8a085dd1c3 --- /dev/null +++ b/python/surf/protocols/event_frame_sequencer/_EventFrameSequencerDemux.py @@ -0,0 +1,146 @@ +#----------------------------------------------------------------------------- +# This file is part of the 'SLAC Firmware Standard Library'. It is subject to +# the license terms in the LICENSE.txt file found in the top-level directory +# of this distribution and at: +# https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +# No part of the 'SLAC Firmware Standard Library', including this file, may be +# copied, modified, propagated, or distributed except according to the terms +# contained in the LICENSE.txt file. +#----------------------------------------------------------------------------- + +import pyrogue as pr + +class EventFrameSequencerDemux(pr.Device): + def __init__( + self, + numberSlaves = 1, + **kwargs): + super().__init__(**kwargs) + + self.addRemoteVariables( + name = 'DataCnt', + description = 'Increments every time a data frame is received', + offset = 0x000, + bitSize = 32, + mode = 'RO', + number = numberSlaves, + stride = 4, + pollInterval = 1, + ) + + self.add(pr.RemoteVariable( + name = 'SeqCnt', + description = 'Increments every time there is a frame sent', + offset = 0xFBC, + bitSize = 8, + mode = 'RO', + pollInterval = 1, + )) + + self.add(pr.RemoteVariable( + name = 'DropCnt', + description = 'Increments every time a frame is dropped', + offset = 0xFC0, + bitSize = 32, + mode = 'RO', + pollInterval = 1, + )) + + self.add(pr.RemoteVariable( + name = 'NUM_MASTERS_G', + description = 'NUM_MASTERS_G generic value', + offset = 0xFF4, + bitSize = 8, + mode = 'RO', + disp = '{:d}', + )) + + self.add(pr.RemoteVariable( + name = "State", + description = "current state of FSM (for debugging)", + offset = 0xFF4, + bitSize = 1, + bitOffset = 8, + mode = "RO", + pollInterval = 1, + enum = { + 0x0: 'IDLE_S', + 0x1: 'MOVE_S', + }, + )) + + self.add(pr.RemoteVariable( + name = "BlowoffExt", + description = "Status of external blowoff input", + offset = 0xFF4, + bitSize = 1, + bitOffset = 16, + base = pr.Bool, + mode = "RO", + pollInterval = 1, + )) + + self.add(pr.RemoteVariable( + name = "HdrError", + description = "Header error code when last frame dropped", + offset = 0xFF4, + bitSize = 8, + bitOffset = 24, + mode = "RO", + pollInterval = 1, + )) + + self.add(pr.RemoteVariable( + name = "Blowoff", + description = "Blows off the inbound AXIS stream (for debugging)", + offset = 0xFF8, + bitSize = 1, + bitOffset = 0, + base = pr.Bool, + mode = "RW", + )) + + self.add(pr.RemoteCommand( + name = "CntRst", + description = "", + offset = 0xFFC, + bitSize = 1, + bitOffset = 0, + function = pr.BaseCommand.toggle, + )) + + self.add(pr.RemoteCommand( + name = "TimerRst", + description = "", + offset = 0xFFC, + bitSize = 1, + bitOffset = 1, + function = pr.BaseCommand.toggle, + )) + + self.add(pr.RemoteCommand( + name = "HardRst", + description = "", + offset = 0xFFC, + bitSize = 1, + bitOffset = 2, + function = pr.BaseCommand.toggle, + )) + + self.add(pr.RemoteCommand( + name = "SoftRst", + description = "", + offset = 0xFFC, + bitSize = 1, + bitOffset = 3, + function = pr.BaseCommand.toggle, + )) + + def hardReset(self): + self.HardRst() + + def initialize(self): + self.SoftRst() + + def countReset(self): + self.CntRst() diff --git a/python/surf/protocols/event_frame_sequencer/_EventFrameSequencerMux.py b/python/surf/protocols/event_frame_sequencer/_EventFrameSequencerMux.py new file mode 100755 index 0000000000..5211746edc --- /dev/null +++ b/python/surf/protocols/event_frame_sequencer/_EventFrameSequencerMux.py @@ -0,0 +1,152 @@ +#----------------------------------------------------------------------------- +# This file is part of the 'SLAC Firmware Standard Library'. It is subject to +# the license terms in the LICENSE.txt file found in the top-level directory +# of this distribution and at: +# https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +# No part of the 'SLAC Firmware Standard Library', including this file, may be +# copied, modified, propagated, or distributed except according to the terms +# contained in the LICENSE.txt file. +#----------------------------------------------------------------------------- + +import pyrogue as pr + +class EventFrameSequencerMux(pr.Device): + def __init__( + self, + numberSlaves = 1, + **kwargs): + super().__init__(**kwargs) + + self.addRemoteVariables( + name = 'DataCnt', + description = 'Increments every time a data frame is received', + offset = 0x000, + bitSize = 32, + mode = 'RO', + number = numberSlaves, + stride = 4, + pollInterval = 1, + ) + + self.add(pr.RemoteVariable( + name = 'SeqCnt', + description = 'Increments every time there is a frame sent', + offset = 0xFBC, + bitSize = 8, + mode = 'RO', + pollInterval = 1, + )) + + self.add(pr.RemoteVariable( + name = 'TransactionCnt', + description = 'Increments every time a transition frame is received', + offset = 0xFC0, + bitSize = 32, + mode = 'RO', + pollInterval = 1, + )) + + self.add(pr.RemoteVariable( + name = 'TRANS_TDEST_G', + description = 'TRANS_TDEST_G generic value', + offset = 0xFC4, + bitSize = 8, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'Bypass', + description = 'Mask to bypass a channel', + offset = 0xFD0, + bitSize = numberSlaves, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'NUM_SLAVES_G', + description = 'NUM_SLAVES_G generic value', + offset = 0xFF4, + bitSize = 8, + mode = 'RO', + disp = '{:d}', + )) + + self.add(pr.RemoteVariable( + name = "State", + description = "current state of FSM (for debugging)", + offset = 0xFF4, + bitSize = 1, + bitOffset = 8, + mode = "RO", + pollInterval = 1, + enum = { + 0x0: 'IDLE_S', + 0x1: 'MOVE_S', + }, + )) + + self.add(pr.RemoteVariable( + name = "BlowoffExt", + description = "Status of external blowoff input", + offset = 0xFF4, + bitSize = 1, + bitOffset = 16, + base = pr.Bool, + mode = "RO", + pollInterval = 1, + )) + + self.add(pr.RemoteVariable( + name = "Blowoff", + description = "Blows off the inbound AXIS stream (for debugging)", + offset = 0xFF8, + bitSize = 1, + bitOffset = 0, + base = pr.Bool, + mode = "RW", + )) + + self.add(pr.RemoteCommand( + name = "CntRst", + description = "", + offset = 0xFFC, + bitSize = 1, + bitOffset = 0, + function = pr.BaseCommand.toggle, + )) + + self.add(pr.RemoteCommand( + name = "TimerRst", + description = "", + offset = 0xFFC, + bitSize = 1, + bitOffset = 1, + function = pr.BaseCommand.toggle, + )) + + self.add(pr.RemoteCommand( + name = "HardRst", + description = "", + offset = 0xFFC, + bitSize = 1, + bitOffset = 2, + function = pr.BaseCommand.toggle, + )) + + self.add(pr.RemoteCommand( + name = "SoftRst", + description = "", + offset = 0xFFC, + bitSize = 1, + bitOffset = 3, + function = pr.BaseCommand.toggle, + )) + + def hardReset(self): + self.HardRst() + + def initialize(self): + self.SoftRst() + + def countReset(self): + self.CntRst() diff --git a/python/surf/protocols/event_frame_sequencer/__init__.py b/python/surf/protocols/event_frame_sequencer/__init__.py new file mode 100755 index 0000000000..fb2bddff1d --- /dev/null +++ b/python/surf/protocols/event_frame_sequencer/__init__.py @@ -0,0 +1,2 @@ +from surf.protocols.event_frame_sequencer._EventFrameSequencerMux import * +from surf.protocols.event_frame_sequencer._EventFrameSequencerDemux import * From dc20d0eab42b5686c5e8c9e95fa5119c497f183c Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 23 Jan 2025 08:47:11 -0800 Subject: [PATCH 17/17] do not save the waveforms in CI --- tests/test_EventFrameSequencerTb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_EventFrameSequencerTb.py b/tests/test_EventFrameSequencerTb.py index 9acafdac95..9f56df2301 100755 --- a/tests/test_EventFrameSequencerTb.py +++ b/tests/test_EventFrameSequencerTb.py @@ -194,5 +194,5 @@ def test_EventFrameSequencerTb(parameters): ######################################################################## # Dump waveform to file ($ gtkwave sim_build/path/To/{tests_module}.ghw) ######################################################################## - sim_args =[f'--wave={tests_module}.ghw'], + # sim_args =[f'--wave={tests_module}.ghw'], )