Skip to content

Commit

Permalink
Merge pull request #581 from slaclab/AxiStreamMonitoring-update
Browse files Browse the repository at this point in the history
Axi stream monitoring updates
  • Loading branch information
ruck314 authored Jan 9, 2020
2 parents 6f95c28 + f0212af commit fcc76a0
Show file tree
Hide file tree
Showing 6 changed files with 479 additions and 212 deletions.
88 changes: 66 additions & 22 deletions axi/axi-stream/rtl/AxiStreamMon.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ 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.AxiStreamPkg.all;
Expand All @@ -38,6 +37,9 @@ entity AxiStreamMon is
statusClk : in sl;
statusRst : in sl;
frameCnt : out slv(63 downto 0); -- units of frames
frameSize : out slv(31 downto 0); -- units of Byte
frameSizeMax : out slv(31 downto 0); -- units of Byte
frameSizeMin : out slv(31 downto 0); -- units of Byte
frameRate : out slv(31 downto 0); -- units of Hz
frameRateMax : out slv(31 downto 0); -- units of Hz
frameRateMin : out slv(31 downto 0); -- units of Hz
Expand All @@ -52,25 +54,33 @@ architecture rtl of AxiStreamMon is
constant TIMEOUT_C : natural := getTimeRatio(AXIS_CLK_FREQ_G, 1.0)-1;

type RegType is record
frameSent : sl;
tValid : sl;
tKeep : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0);
updated : sl;
timer : natural range 0 to TIMEOUT_C;
accum : slv(39 downto 0);
bandwidth : slv(39 downto 0);
frameCnt : slv(63 downto 0);
frameSent : sl;
sizeValid : sl;
armed : sl;
tValid : sl;
tKeep : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0);
updated : sl;
timer : natural range 0 to TIMEOUT_C;
accum : slv(39 downto 0);
bandwidth : slv(39 downto 0);
frameAccum : slv(31 downto 0);
frameSize : slv(31 downto 0);
frameCnt : slv(63 downto 0);
end record;

constant REG_INIT_C : RegType := (
frameSent => '0',
tValid => '0',
tKeep => (others => '0'),
updated => '0',
timer => 0,
accum => (others => '0'),
bandwidth => (others => '0'),
frameCnt => (others => '0'));
frameSent => '0',
sizeValid => '0',
armed => '0',
tValid => '0',
tKeep => (others => '0'),
updated => '0',
timer => 0,
accum => (others => '0'),
bandwidth => (others => '0'),
frameAccum => (others => '0'),
frameSize => (others => '0'),
frameCnt => (others => '0'));

signal r : RegType := REG_INIT_C;
signal rin : RegType;
Expand Down Expand Up @@ -164,8 +174,9 @@ begin
v := r;

-- Reset strobing signals
v.tValid := '0';
v.updated := '0';
v.tValid := '0';
v.updated := '0';
v.sizeValid := '0';

-- Check for end of frame
v.frameSent := axisMaster.tValid and axisMaster.tLast and axisSlave.tReady;
Expand All @@ -184,13 +195,28 @@ begin
end if;

-- Check if last cycle had data moving
if r.tValid = '1' then
if (r.tValid = '1') then

-- Update the accumulator
if (AXIS_CONFIG_G.TKEEP_MODE_C = TKEEP_COUNT_C) then
v.accum := r.accum + conv_integer(r.tKeep(bitSize(AXIS_CONFIG_G.TDATA_BYTES_C)-1 downto 0));
v.accum := r.accum + conv_integer(r.tKeep(bitSize(AXIS_CONFIG_G.TDATA_BYTES_C)-1 downto 0));
v.frameAccum := r.frameAccum + conv_integer(r.tKeep(bitSize(AXIS_CONFIG_G.TDATA_BYTES_C)-1 downto 0));
else
v.accum := r.accum + getTKeep(r.tKeep, AXIS_CONFIG_G);
v.accum := r.accum + getTKeep(r.tKeep, AXIS_CONFIG_G);
v.frameAccum := r.frameAccum + getTKeep(r.tKeep, AXIS_CONFIG_G);
end if;

