Skip to content

Commit

Permalink
Merge pull request #1142 from slaclab/kek-bpm-ring-buffer-fix
Browse files Browse the repository at this point in the history
AxiStreamRingBuffer Bug fix and whitespace removal
  • Loading branch information
ruck314 authored Feb 26, 2024
2 parents 3475d47 + 6dbf057 commit 5320859
Show file tree
Hide file tree
Showing 3 changed files with 231 additions and 95 deletions.
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 5320859

Please sign in to comment.