diff --git a/.github/workflows/surf_ci.yml b/.github/workflows/surf_ci.yml index 34f6872baa..17d1a225ab 100644 --- a/.github/workflows/surf_ci.yml +++ b/.github/workflows/surf_ci.yml @@ -77,92 +77,21 @@ jobs: # ---------------------------------------------------------------------------- gen_release: - name: Generate Release - runs-on: ubuntu-20.04 needs: [test_and_document] - if: startsWith(github.ref, 'refs/tags/') - steps: - - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - uses: actions/setup-python@v2 - with: - python-version: 3.8 - - - name: Get Image Information - id: get_image_info - run: | - echo ::set-output name=tag::`git describe --tags` - - - name: Get Ruckus - run: | - git clone https://github.com/slaclab/ruckus.git - python -m pip install --upgrade pip - pip install -r ruckus/scripts/pip_requirements.txt - - - name: Gen Release - env: - TRAVIS_REPO_SLUG: ${{ github.repository }} - TRAVIS_TAG: ${{ steps.get_image_info.outputs.tag }} - GH_REPO_TOKEN: ${{ secrets.GH_TOKEN }} - run: | - python ruckus/scripts/releaseGen.py + uses: slaclab/ruckus/.github/workflows/gen_release.yml@main + with: + version: '1.0.0' + secrets: + GH_TOKEN: ${{ secrets.GH_TOKEN }} # ---------------------------------------------------------------------------- - conda_build: - name: Anaconda Build + conda_build_lib: needs: [test_and_document] - if: startsWith(github.ref, 'refs/tags/') - strategy: - matrix: - os: - - ubuntu-20.04 - runs-on: ${{ matrix.os }} - steps: - - # This step checks out a copy of your repository. - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - uses: actions/setup-python@v2 - with: - python-version: 3.8 - - - name: Setup anaconda - env: - OS_NAME: ${{ matrix.os }} - run: | - cd ${HOME} - wget -O miniconda.sh https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh - bash miniconda.sh -b -p ${HOME}/miniconda - export PATH="${HOME}/miniconda/bin:$PATH" - source ${HOME}/miniconda/etc/profile.d/conda.sh - conda config --set always_yes yes - conda config --set channel_priority strict - conda install -n base conda-libmamba-solver - conda config --set solver libmamba - conda install conda-build anaconda-client conda-verify - conda update -q conda conda-build - conda update --all - - - name: Get Image Information - id: get_image_info - env: - CONDA_UPLOAD_TOKEN_TAG: ${{ secrets.CONDA_UPLOAD_TOKEN_TAG }} - OS_NAME: ${{ matrix.os }} - run: | - echo ::set-output name=token::$CONDA_UPLOAD_TOKEN_TAG - echo ::set-output name=os::linux-64 - - - name: Build And Upload - run: | - export PATH="${HOME}/miniconda/bin:$PATH" - source ${HOME}/miniconda/etc/profile.d/conda.sh - conda build --debug conda-recipe --output-folder bld-dir -c tidair-tag -c tidair-packages -c conda-forge - anaconda -t ${{ steps.get_image_info.outputs.token }} upload --force bld-dir/noarch/*.tar.bz2 + uses: slaclab/ruckus/.github/workflows/conda_build_lib.yml@main + with: + version: '1.0.0' + secrets: + CONDA_UPLOAD_TOKEN_TAG: ${{ secrets.CONDA_UPLOAD_TOKEN_TAG }} # ---------------------------------------------------------------------------- diff --git a/README.md b/README.md index 7ebf753798..e367a180d4 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,18 @@ $ git lfs install -# Documentation +# Presentations [An Introduction to SURF Presentation](https://docs.google.com/presentation/d/1kvzXiByE8WISo40Xd573DdR7dQU4BpDQGwEgNyeJjTI/edit?usp=sharing) +[IEEE RT 2024: SURF Workshop Presentation](https://docs.google.com/presentation/d/1pPfELOniJzBMBpp1lE9Xmid71ckkBH4wsoWzUGZyyy4/edit?usp=sharing) + + + +# Misc + +[Tutorial](https://github.com/slaclab/surf-tutorial) + [Doxygen Homepage](https://slaclab.github.io/surf/index.html) [Support Homepage](https://confluence.slac.stanford.edu/display/ppareg/Build+System%3A+Vivado+Support) diff --git a/axi/axi-stream/rtl/AxiStreamRingBuffer.vhd b/axi/axi-stream/rtl/AxiStreamRingBuffer.vhd index 6dadeef295..c9679fe392 100644 --- a/axi/axi-stream/rtl/AxiStreamRingBuffer.vhd +++ b/axi/axi-stream/rtl/AxiStreamRingBuffer.vhd @@ -405,13 +405,14 @@ begin when ARMED_S => -- Check if armed if (armed = '1') then + -- Set the trigger + v.softTrig := '1'; -- Next state v.trigState := WAIT_S; end if; ---------------------------------------------------------------------- when WAIT_S => - -- Hold the trigger until cleared by (axilR.dataState = IDLE_S) - v.softTrig := '1'; + null; ---------------------------------------------------------------------- end case; @@ -437,16 +438,14 @@ begin -- Check for trigger event if (readReq = '1') then - - -- Reset the flag - v.softTrig := '0'; - -- Next state v.dataState := MOVE_S; - end if; ---------------------------------------------------------------------- when MOVE_S => + -- Reset the flag + v.softTrig := '0'; + -- Check if ready to move data if (v.txMaster.tValid = '0') and (axilR.rdEn = 0) then @@ -482,6 +481,9 @@ begin end if; ---------------------------------------------------------------------- when CLEARED_S => + -- Reset the flag + v.softTrig := '0'; + -- Check if armed de-asserted if (armed = '0') then -- Next states diff --git a/base/sync/rtl/SyncTrigPeriod.vhd b/base/sync/rtl/SyncTrigPeriod.vhd index 4904c6e092..07753cfa52 100644 --- a/base/sync/rtl/SyncTrigPeriod.vhd +++ b/base/sync/rtl/SyncTrigPeriod.vhd @@ -113,11 +113,11 @@ begin v.periodMin := v.cnt; end if; - -- Reset the counter - v.cnt := (others => '0'); - end if; + -- Reset the counter + v.cnt := (others => '0'); + end if; -- Outputs diff --git a/protocols/i2c/rtl/I2cRegMaster.vhd b/protocols/i2c/rtl/I2cRegMaster.vhd index 91b8b749f8..66a1439476 100644 --- a/protocols/i2c/rtl/I2cRegMaster.vhd +++ b/protocols/i2c/rtl/I2cRegMaster.vhd @@ -209,7 +209,7 @@ begin v.i2cMasterIn.txnReq := '1'; v.i2cMasterIn.op := '0'; v.i2cMasterIn.stop := '1'; -- i2c stop after all bytes are read - v.byteCount := (others => '0'); + v.byteCount := (others => '0'); v.state := READ_S; when READ_S => diff --git a/protocols/ssi/rtl/SsiPrbsRx.vhd b/protocols/ssi/rtl/SsiPrbsRx.vhd index 4c53cba26e..73f8b10c0d 100644 --- a/protocols/ssi/rtl/SsiPrbsRx.vhd +++ b/protocols/ssi/rtl/SsiPrbsRx.vhd @@ -158,7 +158,7 @@ architecture rtl of SsiPrbsRx is signal axisCtrl : AxiStreamCtrlArray(1 downto 0) := (others => AXI_STREAM_CTRL_UNUSED_C); - constant STATUS_SIZE_C : positive := 10; + constant STATUS_SIZE_C : positive := 11; type LocRegType is record cntRst : sl; @@ -180,6 +180,7 @@ architecture rtl of SsiPrbsRx is signal rAxiLite : LocRegType := LOC_REG_INIT_C; signal rinAxiLite : LocRegType; + signal updatedResultsSync : sl; signal errBitStrbSync : sl; signal errWordStrbSync : sl; signal errDataBusSync : sl; @@ -196,6 +197,7 @@ architecture rtl of SsiPrbsRx is signal packetRateSync : slv(31 downto 0); signal errWordCntSync : slv(31 downto 0); + signal frameCnt : slv(STATUS_CNT_WIDTH_G-1 downto 0); signal pause1Cnt : slv(STATUS_CNT_WIDTH_G-1 downto 0); signal overflow1Cnt : slv(STATUS_CNT_WIDTH_G-1 downto 0); signal pause0Cnt : slv(STATUS_CNT_WIDTH_G-1 downto 0); @@ -551,35 +553,38 @@ begin WIDTH_G => STATUS_SIZE_C) port map ( -- Input Status bit Signals (wrClk domain) - statusIn(9) => axisCtrl(1).pause, - statusIn(8) => axisCtrl(1).overflow, - statusIn(7) => axisCtrl(0).pause, - statusIn(6) => axisCtrl(0).overflow, - statusIn(5) => '0', -- Legacy - statusIn(4) => r.errWordStrb, - statusIn(3) => r.errDataBus, - statusIn(2) => r.eofe, - statusIn(1) => r.errLength, - statusIn(0) => r.errMissedPacket, + statusIn(10) => r.updatedResults, + statusIn(9) => axisCtrl(1).pause, + statusIn(8) => axisCtrl(1).overflow, + statusIn(7) => axisCtrl(0).pause, + statusIn(6) => axisCtrl(0).overflow, + statusIn(5) => '0', -- Legacy + statusIn(4) => r.errWordStrb, + statusIn(3) => r.errDataBus, + statusIn(2) => r.eofe, + statusIn(1) => r.errLength, + statusIn(0) => r.errMissedPacket, -- Output Status bit Signals (rdClk domain) - statusOut(9) => pause(1), - statusOut(8) => overflow(1), - statusOut(7) => pause(0), - statusOut(6) => overflow(0), - statusOut(5) => errBitStrbSync, - statusOut(4) => errWordStrbSync, - statusOut(3) => errDataBusSync, - statusOut(2) => errEofeSync, - statusOut(1) => errLengthSync, - statusOut(0) => errMissedPacketSync, + statusOut(10) => updatedResultsSync, + statusOut(9) => pause(1), + statusOut(8) => overflow(1), + statusOut(7) => pause(0), + statusOut(6) => overflow(0), + statusOut(5) => errBitStrbSync, + statusOut(4) => errWordStrbSync, + statusOut(3) => errDataBusSync, + statusOut(2) => errEofeSync, + statusOut(1) => errLengthSync, + statusOut(0) => errMissedPacketSync, -- Status Bit Counters Signals (rdClk domain) - cntRstIn => rAxiLite.cntRst, - rollOverEnIn => rAxiLite.rollOverEn, - cntOut => cntOut, + cntRstIn => rAxiLite.cntRst, + rollOverEnIn => rAxiLite.rollOverEn, + cntOut => cntOut, -- Clocks and Reset Ports - wrClk => sAxisClk, - rdClk => axiClk); + wrClk => sAxisClk, + rdClk => axiClk); + frameCnt <= muxSlVectorArray(cntOut, 10); pause1Cnt <= muxSlVectorArray(cntOut, 9); overflow1Cnt <= muxSlVectorArray(cntOut, 8); pause0Cnt <= muxSlVectorArray(cntOut, 7); @@ -598,7 +603,7 @@ begin errDataBusSync, errEofeCnt, errEofeSync, errLengthCnt, errLengthSync, errMissedPacketCnt, errMissedPacketSync, errWordCntSync, errWordStrbCnt, - errWordStrbSync, overflow, overflow0Cnt, + errWordStrbSync, frameCnt, overflow, overflow0Cnt, overflow1Cnt, packetLengthSync, packetRateSync, pause, pause0Cnt, pause1Cnt, rAxiLite) is variable v : LocRegType; @@ -629,7 +634,7 @@ begin axiSlaveRegisterR(axilEp, X"70", 2, errEofeSync); axiSlaveRegisterR(axilEp, X"70", 3, errDataBusSync); axiSlaveRegisterR(axilEp, X"70", 4, errWordStrbSync); - axiSlaveRegisterR(axilEp, X"70", 5, '0'); -- legacy errBitStrbSync + axiSlaveRegisterR(axilEp, X"70", 5, '0'); -- legacy errBitStrbSync axiSlaveRegisterR(axilEp, X"70", 6, overflow(0)); axiSlaveRegisterR(axilEp, X"70", 7, pause(0)); axiSlaveRegisterR(axilEp, X"70", 8, overflow(1)); @@ -638,6 +643,7 @@ begin axiSlaveRegisterR(axilEp, X"78", 0, packetRateSync); axiSlaveRegisterR(axilEp, X"7C", 0, X"00000000"); -- legacy errBitCntSync axiSlaveRegisterR(axilEp, X"80", 0, errWordCntSync); + axiSlaveRegisterR(axilEp, X"84", 0, frameCnt); axiSlaveRegister(axilEp, X"F0", 0, v.rollOverEn); axiSlaveRegister(axilEp, X"F4", 0, v.bypCheck); axiSlaveRegisterR(axilEp, X"F8", 0, toSlv(PRBS_SEED_SIZE_G, 32)); diff --git a/protocols/ssi/rtl/SsiPrbsTx.vhd b/protocols/ssi/rtl/SsiPrbsTx.vhd index 684407433a..6f29b660cd 100644 --- a/protocols/ssi/rtl/SsiPrbsTx.vhd +++ b/protocols/ssi/rtl/SsiPrbsTx.vhd @@ -93,8 +93,10 @@ architecture rtl of SsiPrbsTx is DATA_S); type RegType is record + cntRst : sl; busy : sl; overflow : sl; + frameCnt : slv(31 downto 0); length : slv(31 downto 0); packetLength : slv(31 downto 0); dataCnt : slv(31 downto 0); @@ -116,8 +118,10 @@ architecture rtl of SsiPrbsTx is end record; constant REG_INIT_C : RegType := ( + cntRst => '1', busy => '1', overflow => '0', + frameCnt => (others => '0'), length => (others => '0'), packetLength => AXI_DEFAULT_PKT_LEN_G, dataCnt => (others => '0'), @@ -155,6 +159,9 @@ begin -- Latch the current value v := r; + -- Reset strobes + v.cntRst := '0'; + ---------------------------------------------------------------------------------------------- -- Axi-Lite Registers ---------------------------------------------------------------------------------------------- @@ -178,6 +185,9 @@ begin axiSlaveRegisterR(axilEp, X"1C", 0, r.trigDly); axiSlaveRegisterR(axilEp, X"20", 0, toSlv(PRBS_SEED_SIZE_G, 32)); + axiSlaveRegisterR(axilEp, X"24", 0, r.frameCnt); + + axiWrDetect(axilEp, X"FC", v.cntRst); axiSlaveDefault(axilEp, v.axilWriteSlave, v.axilReadSlave, AXI_RESP_DECERR_C); @@ -266,6 +276,8 @@ begin v.dataCnt := r.dataCnt + 1; -- Set the SOF bit ssiSetUserSof(PRBS_SSI_CONFIG_C, v.txAxisMaster, '1'); + -- Count the frame + v.frameCnt := r.frameCnt + 1; -- Next State v.state := LENGTH_S; end if; @@ -320,6 +332,11 @@ begin ---------------------------------------------------------------------- end case; + -- Check for counter reset + if (r.cntRst = '1') then + v.frameCnt := (others=>'0'); + end if; + -- Reset if (RST_ASYNC_G = false and locRst = '1') then v := REG_INIT_C; diff --git a/python/surf/protocols/ssi/_SsiPrbsRx.py b/python/surf/protocols/ssi/_SsiPrbsRx.py index 43fd4df738..145547d512 100644 --- a/python/surf/protocols/ssi/_SsiPrbsRx.py +++ b/python/surf/protocols/ssi/_SsiPrbsRx.py @@ -195,6 +195,15 @@ def __init__(self, pollInterval = 1, )) + self.add(pr.RemoteVariable( + name = "FrameCnt", + description = "", + offset = 0x84, + bitSize = 32, + mode = "RO", + pollInterval = 1, + )) + self.add(pr.RemoteVariable( name = "RolloverEnable", description = "", diff --git a/python/surf/protocols/ssi/_SsiPrbsTx.py b/python/surf/protocols/ssi/_SsiPrbsTx.py index 2051277a27..8621f36f3e 100644 --- a/python/surf/protocols/ssi/_SsiPrbsTx.py +++ b/python/surf/protocols/ssi/_SsiPrbsTx.py @@ -161,6 +161,23 @@ def __init__(self, clock_freq=125e6, **kwargs): mode = "RW", )) + self.add(pr.RemoteVariable( + name = "FrameCnt", + description = "", + offset = 0x24, + bitSize = 32, + mode = "RO", + pollInterval = 1, + )) + + self.add(pr.RemoteCommand( + name = "CountReset", + description = "Status counter reset", + offset = 0xFC, + bitSize = 1, + function = pr.BaseCommand.touchOne + )) + def get_conv(read): return clock_freq / (self.TrigDly.get(read=read)+1) @@ -179,3 +196,6 @@ def set_conv(value, write): mode = 'RW', linkedGet = get_conv, linkedSet = set_conv)) + + def countReset(self): + self.CountReset() diff --git a/yaml/Dac38J84.yaml b/yaml/Dac38J84.yaml index e7ccc4da63..a22c574e3b 100644 --- a/yaml/Dac38J84.yaml +++ b/yaml/Dac38J84.yaml @@ -16,7 +16,7 @@ Dac38J84: &Dac38J84 class: MMIODev configPrio: 1 metadata: - numTxLanes: &numTxLanes 2 + numTxLanes: &numTxLanes 8 children: ######################################################### DacReg: @@ -29,6 +29,14 @@ Dac38J84: &Dac38J84 mode: RW description: DAC Registers[125:0] ######################################################### + LaneEnable: + at: + offset: 0x129 + class: IntField + sizeBits: 8 + mode: RO + description: Lane Enable + ######################################################### LaneBufferDelay: at: offset: 0x01C