From d08516555ac974ab7e256f2e8c61bb138a2fa696 Mon Sep 17 00:00:00 2001 From: Marcio Donadio Date: Thu, 22 Feb 2024 16:31:29 -0800 Subject: [PATCH 1/7] Wrong indentation was preventing the loop from reaching all files --- scripts/apply_slac_license.py | 42 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/scripts/apply_slac_license.py b/scripts/apply_slac_license.py index ecaa4f5e38..6ba73d5ea6 100644 --- a/scripts/apply_slac_license.py +++ b/scripts/apply_slac_license.py @@ -118,30 +118,30 @@ def updateFile(path,module,comment,log,script): src = "%s/%s" % (root,f) ret = None - # Skip .svn sub-directories - if f.find(".svn") > 0: - logFile.write("Ignored: %s\n" % (src)) + # Skip .svn sub-directories + if f.find(".svn") > 0: + logFile.write("Ignored: %s\n" % (src)) - # VHDL - elif f.endswith(".vhd"): - updateFile(src,module,"--",logFile,False) + # VHDL + elif f.endswith(".vhd"): + updateFile(src,module,"--",logFile,False) - # C files - elif f.endswith(".h") or f.endswith(".hh") or f.endswith(".c") or f.endswith(".cc") or f.endswith(".cpp"): - updateFile(src,module,"//",logFile,False) + # C files + elif f.endswith(".h") or f.endswith(".hh") or f.endswith(".c") or f.endswith(".cc") or f.endswith(".cpp"): + updateFile(src,module,"//",logFile,False) - # Verilog, Verilog, or System Verilog - elif f.endswith(".v") or f.endswith(".vh") or f.endswith(".sv"): - updateFile(src,module,"//",logFile,False) + # Verilog, Verilog, or System Verilog + elif f.endswith(".v") or f.endswith(".vh") or f.endswith(".sv"): + updateFile(src,module,"//",logFile,False) - # TCL / XDC - elif f.endswith(".tcl") or f.endswith(".xdc"): - updateFile(src,module,"##",logFile,False) + # TCL / XDC + elif f.endswith(".tcl") or f.endswith(".xdc"): + updateFile(src,module,"##",logFile,False) - # Python - elif f.endswith(".py"): - updateFile(src,module,"##",logFile,True) + # Python + elif f.endswith(".py"): + updateFile(src,module,"##",logFile,True) - # Unknown - else: - logFile.write("Unknown: %s\n" % (src)) + # Unknown + else: + logFile.write("Unknown: %s\n" % (src)) From 0fd160517108f21eaaeea0056e5a74ffea1711ad Mon Sep 17 00:00:00 2001 From: Marcio Donadio Date: Thu, 22 Feb 2024 16:32:20 -0800 Subject: [PATCH 2/7] Fixed typo in help message --- scripts/apply_slac_license.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/apply_slac_license.py b/scripts/apply_slac_license.py index 6ba73d5ea6..c040f4bafa 100644 --- a/scripts/apply_slac_license.py +++ b/scripts/apply_slac_license.py @@ -100,7 +100,7 @@ def updateFile(path,module,comment,log,script): # Check args if len(sys.argv) < 3: - print ("Usage: apply_license.py root_dir module_name") + print ("Usage: apply_slac_license.py root_dir module_name") exit() module = sys.argv[2] From b0e0c028c841351687bd248aa0a1a1f4828c10dd Mon Sep 17 00:00:00 2001 From: Marcio Donadio Date: Thu, 22 Feb 2024 16:52:55 -0800 Subject: [PATCH 3/7] Provided an optional argument so the user can choose the location of the LICENSE.txt file --- scripts/apply_slac_license.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scripts/apply_slac_license.py b/scripts/apply_slac_license.py index c040f4bafa..06645bcd84 100644 --- a/scripts/apply_slac_license.py +++ b/scripts/apply_slac_license.py @@ -100,17 +100,27 @@ def updateFile(path,module,comment,log,script): # Check args if len(sys.argv) < 3: - print ("Usage: apply_slac_license.py root_dir module_name") + print ("Usage: apply_slac_license.py root_dir module_name [optional path_to_license]") exit() module = sys.argv[2] path = sys.argv[1] +# Path to license is an optional argument +license_path = "" +if len(sys.argv) == 4: + license_path = sys.argv[3] logFile = open (path + "/apply_license_log.txt","w") # Copy license file -baseDir = os.path.realpath(__file__).split('surf')[0] -shutil.copy(baseDir+"surf/LICENSE.txt",path + "/LICENSE.txt") +if license_path != "": + # Use user defined directory + baseDir = os.path.realpath(license_path) + shutil.copy(baseDir + "/LICENSE.txt", path + "/LICENSE.txt") +else: + # Use surf default directory + baseDir = os.path.realpath(__file__).split('surf')[0] + shutil.copy(baseDir + "surf/LICENSE.txt", path + "/LICENSE.txt") # Walk directories recursively for root,dirs,files in os.walk(path): From 2c342a06828cb35fc7d608b6d046a777c8d82ccf Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Sun, 25 Feb 2024 20:41:53 -0800 Subject: [PATCH 4/7] adding support for Ultrascale Virtex Part Numbers in ruckus.tcl loading Discovered by @AnthonyL01 while working on KLM Trigger firmware for Belle-2 --- devices/AnalogDevices/ad9249/ruckus.tcl | 1 + devices/AnalogDevices/ad9681/ruckus.tcl | 1 + devices/Marvell/Sgmii88E1111/ruckus.tcl | 1 + devices/Ti/dp83867/ruckus.tcl | 1 + ethernet/GigEthCore/ruckus.tcl | 3 ++- ethernet/TenGigEthCore/ruckus.tcl | 3 ++- ethernet/XauiCore/ruckus.tcl | 3 ++- ethernet/XlauiCore/ruckus.tcl | 3 ++- protocols/clink/ruckus.tcl | 1 + protocols/coaxpress/ruckus.tcl | 3 ++- protocols/pgp/pgp2b/ruckus.tcl | 3 ++- protocols/pgp/pgp3/ruckus.tcl | 3 ++- protocols/pgp/pgp4/ruckus.tcl | 3 ++- protocols/salt/ruckus.tcl | 1 + protocols/ssp/ruckus.tcl | 1 + protocols/xvc-udp/ruckus.tcl | 1 + xilinx/ruckus.tcl | 3 ++- 17 files changed, 26 insertions(+), 9 deletions(-) diff --git a/devices/AnalogDevices/ad9249/ruckus.tcl b/devices/AnalogDevices/ad9249/ruckus.tcl index 3ae406e9b4..35ed2898d2 100644 --- a/devices/AnalogDevices/ad9249/ruckus.tcl +++ b/devices/AnalogDevices/ad9249/ruckus.tcl @@ -16,6 +16,7 @@ if { ${family} eq {artix7} || } if { ${family} eq {kintexu} || + ${family} eq {virtexu} || ${family} eq {kintexuplus} || ${family} eq {virtexuplus} || ${family} eq {virtexuplusHBM} || diff --git a/devices/AnalogDevices/ad9681/ruckus.tcl b/devices/AnalogDevices/ad9681/ruckus.tcl index 9624424dd4..ec7c6fe333 100644 --- a/devices/AnalogDevices/ad9681/ruckus.tcl +++ b/devices/AnalogDevices/ad9681/ruckus.tcl @@ -16,6 +16,7 @@ if { ${family} eq {artix7} || } # if { ${family} eq {kintexu} || + # ${family} eq {virtexu} || # ${family} eq {kintexuplus} || # ${family} eq {virtexuplus} || # ${family} eq {virtexuplusHBM} || diff --git a/devices/Marvell/Sgmii88E1111/ruckus.tcl b/devices/Marvell/Sgmii88E1111/ruckus.tcl index 09b0940c24..d666dee69d 100644 --- a/devices/Marvell/Sgmii88E1111/ruckus.tcl +++ b/devices/Marvell/Sgmii88E1111/ruckus.tcl @@ -8,6 +8,7 @@ loadSource -lib surf -dir "$::DIR_PATH/core" set family [getFpgaArch] if { ${family} eq {kintexu} || + ${family} eq {virtexu} || ${family} eq {kintexuplus} || ${family} eq {virtexuplus} || ${family} eq {virtexuplusHBM} || diff --git a/devices/Ti/dp83867/ruckus.tcl b/devices/Ti/dp83867/ruckus.tcl index 09b0940c24..d666dee69d 100644 --- a/devices/Ti/dp83867/ruckus.tcl +++ b/devices/Ti/dp83867/ruckus.tcl @@ -8,6 +8,7 @@ loadSource -lib surf -dir "$::DIR_PATH/core" set family [getFpgaArch] if { ${family} eq {kintexu} || + ${family} eq {virtexu} || ${family} eq {kintexuplus} || ${family} eq {virtexuplus} || ${family} eq {virtexuplusHBM} || diff --git a/ethernet/GigEthCore/ruckus.tcl b/ethernet/GigEthCore/ruckus.tcl index e308b50d2a..b084a5dfef 100644 --- a/ethernet/GigEthCore/ruckus.tcl +++ b/ethernet/GigEthCore/ruckus.tcl @@ -27,7 +27,8 @@ if { ${family} eq {virtex7} } { loadRuckusTcl "$::DIR_PATH/gth7" } -if { ${family} eq {kintexu} } { +if { ${family} eq {kintexu} || + ${family} eq {virtexu} } { loadRuckusTcl "$::DIR_PATH/gthUltraScale" loadRuckusTcl "$::DIR_PATH/lvdsUltraScale" } diff --git a/ethernet/TenGigEthCore/ruckus.tcl b/ethernet/TenGigEthCore/ruckus.tcl index 7098fae39f..b8ede006a5 100644 --- a/ethernet/TenGigEthCore/ruckus.tcl +++ b/ethernet/TenGigEthCore/ruckus.tcl @@ -16,7 +16,8 @@ if { ${family} eq {virtex7} } { loadRuckusTcl "$::DIR_PATH/gth7" } -if { ${family} eq {kintexu} } { +if { ${family} eq {kintexu} || + ${family} eq {virtexu} } { loadRuckusTcl "$::DIR_PATH/gthUltraScale" } diff --git a/ethernet/XauiCore/ruckus.tcl b/ethernet/XauiCore/ruckus.tcl index 7098fae39f..b8ede006a5 100644 --- a/ethernet/XauiCore/ruckus.tcl +++ b/ethernet/XauiCore/ruckus.tcl @@ -16,7 +16,8 @@ if { ${family} eq {virtex7} } { loadRuckusTcl "$::DIR_PATH/gth7" } -if { ${family} eq {kintexu} } { +if { ${family} eq {kintexu} || + ${family} eq {virtexu} } { loadRuckusTcl "$::DIR_PATH/gthUltraScale" } diff --git a/ethernet/XlauiCore/ruckus.tcl b/ethernet/XlauiCore/ruckus.tcl index d59855b677..b68420a2de 100644 --- a/ethernet/XlauiCore/ruckus.tcl +++ b/ethernet/XlauiCore/ruckus.tcl @@ -16,7 +16,8 @@ if { ${family} eq {virtex7} } { loadRuckusTcl "$::DIR_PATH/gth7" } -if { ${family} eq {kintexu} } { +if { ${family} eq {kintexu} || + ${family} eq {virtexu} } { loadRuckusTcl "$::DIR_PATH/gthUltraScale" } diff --git a/protocols/clink/ruckus.tcl b/protocols/clink/ruckus.tcl index 5c507d0181..bdebcd1e53 100644 --- a/protocols/clink/ruckus.tcl +++ b/protocols/clink/ruckus.tcl @@ -18,6 +18,7 @@ if { ${family} == "artix7" || } if { ${family} eq {kintexu} || + ${family} eq {virtexu} || ${family} eq {kintexuplus} || ${family} eq {virtexuplus} || ${family} eq {virtexuplusHBM} || diff --git a/protocols/coaxpress/ruckus.tcl b/protocols/coaxpress/ruckus.tcl index c3de29fbbb..e5b28a0fab 100644 --- a/protocols/coaxpress/ruckus.tcl +++ b/protocols/coaxpress/ruckus.tcl @@ -7,7 +7,8 @@ loadRuckusTcl "$::DIR_PATH/core" # Get the family type set family [getFpgaArch] -if { ${family} eq {kintexu} } { +if { ${family} eq {kintexu} || + ${family} eq {virtexu} } { loadRuckusTcl "$::DIR_PATH/gthUs" } diff --git a/protocols/pgp/pgp2b/ruckus.tcl b/protocols/pgp/pgp2b/ruckus.tcl index 8449a987e8..2fea89839f 100644 --- a/protocols/pgp/pgp2b/ruckus.tcl +++ b/protocols/pgp/pgp2b/ruckus.tcl @@ -27,7 +27,8 @@ if { ${family} eq {virtex7} } { loadRuckusTcl "$::DIR_PATH/gth7" } -if { ${family} eq {kintexu} } { +if { ${family} eq {kintexu} || + ${family} eq {virtexu} } { loadRuckusTcl "$::DIR_PATH/gthUltraScale" } diff --git a/protocols/pgp/pgp3/ruckus.tcl b/protocols/pgp/pgp3/ruckus.tcl index 0d4b25db7d..4920c89b89 100644 --- a/protocols/pgp/pgp3/ruckus.tcl +++ b/protocols/pgp/pgp3/ruckus.tcl @@ -30,7 +30,8 @@ if { $::env(VIVADO_VERSION) > 0.0} { # loadRuckusTcl "$::DIR_PATH/gth7" # } - if { ${family} eq {kintexu} } { + if { ${family} eq {kintexu} || + ${family} eq {virtexu} } { loadRuckusTcl "$::DIR_PATH/gthUs" } diff --git a/protocols/pgp/pgp4/ruckus.tcl b/protocols/pgp/pgp4/ruckus.tcl index 201f478e2d..d312aa110b 100644 --- a/protocols/pgp/pgp4/ruckus.tcl +++ b/protocols/pgp/pgp4/ruckus.tcl @@ -30,7 +30,8 @@ if { $::env(VIVADO_VERSION) > 0.0} { # loadRuckusTcl "$::DIR_PATH/gth7" # } - if { ${family} eq {kintexu} } { + if { ${family} eq {kintexu} || + ${family} eq {virtexu} } { loadRuckusTcl "$::DIR_PATH/gthUs" } diff --git a/protocols/salt/ruckus.tcl b/protocols/salt/ruckus.tcl index 40d14bdca4..74d14f8095 100644 --- a/protocols/salt/ruckus.tcl +++ b/protocols/salt/ruckus.tcl @@ -12,6 +12,7 @@ if { ${family} eq {artix7} || } if { ${family} eq {kintexu} || + ${family} eq {virtexu} || ${family} eq {kintexuplus} || ${family} eq {virtexuplus} || ${family} eq {virtexuplusHBM} || diff --git a/protocols/ssp/ruckus.tcl b/protocols/ssp/ruckus.tcl index ccf9d8c2c8..925ca902a8 100644 --- a/protocols/ssp/ruckus.tcl +++ b/protocols/ssp/ruckus.tcl @@ -11,6 +11,7 @@ loadSource -lib surf -dir "$::DIR_PATH/rtl" loadSource -lib surf -sim_only -dir "$::DIR_PATH/tb" if { ${family} eq {kintexu} || + ${family} eq {virtexu} || ${family} eq {kintexuplus} || ${family} eq {virtexuplus} || ${family} eq {virtexuplusHBM} || diff --git a/protocols/xvc-udp/ruckus.tcl b/protocols/xvc-udp/ruckus.tcl index 5266224029..73c8578d5e 100644 --- a/protocols/xvc-udp/ruckus.tcl +++ b/protocols/xvc-udp/ruckus.tcl @@ -21,6 +21,7 @@ if { [isVersal] == true } { } if { ${family} eq {kintexu} || + ${family} eq {virtexu} || ${family} eq {kintexuplus} || ${family} eq {virtexuplus} || ${family} eq {virtexuplusHBM} || diff --git a/xilinx/ruckus.tcl b/xilinx/ruckus.tcl index 467a1d0066..471bb69da7 100644 --- a/xilinx/ruckus.tcl +++ b/xilinx/ruckus.tcl @@ -20,7 +20,8 @@ if { ${family} eq {artix7} || loadRuckusTcl "$::DIR_PATH/7Series" } -if { ${family} eq {kintexu} } { +if { ${family} eq {kintexu} || + ${family} eq {virtexu} } { loadRuckusTcl "$::DIR_PATH/UltraScale" } From dba05b3f128f556665268cef95dab9fdcbf9bf6f Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 26 Feb 2024 10:50:42 -0800 Subject: [PATCH 5/7] whitespace removal --- devices/AnalogDevices/ruckus.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devices/AnalogDevices/ruckus.tcl b/devices/AnalogDevices/ruckus.tcl index 0e92b6ce04..b77afd7118 100644 --- a/devices/AnalogDevices/ruckus.tcl +++ b/devices/AnalogDevices/ruckus.tcl @@ -13,5 +13,5 @@ if { $::env(VIVADO_VERSION) > 0.0} { # AD9249 sim model requires ClockManager7 loadSource -lib surf -path "$::DIR_PATH/../../xilinx/7Series/general/rtl/ClockManager7.vhd" - loadSource -lib surf -path "$::DIR_PATH/../../xilinx/7Series/general/rtl/ClockManager7Pkg.vhd" + loadSource -lib surf -path "$::DIR_PATH/../../xilinx/7Series/general/rtl/ClockManager7Pkg.vhd" } From 9ce3b4aa76dfa75121f3b6b3d90f2ccbbfc88fb6 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 26 Feb 2024 10:50:57 -0800 Subject: [PATCH 6/7] adding AxiStreamRingBufferTb.vhd --- axi/axi-stream/tb/AxiStreamRingBufferTb.vhd | 153 ++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 axi/axi-stream/tb/AxiStreamRingBufferTb.vhd diff --git a/axi/axi-stream/tb/AxiStreamRingBufferTb.vhd b/axi/axi-stream/tb/AxiStreamRingBufferTb.vhd new file mode 100644 index 0000000000..05d14f35db --- /dev/null +++ b/axi/axi-stream/tb/AxiStreamRingBufferTb.vhd @@ -0,0 +1,153 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Simulation Testbed for testing the AxiStreamRingBuffer module +------------------------------------------------------------------------------- +-- 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 AxiStreamRingBufferTb is end AxiStreamRingBufferTb; + +architecture testbed of AxiStreamRingBufferTb is + + constant CLK_PERIOD_C : time := 10 ns; + constant TPD_C : time := CLK_PERIOD_C/4; + + constant AXIS_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(dataBytes => 2); + + type RegType is record + extTrig : sl; + data : slv(15 downto 0); + cnt : slv(11 downto 0); + end record; + + constant REG_INIT_C : RegType := ( + extTrig => '0', + data => (others => '0'), + cnt => (others => '0')); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal clk : sl := '0'; + signal rst : sl := '1'; + + signal axilWriteMaster : AxiLiteWriteMasterType := AXI_LITE_WRITE_MASTER_INIT_C; + signal axilWriteSlave : AxiLiteWriteSlaveType := AXI_LITE_WRITE_SLAVE_INIT_C; + signal axilReadMaster : AxiLiteReadMasterType := AXI_LITE_READ_MASTER_INIT_C; + signal axilReadSlave : AxiLiteReadSlaveType := AXI_LITE_READ_SLAVE_INIT_C; + + signal axisMaster : AxiStreamMasterType := AXI_STREAM_MASTER_INIT_C; + signal axisSlave : AxiStreamSlaveType := AXI_STREAM_SLAVE_FORCE_C; + +begin + + --------------------------- + -- Generate clock and reset + --------------------------- + U_ClkRst : entity surf.ClkRst + generic map ( + CLK_PERIOD_G => CLK_PERIOD_C, + RST_START_DELAY_G => 0 ns, -- Wait this long into simulation before asserting reset + RST_HOLD_TIME_G => 1000 ns) -- Hold reset for this long) + port map ( + clkP => clk, + clkN => open, + rst => rst, + rstL => open); + + -------------------------- + -- Design Under Test (DUT) + -------------------------- + U_DUT : entity surf.AxiStreamRingBuffer + generic map ( + TPD_G => TPD_C, + COMMON_CLK_G => true, -- true if dataClk=axilClk + DATA_BYTES_G => 2, -- 16-bit data + RAM_ADDR_WIDTH_G => 10, -- 1k samples deep + -- AXI Stream Configurations + GEN_SYNC_FIFO_G => true, -- true if axisClk=axilClk + AXI_STREAM_CONFIG_G => AXIS_CONFIG_C) + port map ( + -- Data to store in ring buffer (dataClk domain) + dataClk => clk, + dataValue => r.data, + extTrig => r.extTrig, + -- AXI-Lite interface (axilClk domain) + axilClk => clk, + axilRst => rst, + axilReadMaster => axilReadMaster, + axilReadSlave => axilReadSlave, + axilWriteMaster => axilWriteMaster, + axilWriteSlave => axilWriteSlave, + -- AXI-Stream Interface (axilClk domain) + axisClk => clk, + axisRst => rst, + axisMaster => axisMaster, + axisSlave => axisSlave); + + comb : process (r, rst) is + variable v : RegType; + begin + -- Latch the current value + v := r; + + -- Reset the strobes + v.extTrig := '0'; + + -- Check if increment the counter + if (r.cnt /= x"FFF") then + + -- Increment the counter + v.cnt := r.cnt + 1; + + -- Check if making data pattern + if r.cnt < 1024 then + v.data := r.data + 1; + else + v.data := (others => '0'); + end if; + + -- check for the trigger event + if (r.cnt = 1111) then + -- Set the flag + v.extTrig := '1'; + end if; + + end if; + + -- Synchronous Reset + if (rst = '1') then + v := REG_INIT_C; + end if; + + -- Register the variable for next clock cycle + rin <= v; + + end process comb; + + seq : process (clk) is + begin + if (rising_edge(clk)) then + r <= rin after TPD_C; + end if; + end process seq; + +end testbed; From 6dbf0571770e9829d3fe6dafaefba8cf8af3f7dd Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Mon, 26 Feb 2024 10:51:24 -0800 Subject: [PATCH 7/7] fixed bug in AxiStreamRingBuffer.vhd where not logging data before external trigger --- axi/axi-stream/rtl/AxiStreamRingBuffer.vhd | 171 ++++++++++----------- 1 file changed, 77 insertions(+), 94 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamRingBuffer.vhd b/axi/axi-stream/rtl/AxiStreamRingBuffer.vhd index 85857fa4ef..6dadeef295 100644 --- a/axi/axi-stream/rtl/AxiStreamRingBuffer.vhd +++ b/axi/axi-stream/rtl/AxiStreamRingBuffer.vhd @@ -29,7 +29,7 @@ entity AxiStreamRingBuffer is RST_ASYNC_G : boolean := false; SYNTH_MODE_G : string := "inferred"; MEMORY_TYPE_G : string := "block"; - COMMON_CLK_G : boolean := false; -- true if dataClk=axilClk + COMMON_CLK_G : boolean := false; -- true if dataClk=axilClk DATA_BYTES_G : positive := 16; RAM_ADDR_WIDTH_G : positive := 9; -- AXI Stream Configurations @@ -74,10 +74,7 @@ architecture rtl of AxiStreamRingBuffer is -- Stream clock domain signals ------------------------------ type DataRegType is record - extTrig : sl; - bufferEnable : sl; enable : sl; - cleared : sl; armed : sl; ramWrEn : sl; readReq : sl; @@ -88,10 +85,7 @@ architecture rtl of AxiStreamRingBuffer is end record; constant DATA_REG_INIT_C : DataRegType := ( - extTrig => '0', - bufferEnable => '0', - enable => '0', - cleared => '1', -- Only set HIGH after reset + enable => '1', -- Only set HIGH after reset armed => '0', ramWrEn => '0', readReq => '0', @@ -103,26 +97,26 @@ architecture rtl of AxiStreamRingBuffer is signal dataR : DataRegType := DATA_REG_INIT_C; signal dataRin : DataRegType; - signal bufferEnableSync : sl; - signal bufferClearSync : sl; + signal softTrigSync : sl; + signal bufferClearSync : sl; -------------------------------- -- AXI-Lite clock domain signals -------------------------------- type DataStateType is ( IDLE_S, - MOVE_S); + MOVE_S, + CLEARED_S); type TrigStateType is ( IDLE_S, - CLEAR_S, ARMED_S, WAIT_S); type AxilRegType is record trigCnt : slv(31 downto 0); continuous : sl; - bufferEnable : sl; + softTrig : sl; bufferClear : sl; wordCnt : slv(RAM_ADDR_WIDTH_G-1 downto 0); ramRdAddr : slv(RAM_ADDR_WIDTH_G-1 downto 0); @@ -137,7 +131,7 @@ architecture rtl of AxiStreamRingBuffer is constant AXIL_REG_INIT_C : AxilRegType := ( trigCnt => (others => '0'), continuous => '0', - bufferEnable => '0', + softTrig => '0', bufferClear => '0', wordCnt => (others => '0'), ramRdAddr => (others => '0'), @@ -159,7 +153,6 @@ architecture rtl of AxiStreamRingBuffer is signal bufferLength : slv(RAM_ADDR_WIDTH_G-1 downto 0); signal readReq : sl; - signal cleared : sl; signal armed : sl; signal txSlave : AxiStreamSlaveType; @@ -238,32 +231,24 @@ begin -------------------------------------------------- -- Synchronize AXI registers to data clock dataClk -------------------------------------------------- - U_bufferEnable : entity surf.Synchronizer + U_SyncVec_dataClk : entity surf.SynchronizerVector generic map ( TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G) - port map ( - clk => dataClk, - rst => dataRst, - dataIn => axilR.bufferEnable, - dataOut => bufferEnableSync); - - U_bufferClear : entity surf.SynchronizerOneShot - generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - PULSE_WIDTH_G => 10) + RST_ASYNC_G => RST_ASYNC_G, + WIDTH_G => 2) port map ( - clk => dataClk, - rst => dataRst, - dataIn => axilR.bufferClear, - dataOut => bufferClearSync); + clk => dataClk, + rst => dataRst, + dataIn(0) => axilR.softTrig, + dataIn(1) => axilR.bufferClear, + dataOut(0) => softTrigSync, + dataOut(1) => bufferClearSync); -------------------------- -- Main AXI-Stream process -------------------------- - dataComb : process (bufferClearSync, bufferEnableSync, dataR, dataRst, - dataValid, dataValue, extTrig) is + dataComb : process (bufferClearSync, dataR, dataRst, dataValid, dataValue, + extTrig, softTrigSync) is variable v : DataRegType; begin -- Latch the current value @@ -272,38 +257,43 @@ begin -- Reset strobes v.ramWrEn := '0'; v.readReq := '0'; - v.cleared := '0'; - - -- Check for external trigger - if (extTrig = '1') and (dataR.extTrig = '0') then - v.extTrig := '1'; - v.bufferEnable := '1'; - end if; - -- Default assignment + -- Register data value to help with making timing v.ramWrData := dataValue; - v.enable := bufferEnableSync or dataR.bufferEnable; - - -- Increment the addresses on each valid if logging enabled - if (dataValid = '1') and (dataR.enable = '1') then - -- Trigger a write - v.ramWrEn := '1'; - - -- Increment the address - v.nextAddr := dataR.nextAddr + 1; - -- Check if the write pointer = read pointer - if (v.nextAddr = dataR.firstAddr) then - v.firstAddr := dataR.firstAddr + 1; - v.armed := '1'; - v.bufferEnable := '0'; + + -- Check if ring buffer is logging + if (dataR.enable = '1') then + + -- Check for valid data to write + if (dataValid = '1') then + + -- Trigger a write + v.ramWrEn := '1'; + + -- Increment the address + v.nextAddr := dataR.nextAddr + 1; + -- Check if the write pointer = read pointer + if (v.nextAddr = dataR.firstAddr) then + v.firstAddr := dataR.firstAddr + 1; + v.armed := '1'; + end if; + + -- Calculate the length of the buffer + v.bufferLength := dataR.nextAddr - dataR.firstAddr; + + end if; + + -- Check for a trigger event to stop the logging + if (extTrig = '1') or (softTrigSync = '1') then + + -- Stop the logging in the ring buffer + v.enable := '0'; + + -- Make a read request event + v.readReq := '1'; + end if; - -- Calculate the length of the buffer - v.bufferLength := dataR.nextAddr - dataR.firstAddr; - end if; - -- Check for read request event - if (dataR.enable = '1') and (v.enable = '0') then - v.readReq := '1'; end if; -- Synchronous Reset @@ -354,21 +344,18 @@ begin generic map ( TPD_G => TPD_G, RST_ASYNC_G => RST_ASYNC_G, - WIDTH_G => 2) + WIDTH_G => 1) port map ( clk => axilClk, rst => axilRst, - dataIn(0) => dataR.cleared, - dataIn(1) => dataR.armed, - dataOut(0) => cleared, - dataOut(1) => armed); + dataIn(0) => dataR.armed, + dataOut(0) => armed); ------------------------ -- Main AXI-Lite process ------------------------ axiComb : process (armed, axilR, axilReadMaster, axilRst, axilWriteMaster, - bufferLength, cleared, firstAddr, ramRdData, readReq, - txSlave) is + bufferLength, firstAddr, ramRdData, readReq, txSlave) is variable v : AxilRegType; variable axilEp : AxiLiteEndpointType; begin @@ -401,44 +388,30 @@ begin case axilR.trigState is ---------------------------------------------------------------------- when IDLE_S => - -- Check for trigger request + -- Check for software trigger request if ((axilR.trigCnt /= 0) or (axilR.continuous = '1')) and (axilR.dataState = IDLE_S) then - -- Set the flags - v.bufferEnable := '1'; - v.bufferClear := '1'; + -- Check if we need to decrement the counter if (axilR.trigCnt /= 0) then -- Decrement the counter v.trigCnt := axilR.trigCnt - 1; end if; + -- Next state - v.trigState := CLEAR_S; - else - -- Reset the flag - v.bufferEnable := '0'; - end if; - ---------------------------------------------------------------------- - when CLEAR_S => - -- Check if cleared - if (cleared = '1') then - -- Set the flag - v.bufferEnable := '1'; - -- Next state - v.trigState := ARMED_S; + v.trigState := ARMED_S; + end if; ---------------------------------------------------------------------- when ARMED_S => -- Check if armed if (armed = '1') then - -- Set the flag - v.bufferEnable := '0'; -- Next state - v.trigState := WAIT_S; + v.trigState := WAIT_S; end if; ---------------------------------------------------------------------- when WAIT_S => - -- Set the flag - v.bufferEnable := '0'; + -- Hold the trigger until cleared by (axilR.dataState = IDLE_S) + v.softTrig := '1'; ---------------------------------------------------------------------- end case; @@ -465,6 +438,9 @@ begin -- Check for trigger event if (readReq = '1') then + -- Reset the flag + v.softTrig := '0'; + -- Next state v.dataState := MOVE_S; @@ -495,9 +471,8 @@ begin -- Set the clear flag v.bufferClear := '1'; - -- Next states - v.dataState := IDLE_S; - v.trigState := IDLE_S; + -- Next state + v.dataState := CLEARED_S; else -- Increment the counter @@ -505,6 +480,14 @@ begin end if; end if; + ---------------------------------------------------------------------- + when CLEARED_S => + -- Check if armed de-asserted + if (armed = '0') then + -- Next states + v.dataState := IDLE_S; + v.trigState := IDLE_S; + end if; ---------------------------------------------------------------------- end case;