-- Check for end of frame
if (r.frameSent = '1') then
-- Set the flag
v.sizeValid := r.armed;
v.frameSize := v.frameAccum;
-- Reset the accumulator
v.frameAccum := (others => '0');
-- Confirmed that not in the middle of a frame since reset
v.armed := '1';
end if;

end if;

-- Increment the timer
Expand Down Expand Up @@ -232,6 +258,24 @@ begin
end if;
end process seq;

Sync_frameSize : entity surf.SyncMinMax
generic map (
TPD_G => TPD_G,
COMMON_CLK_G => COMMON_CLK_G,
WIDTH_G => 32)
port map (
-- ASYNC statistics reset
rstStat => axisRst,
-- Write Interface (wrClk domain)
wrClk => axisClk,
wrEn => r.sizeValid,
dataIn => r.frameSize,
-- Read Interface (rdClk domain)
rdClk => statusClk,
dataOut => frameSize,
dataMin => frameSizeMin,
dataMax => frameSizeMax);

Sync_bandwidth : entity surf.SyncMinMax
generic map (
TPD_G => TPD_G,
Expand Down
141 changes: 106 additions & 35 deletions axi/axi-stream/rtl/AxiStreamMonAxiL.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ 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.AxiStreamPkg.all;
Expand Down Expand Up @@ -52,17 +51,17 @@ architecture rtl of AxiStreamMonAxiL is
type RegType is record
we : sl;
data : slv(31 downto 0);
cnt : slv(ADDR_WIDTH_C-1 downto 0);
addr : slv(ADDR_WIDTH_C-1 downto 0);
ch : natural range 0 to AXIS_NUM_SLOTS_G-1;
wrd : natural range 0 to 15;
end record;

constant REG_INIT_C : RegType := (
we => '0',
data => (others => '0'),
cnt => (others => '1'), -- pre-set to all ones so 1st write after reset is address=0x0
addr => (others => '1'), -- pre-set to all ones so 1st write after reset is address=0x0
ch => 0,
wrd => 0);
ch => 0);

signal r : RegType := REG_INIT_C;
signal rin : RegType;
Expand All @@ -71,16 +70,35 @@ architecture rtl of AxiStreamMonAxiL is
signal localReset : sl;
signal axisReset : sl;

signal frameCnt : Slv64Array(AXIS_NUM_SLOTS_G-1 downto 0);
signal frameCnt : Slv64Array(AXIS_NUM_SLOTS_G-1 downto 0);

signal frameSize : Slv32Array(AXIS_NUM_SLOTS_G-1 downto 0);
signal frameSizeMax : Slv32Array(AXIS_NUM_SLOTS_G-1 downto 0);
signal frameSizeMin : Slv32Array(AXIS_NUM_SLOTS_G-1 downto 0);

signal frameRate : Slv32Array(AXIS_NUM_SLOTS_G-1 downto 0);
signal frameRateMax : Slv32Array(AXIS_NUM_SLOTS_G-1 downto 0);
signal frameRateMin : Slv32Array(AXIS_NUM_SLOTS_G-1 downto 0);

signal bandwidth : Slv64Array(AXIS_NUM_SLOTS_G-1 downto 0);
signal bandwidthMax : Slv64Array(AXIS_NUM_SLOTS_G-1 downto 0);
signal bandwidthMin : Slv64Array(AXIS_NUM_SLOTS_G-1 downto 0);

