Skip to content

Commit

Permalink
merge pre-release into ldmx-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
cbakalis-slac committed Mar 5, 2024
2 parents 7bf9521 + af26985 commit 46a10e5
Show file tree
Hide file tree
Showing 36 changed files with 1,011 additions and 629 deletions.
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

Copyright (c) 2023, The Board of Trustees of the Leland Stanford Junior
Copyright (c) 2024, 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
Expand Down
171 changes: 77 additions & 94 deletions axi/axi-stream/rtl/AxiStreamRingBuffer.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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',
Expand All @@ -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);
Expand All @@ -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'),
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand Down Expand Up @@ -495,16 +471,23 @@ 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
v.wordCnt := axilR.wordCnt + 1;
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;

Expand Down
Loading

0 comments on commit 46a10e5

Please sign in to comment.