-- attribute dont_touch : string;
-- attribute dont_touch of r : signal is "true";
-- attribute dont_touch : string;
-- attribute dont_touch of r : signal is "true";
-- attribute dont_touch of rstCnt : signal is "true";
-- attribute dont_touch of localReset : signal is "true";
-- attribute dont_touch of axisReset : signal is "true";
-- attribute dont_touch of frameCnt : signal is "true";
-- attribute dont_touch of frameSize : signal is "true";
-- attribute dont_touch of frameSizeMax : signal is "true";
-- attribute dont_touch of frameSizeMin : signal is "true";
-- attribute dont_touch of frameRate : signal is "true";
-- attribute dont_touch of frameRateMax : signal is "true";
-- attribute dont_touch of frameRateMin : signal is "true";
-- attribute dont_touch of bandwidth : signal is "true";
-- attribute dont_touch of bandwidthMax : signal is "true";
-- attribute dont_touch of bandwidthMin : signal is "true";

begin

Expand Down Expand Up @@ -112,13 +130,20 @@ begin
axisRst => axisReset,
axisMaster => axisMasters(i),
axisSlave => axisSlaves(i),
-- Status Interface
-- Status Clock and reset
statusClk => axisClk,
statusRst => axisReset,
-- Status: Total number of frame received since statusRst
frameCnt => frameCnt(i),
-- Status: Frame Size (units of Byte)
frameSize => frameSize(i),
frameSizeMax => frameSizeMax(i),
frameSizeMin => frameSizeMin(i),
-- Status: Frame rate (units of Hz)
frameRate => frameRate(i),
frameRateMax => frameRateMax(i),
frameRateMin => frameRateMin(i),
-- Status: Bandwidth (units of Byte/s)
bandwidth => bandwidth(i),
bandwidthMax => bandwidthMax(i),
bandwidthMin => bandwidthMin(i));
Expand Down Expand Up @@ -152,50 +177,96 @@ begin
din => r.data);

comb : process (axisRst, bandwidth, bandwidthMax, bandwidthMin, frameCnt,
frameRate, frameRateMax, frameRateMin, r) is
variable v : RegType;
frameRate, frameRateMax, frameRateMin, frameSize,
frameSizeMax, frameSizeMin, r) is
variable v : RegType;
variable wrd : slv(3 downto 0);
begin
-- Latch the current value
v := r;

-- Increment the counter
v.cnt := r.cnt + 1;

-- Write the status counter to RAM
v.we := '1';
v.addr := r.addr + 1;
case (r.wrd) is
----------------------------------------------------------------------
when 1 => v.data := frameCnt(r.ch)(31 downto 0); -- i*0x40 + 0x04
when 2 => v.data := frameCnt(r.ch)(63 downto 32); -- i*0x40 + 0x08
when 3 => v.data := frameRate(r.ch); -- i*0x40 + 0x0C
when 4 => v.data := frameRateMax(r.ch); -- i*0x40 + 0x10
when 5 => v.data := frameRateMin(r.ch); -- i*0x40 + 0x14
when 6 => v.data := bandwidth(r.ch)(31 downto 0); -- i*0x40 + 0x18
when 7 => v.data := bandwidth(r.ch)(63 downto 32); -- i*0x40 + 0x1C
when 8 => v.data := bandwidthMax(r.ch)(31 downto 0); -- i*0x40 + 0x20
when 9 => v.data := bandwidthMax(r.ch)(63 downto 32); -- i*0x40 + 0x24
when 10 => v.data := bandwidthMin(r.ch)(31 downto 0); -- i*0x40 + 0x28
when 11 => v.data := bandwidthMin(r.ch)(63 downto 32); -- i*0x40 + 0x2C
when others => v.we := '0';
----------------------------------------------------------------------
v.addr := v.cnt;

-- Case on the word index
wrd := v.addr(3 downto 0);
case (wrd) is
----------------------------------------------------------------------
when x"0" => -- i*0x40 + 0x00: DMA AXI Stream Configuration (debugging)

v.data(31 downto 24) := toSlv(AXIS_CONFIG_G.TDATA_BYTES_C, 8);
v.data(23 downto 20) := toSlv(AXIS_CONFIG_G.TDEST_BITS_C, 4);
v.data(19 downto 16) := toSlv(AXIS_CONFIG_G.TUSER_BITS_C, 4);
v.data(15 downto 12) := toSlv(AXIS_CONFIG_G.TID_BITS_C, 4);

case AXIS_CONFIG_G.TKEEP_MODE_C is
when TKEEP_NORMAL_C => v.data(11 downto 8) := x"0";
when TKEEP_COMP_C => v.data(11 downto 8) := x"1";
when TKEEP_FIXED_C => v.data(11 downto 8) := x"2";
when TKEEP_COUNT_C => v.data(11 downto 8) := x"3";
when others => v.data(11 downto 8) := x"F";
end case;

case AXIS_CONFIG_G.TUSER_MODE_C is
when TUSER_NORMAL_C => v.data(7 downto 4) := x"0";
when TUSER_FIRST_LAST_C => v.data(7 downto 4) := x"1";
when TUSER_LAST_C => v.data(7 downto 4) := x"2";
when TUSER_NONE_C => v.data(7 downto 4) := x"3";
when others => v.data(7 downto 4) := x"F";
end case;

v.data(3) := '0';
v.data(2) := '0';
v.data(1) := ite(AXIS_CONFIG_G.TSTRB_EN_C, '1', '0');
v.data(0) := ite(COMMON_CLK_G, '1', '0');

----------------------------------------------------------------------
when x"1" => v.data := frameCnt(r.ch)(31 downto 0); -- i*0x40 + 0x04
when x"2" => v.data := frameCnt(r.ch)(63 downto 32); -- i*0x40 + 0x08
----------------------------------------------------------------------
when x"3" => v.data := frameRate(r.ch); -- i*0x40 + 0x0C
when x"4" => v.data := frameRateMax(r.ch); -- i*0x40 + 0x10
when x"5" => v.data := frameRateMin(r.ch); -- i*0x40 + 0x14
----------------------------------------------------------------------
when x"6" => v.data := bandwidth(r.ch)(31 downto 0); -- i*0x40 + 0x18
when x"7" => v.data := bandwidth(r.ch)(63 downto 32); -- i*0x40 + 0x1C
when x"8" => v.data := bandwidthMax(r.ch)(31 downto 0); -- i*0x40 + 0x20
when x"9" => v.data := bandwidthMax(r.ch)(63 downto 32); -- i*0x40 + 0x24
when x"A" => v.data := bandwidthMin(r.ch)(31 downto 0); -- i*0x40 + 0x28
when x"B" => v.data := bandwidthMin(r.ch)(63 downto 32); -- i*0x40 + 0x2C
----------------------------------------------------------------------
when x"C" => v.data := frameSize(r.ch); -- i*0x40 + 0x30
when x"D" => v.data := frameSizeMax(r.ch); -- i*0x40 + 0x34
when x"E" => v.data := frameSizeMin(r.ch); -- i*0x40 + 0x38
----------------------------------------------------------------------
when x"F" => -- i*0x40 + 0x3C: Debugging
v.data(7 downto 0) := toSlv(AXIS_NUM_SLOTS_G, 8);
v.data(15 downto 8) := toSlv(ADDR_WIDTH_C, 8);
v.data(23 downto 16) := toSlv(r.ch, 8);
v.data(31 downto 16) := (others => '0');
-----------------------------------------------------------------------
when others =>
v.we := '0';
-----------------------------------------------------------------------
end case;

-- Check for last word
if (r.wrd = 15) then

-- Reset the counter
v.wrd := 0;
if (wrd = x"F") then

-- Check for last word
if (r.ch = AXIS_NUM_SLOTS_G-1) then
-- Reset the counter
v.ch := 0;
-- Reset the counters
v.ch := 0;
v.cnt := (others => '1'); -- pre-set to all ones so 1st write after reset is address=0x0
else
-- Increment the counters
v.ch := r.ch + 1;
end if;

else
-- Increment the counters
v.wrd := r.wrd + 1;
end if;

-- Synchronous Reset
Expand Down
Loading

0 comments on commit fcc76a0

Please sign in to comment.