FEATURE: Added AXI implementation and implemented LASTWINn Register

This commit is contained in:
Oliver Bruendler
2019-06-05 13:51:51 +02:00
parent 0a791bcb05
commit c409f8ea36
33 changed files with 3193 additions and 142 deletions

Binary file not shown.

Binary file not shown.

429
hdl/psi_ms_daq_axi.vhd Normal file
View File

@ -0,0 +1,429 @@
------------------------------------------------------------------------------
-- Libraries
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_ms_daq_pkg.all;
------------------------------------------------------------------------------
-- Entity Declaration
------------------------------------------------------------------------------
entity psi_ms_daq_axi is
generic (
-- Streams
Streams_g : positive range 1 to 32 := 2;
StreamWidth_g : t_ainteger := (16, 16);
StreamPrio_g : t_ainteger := (1, 1);
StreamBuffer_g : t_ainteger := (1024, 1024);
StreamTimeout_g : t_areal := (1.0e-3, 1.0e-3);
StreamClkFreq_g : t_areal := (100.0e6, 100.0e6);
StreamTsFifoDepth_g : t_ainteger := (16, 16);
StreamUseTs_g : t_abool := (true, true);
-- Recording
MaxWindows_g : positive range 1 to 32 := 16;
MinBurstSize_g : integer range 1 to 512 := 512;
MaxBurstSize_g : integer range 1 to 512 := 512;
-- Axi
AxiDataWidth_g : natural range 64 to 1024 := 64;
AxMaxBustBeats_g : integer range 1 to 256 := 256;
AxiMaxOpenTrasactions_g : natural range 1 to 8 := 8;
AxiFifoDepth_g : natural := 1024
);
port (
-- Data Stream Input
Str_Clk : in std_logic_vector(Streams_g-1 downto 0);
Str_Data : in t_aslv64(Streams_g-1 downto 0);
Str_Ts : in t_aslv64(Streams_g-1 downto 0);
Str_Vld : in std_logic_vector(Streams_g-1 downto 0);
Str_Rdy : out std_logic_vector(Streams_g-1 downto 0);
Str_Trig : in std_logic_vector(Streams_g-1 downto 0);
-- Miscellaneous
Irq : out std_logic;
-- AXI Slave Interface for Register Access
S_Axi_Aclk : in std_logic;
S_Axi_Aresetn : in std_logic;
S_Axi_ArAddr : in std_logic_vector(15 downto 0);
S_Axi_Arlen : in std_logic_vector(7 downto 0);
S_Axi_ArSize : in std_logic_vector(2 downto 0);
S_Axi_ArBurst : in std_logic_vector(1 downto 0);
S_Axi_ArLock : in std_logic;
S_Axi_ArCache : in std_logic_vector(3 downto 0);
S_Axi_ArProt : in std_logic_vector(2 downto 0);
S_Axi_ArValid : in std_logic;
S_Axi_ArReady : out std_logic;
S_Axi_RData : out std_logic_vector(31 downto 0);
S_Axi_RResp : out std_logic_vector(1 downto 0);
S_Axi_RLast : out std_logic;
S_Axi_RValid : out std_logic;
S_Axi_RReady : in std_logic;
S_Axi_AwAddr : in std_logic_vector(15 downto 0);
S_Axi_AwLen : in std_logic_vector(7 downto 0);
S_Axi_AwSize : in std_logic_vector(2 downto 0);
S_Axi_AwBurst : in std_logic_vector(1 downto 0);
S_Axi_AwLock : in std_logic;
S_Axi_AwCache : in std_logic_vector(3 downto 0);
S_Axi_AwProt : in std_logic_vector(2 downto 0);
S_Axi_AwValid : in std_logic;
S_Axi_AwReady : out std_logic;
S_Axi_WData : in std_logic_vector(31 downto 0);
S_Axi_WStrb : in std_logic_vector(3 downto 0);
S_Axi_WLast : in std_logic;
S_Axi_WValid : in std_logic;
S_Axi_WReady : out std_logic;
S_Axi_BResp : out std_logic_vector(1 downto 0);
S_Axi_BValid : out std_logic;
S_Axi_BReady : in std_logic;
-- AXI Master Interface for Memory Access
M_Axi_Aclk : in std_logic;
M_Axi_Aresetn : in std_logic;
M_Axi_AwAddr : out std_logic_vector(31 downto 0);
M_Axi_AwLen : out std_logic_vector(7 downto 0);
M_Axi_AwSize : out std_logic_vector(2 downto 0);
M_Axi_AwBurst : out std_logic_vector(1 downto 0);
M_Axi_AwLock : out std_logic;
M_Axi_AwCache : out std_logic_vector(3 downto 0);
M_Axi_AwProt : out std_logic_vector(2 downto 0);
M_Axi_AwValid : out std_logic;
M_Axi_AwReady : in std_logic := '0';
M_Axi_WData : out std_logic_vector(AxiDataWidth_g-1 downto 0);
M_Axi_WStrb : out std_logic_vector(AxiDataWidth_g/8-1 downto 0);
M_Axi_WLast : out std_logic;
M_Axi_WValid : out std_logic;
M_Axi_WReady : in std_logic := '0';
M_Axi_BResp : in std_logic_vector(1 downto 0) := (others => '0');
M_Axi_BValid : in std_logic := '0';
M_Axi_BReady : out std_logic;
M_Axi_ArAddr : out std_logic_vector(31 downto 0);
M_Axi_ArLen : out std_logic_vector(7 downto 0);
M_Axi_ArSize : out std_logic_vector(2 downto 0);
M_Axi_ArBurst : out std_logic_vector(1 downto 0);
M_Axi_ArLock : out std_logic;
M_Axi_ArCache : out std_logic_vector(3 downto 0);
M_Axi_ArProt : out std_logic_vector(2 downto 0);
M_Axi_ArValid : out std_logic;
M_Axi_ArReady : in std_logic := '0';
M_Axi_RData : in std_logic_vector(AxiDataWidth_g-1 downto 0) := (others => '0');
M_Axi_RResp : in std_logic_vector(1 downto 0) := (others => '0');
M_Axi_RLast : in std_logic := '0';
M_Axi_RValid : in std_logic := '0';
M_Axi_RReady : out std_logic
);
end entity;
------------------------------------------------------------------------------
-- Architecture Declaration
------------------------------------------------------------------------------
architecture rtl of psi_ms_daq_axi is
-- Input/Statemachine Signals
signal InpSm_HasTlast : std_logic_vector(Streams_g-1 downto 0);
signal InpSm_TsVld : std_logic_vector(Streams_g-1 downto 0);
signal InpSm_TsRdy : std_logic_vector(Streams_g-1 downto 0);
signal InpSm_Level : t_aslv16(Streams_g-1 downto 0);
signal InpSm_TsData : t_aslv64(Streams_g-1 downto 0);
-- Statemachine/Dma
signal SmDma_Cmd : DaqSm2DaqDma_Cmd_t;
signal SmDma_CmdVld : std_logic;
signal DmaSm_Resp : DaqDma2DaqSm_Resp_t;
signal DmaSm_RespVld : std_logic;
signal DmaSm_RespRdy : std_logic;
signal DmaSm_HasLast : std_logic_vector(Streams_g-1 downto 0);
-- Input/Dma
signal InpDma_Vld : std_logic_vector(Streams_g-1 downto 0);
signal InpDma_Rdy : std_logic_vector(Streams_g-1 downto 0);
signal InpDma_Data : Input2Daq_Data_a(Streams_g-1 downto 0);
-- Dma/Mem
signal DmaMem_CmdAddr : std_logic_vector(31 downto 0);
signal DmaMem_CmdSize : std_logic_vector(31 downto 0);
signal DmaMem_CmdVld : std_logic;
signal DmaMem_CmdRdy : std_logic;
signal DmaMem_DatData : std_logic_vector(63 downto 0);
signal DmaMem_DatVld : std_logic;
signal DmaMem_DatRdy : std_logic;
-- Mem/Statemachine
signal MemSm_Done : std_logic;
-- Configuration
signal Cfg_StrEna : std_logic_vector(Streams_g-1 downto 0);
signal Cfg_GlbEna : std_logic;
signal Cfg_PostTrig : t_aslv32(Streams_g-1 downto 0);
signal Cfg_Arm : std_logic_vector(Streams_g-1 downto 0);
signal Cfg_RecMode : t_aslv2(Streams_g-1 downto 0);
-- Status
signal Stat_StrIrq : std_logic_vector(Streams_g-1 downto 0);
signal Stat_StrLastWin : WinType_a(Streams_g-1 downto 0);
signal Stat_IsArmed : std_logic_vector(Streams_g-1 downto 0);
signal Stat_IsRecording : std_logic_vector(Streams_g-1 downto 0);
-- Context Memory Connections
signal CtxStr_Cmd : ToCtxStr_t;
signal CtxStr_Resp : FromCtx_t;
signal CtxWin_Cmd : ToCtxWin_t;
signal CtxWin_Resp : FromCtx_t;
-- Others
signal Sm_HasLast : std_logic_vector(Streams_g-1 downto 0);
signal M_Axi_Areset : std_logic; -- high active reset
signal S_Axi_Areset : std_logic; -- high active reset
begin
M_Axi_Areset <= not M_Axi_Aresetn;
S_Axi_Areset <= not S_Axi_Aresetn;
--------------------------------------------
-- Register Interface
--------------------------------------------
i_reg : entity work.psi_ms_daq_reg_axi
generic map (
Streams_g => Streams_g,
MaxWindows_g => MaxWindows_g
)
port map (
S_Axi_Aclk => S_Axi_Aclk,
S_Axi_Aresetn => S_Axi_Aresetn,
S_Axi_ArAddr => S_Axi_ArAddr,
S_Axi_Arlen => S_Axi_Arlen,
S_Axi_ArSize => S_Axi_ArSize,
S_Axi_ArBurst => S_Axi_ArBurst,
S_Axi_ArLock => S_Axi_ArLock,
S_Axi_ArCache => S_Axi_ArCache,
S_Axi_ArProt => S_Axi_ArProt,
S_Axi_ArValid => S_Axi_ArValid,
S_Axi_ArReady => S_Axi_ArReady,
S_Axi_RData => S_Axi_RData,
S_Axi_RResp => S_Axi_RResp,
S_Axi_RLast => S_Axi_RLast,
S_Axi_RValid => S_Axi_RValid,
S_Axi_RReady => S_Axi_RReady,
S_Axi_AwAddr => S_Axi_AwAddr,
S_Axi_AwLen => S_Axi_AwLen,
S_Axi_AwSize => S_Axi_AwSize,
S_Axi_AwBurst => S_Axi_AwBurst,
S_Axi_AwLock => S_Axi_AwLock,
S_Axi_AwCache => S_Axi_AwCache,
S_Axi_AwProt => S_Axi_AwProt,
S_Axi_AwValid => S_Axi_AwValid,
S_Axi_AwReady => S_Axi_AwReady,
S_Axi_WData => S_Axi_WData,
S_Axi_WStrb => S_Axi_WStrb,
S_Axi_WLast => S_Axi_WLast,
S_Axi_WValid => S_Axi_WValid,
S_Axi_WReady => S_Axi_WReady,
S_Axi_BResp => S_Axi_BResp,
S_Axi_BValid => S_Axi_BValid,
S_Axi_BReady => S_Axi_BReady,
IrqOut => Irq,
PostTrig => Cfg_PostTrig,
Arm => Cfg_Arm,
IsArmed => Stat_IsArmed,
IsRecording => Stat_IsRecording,
RecMode => Cfg_RecMode,
ClkMem => M_Axi_Aclk,
RstMem => M_Axi_Areset,
CtxStr_Cmd => CtxStr_Cmd,
CtxStr_Resp => CtxStr_Resp,
CtxWin_Cmd => CtxWin_Cmd,
CtxWin_Resp => CtxWin_Resp,
InLevel => InpSm_Level,
StrIrq => Stat_StrIrq,
StrLastWin => Stat_StrLastWin,
StrEna => Cfg_StrEna,
GlbEna => Cfg_GlbEna
);
--------------------------------------------
-- Input Logic Instantiation
--------------------------------------------
g_input : for str in 0 to Streams_g-1 generate
signal InRst : std_logic;
signal StrInput : std_logic_vector(StreamWidth_g(str)-1 downto 0);
begin
-- Reset if stream is disabled
InRst <= M_Axi_Areset or not Cfg_StrEna(str) or not Cfg_GlbEna;
StrInput <= Str_Data(str)(StrInput'range);
-- Instantiation
i_input : entity work.psi_ms_daq_input
generic map (
StreamWidth_g => StreamWidth_g(str),
StreamBuffer_g => StreamBuffer_g(str),
StreamTimeout_g => StreamTimeout_g(str),
StreamClkFreq_g => StreamClkFreq_g(str),
StreamTsFifoDepth_g => StreamTsFifoDepth_g(str),
StreamUseTs_g => StreamUseTs_g(str)
)
port map (
Str_Clk => Str_Clk(str),
Str_Vld => Str_Vld(str),
Str_Rdy => Str_Rdy(str),
Str_Data => StrInput,
Str_Trig => Str_Trig(str),
Str_Ts => Str_Ts(str),
ClkReg => S_Axi_Aclk,
RstReg => S_Axi_Areset,
PostTrigSpls => Cfg_PostTrig(str),
Mode => Cfg_RecMode(str),
Arm => Cfg_Arm(str),
IsArmed => Stat_IsArmed(str),
IsRecording => Stat_IsRecording(str),
ClkMem => M_Axi_Aclk,
RstMem => InRst,
Daq_Vld => InpDma_Vld(str),
Daq_Rdy => InpDma_Rdy(str),
Daq_Data => InpDma_Data(str),
Daq_Level => InpSm_Level(str),
Daq_HasLast => InpSm_HasTlast(str),
Ts_Vld => InpSm_TsVld(str),
Ts_Rdy => InpSm_TsRdy(str),
Ts_Data => InpSm_TsData(str)
);
end generate;
--------------------------------------------
-- Control State Machine
--------------------------------------------
-- Detect end-of frame in input buffer or DMA buffer
Sm_HasLast <= InpSm_HasTlast or DmaSm_HasLast;
-- Instantiation
i_statemachine : entity work.psi_ms_daq_daq_sm
generic map (
Streams_g => Streams_g,
StreamPrio_g => StreamPrio_g,
StreamWidth_g => StreamWidth_g,
Windows_g => MaxWindows_g,
MinBurstSize_g => MinBurstSize_g,
MaxBurstSize_g => MaxBurstSize_g
)
port map (
Clk => M_Axi_Aclk,
Rst => M_Axi_Areset,
GlbEna => Cfg_GlbEna,
StrEna => Cfg_StrEna,
StrIrq => Stat_StrIrq,
StrLastWin => Stat_StrLastWin,
Inp_HasLast => Sm_HasLast,
Inp_Level => InpSm_Level,
Ts_Vld => InpSm_TsVld,
Ts_Rdy => InpSm_TsRdy,
Ts_Data => InpSm_TsData,
Dma_Cmd => SmDma_Cmd,
Dma_Cmd_Vld => SmDma_CmdVld,
Dma_Resp => DmaSm_Resp,
Dma_Resp_Vld => DmaSm_RespVld,
Dma_Resp_Rdy => DmaSm_RespRdy,
TfDone => MemSm_Done,
-- Context RAM connections
CtxStr_Cmd => CtxStr_Cmd,
CtxStr_Resp => CtxStr_Resp,
CtxWin_Cmd => CtxWin_Cmd,
CtxWin_Resp => CtxWin_Resp
);
--------------------------------------------
-- DMA Engine
--------------------------------------------
i_dma : entity work.psi_ms_daq_daq_dma
generic map (
Streams_g => Streams_g
)
port map (
Clk => M_Axi_Aclk,
Rst => M_Axi_Areset,
DaqSm_Cmd => SmDma_Cmd,
DaqSm_Cmd_Vld => SmDma_CmdVld,
DaqSm_Resp => DmaSm_Resp,
DaqSm_Resp_Vld => DmaSm_RespVld,
DaqSm_Resp_Rdy => DmaSm_RespRdy,
DaqSm_HasLast => DmaSm_HasLast,
Inp_Vld => InpDma_Vld,
Inp_Rdy => InpDma_Rdy,
Inp_Data => InpDma_Data,
Mem_CmdAddr => DmaMem_CmdAddr,
Mem_CmdSize => DmaMem_CmdSize,
Mem_CmdVld => DmaMem_CmdVld,
Mem_CmdRdy => DmaMem_CmdRdy,
Mem_DatData => DmaMem_DatData,
Mem_DatVld => DmaMem_DatVld,
Mem_DatRdy => DmaMem_DatRdy
);
--------------------------------------------
-- Memory Interface
--------------------------------------------
i_memif : entity work.psi_ms_daq_axi_if
generic map (
AxiDataWidth_g => AxiDataWidth_g,
AxiMaxBeats_g => AxMaxBustBeats_g,
AxiMaxOpenTrasactions_g => AxiMaxOpenTrasactions_g,
MaxOpenCommands_g => Streams_g,
DataFifoDepth_g => 1024,
AxiFifoDepth_g => AxiFifoDepth_g,
RamBehavior_g => "RBW" -- Okay for Xilinx chips
)
port map (
Clk => M_Axi_Aclk,
Rst_n => M_Axi_Aresetn,
Cmd_Addr => DmaMem_CmdAddr,
Cmd_Size => DmaMem_CmdSize,
Cmd_Vld => DmaMem_CmdVld,
Cmd_Rdy => DmaMem_CmdRdy,
Dat_Data => DmaMem_DatData,
Dat_Vld => DmaMem_DatVld,
Dat_Rdy => DmaMem_DatRdy,
Done => MemSm_Done,
M_Axi_AwAddr => M_Axi_AwAddr,
M_Axi_AwLen => M_Axi_AwLen,
M_Axi_AwSize => M_Axi_AwSize,
M_Axi_AwBurst => M_Axi_AwBurst,
M_Axi_AwLock => M_Axi_AwLock,
M_Axi_AwCache => M_Axi_AwCache,
M_Axi_AwProt => M_Axi_AwProt,
M_Axi_AwValid => M_Axi_AwValid,
M_Axi_AwReady => M_Axi_AwReady,
M_Axi_WData => M_Axi_WData,
M_Axi_WStrb => M_Axi_WStrb,
M_Axi_WLast => M_Axi_WLast,
M_Axi_WValid => M_Axi_WValid,
M_Axi_WReady => M_Axi_WReady,
M_Axi_BResp => M_Axi_BResp,
M_Axi_BValid => M_Axi_BValid,
M_Axi_BReady => M_Axi_BReady,
M_Axi_ArAddr => M_Axi_ArAddr,
M_Axi_ArLen => M_Axi_ArLen,
M_Axi_ArSize => M_Axi_ArSize,
M_Axi_ArBurst => M_Axi_ArBurst,
M_Axi_ArLock => M_Axi_ArLock,
M_Axi_ArCache => M_Axi_ArCache,
M_Axi_ArProt => M_Axi_ArProt,
M_Axi_ArValid => M_Axi_ArValid,
M_Axi_ArReady => M_Axi_ArReady,
M_Axi_RData => M_Axi_RData,
M_Axi_RResp => M_Axi_RResp,
M_Axi_RLast => M_Axi_RLast,
M_Axi_RValid => M_Axi_RValid,
M_Axi_RReady => M_Axi_RReady
);
end;

220
hdl/psi_ms_daq_axi_if.vhd Normal file
View File

@ -0,0 +1,220 @@
------------------------------------------------------------------------------
-- Libraries
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.smem_master_types_pkg.all;
------------------------------------------------------------------------------
-- Entity Declaration
------------------------------------------------------------------------------
entity psi_ms_daq_axi_if is
generic (
AxiDataWidth_g : natural range 64 to 1024 := 64;
AxiMaxBeats_g : natural range 1 to 256 := 256;
AxiMaxOpenTrasactions_g : natural range 1 to 8 := 8;
MaxOpenCommands_g : positive := 16;
DataFifoDepth_g : natural := 1024;
AxiFifoDepth_g : natural := 1024;
RamBehavior_g : string := "RBW"
);
port (
-- Control Signals
Clk : in std_logic;
Rst_n : in std_logic;
-- Write Command
Cmd_Addr : in std_logic_vector(31 downto 0);
Cmd_Size : in std_logic_vector(31 downto 0);
Cmd_Vld : in std_logic;
Cmd_Rdy : out std_logic;
-- Write Data
Dat_Data : in std_logic_vector(63 downto 0);
Dat_Vld : in std_logic;
Dat_Rdy : out std_logic;
-- Response
Done : out std_logic;
-- AXI Address Write Channel
M_Axi_AwAddr : out std_logic_vector(31 downto 0);
M_Axi_AwLen : out std_logic_vector(7 downto 0);
M_Axi_AwSize : out std_logic_vector(2 downto 0);
M_Axi_AwBurst : out std_logic_vector(1 downto 0);
M_Axi_AwLock : out std_logic;
M_Axi_AwCache : out std_logic_vector(3 downto 0);
M_Axi_AwProt : out std_logic_vector(2 downto 0);
M_Axi_AwValid : out std_logic;
M_Axi_AwReady : in std_logic := '0';
-- AXI Write Data Channel
M_Axi_WData : out std_logic_vector(AxiDataWidth_g-1 downto 0);
M_Axi_WStrb : out std_logic_vector(AxiDataWidth_g/8-1 downto 0);
M_Axi_WLast : out std_logic;
M_Axi_WValid : out std_logic;
M_Axi_WReady : in std_logic := '0';
-- AXI Write Response Channel
M_Axi_BResp : in std_logic_vector(1 downto 0) := (others => '0');
M_Axi_BValid : in std_logic := '0';
M_Axi_BReady : out std_logic;
-- AXI Read Address Channel
M_Axi_ArAddr : out std_logic_vector(31 downto 0);
M_Axi_ArLen : out std_logic_vector(7 downto 0);
M_Axi_ArSize : out std_logic_vector(2 downto 0);
M_Axi_ArBurst : out std_logic_vector(1 downto 0);
M_Axi_ArLock : out std_logic;
M_Axi_ArCache : out std_logic_vector(3 downto 0);
M_Axi_ArProt : out std_logic_vector(2 downto 0);
M_Axi_ArValid : out std_logic;
M_Axi_ArReady : in std_logic := '0';
-- AXI Read Data Channel
M_Axi_RData : in std_logic_vector(AxiDataWidth_g-1 downto 0) := (others => '0');
M_Axi_RResp : in std_logic_vector(1 downto 0) := (others => '0');
M_Axi_RLast : in std_logic := '0';
M_Axi_RValid : in std_logic := '0';
M_Axi_RReady : out std_logic
);
end entity;
------------------------------------------------------------------------------
-- Architecture Declaration
------------------------------------------------------------------------------
architecture rtl of psi_ms_daq_axi_if is
signal Rst : std_logic;
subtype CommandAddrRng_c is natural range 31 downto 0;
subtype CommandSizeRng_c is natural range 63 downto 32;
constant WrCmdWidth_c : integer := CommandSizeRng_c'high+1;
signal InfoFifoIn : std_logic_vector(WrCmdWidth_c-1 downto 0);
signal InfoFifoOut : std_logic_vector(WrCmdWidth_c-1 downto 0);
signal WrCmdFifo_Vld : std_logic;
signal WrCmdFifo_Rdy : std_logic;
signal WrCmdFifo_Addr : std_logic_vector(31 downto 0);
signal WrCmdFifo_Size : std_logic_vector(31 downto 0);
signal DoneI : std_logic;
signal ErrorI : std_logic;
begin
Rst <= not Rst_n;
InfoFifoIn(CommandAddrRng_c) <= Cmd_Addr;
InfoFifoIn(CommandSizeRng_c) <= Cmd_Size;
i_wrinfo_fifo : entity work.psi_common_sync_fifo
generic map (
Width_g => WrCmdWidth_c,
Depth_g => MaxOpenCommands_g,
RamStyle_g => "distributed"
)
port map (
Clk => Clk,
Rst => Rst,
InData => InfoFifoIn,
InVld => Cmd_Vld,
InRdy => Cmd_Rdy,
OutData => InfoFifoOut,
OutVld => WrCmdFifo_Vld,
OutRdy => WrCmdFifo_Rdy
);
WrCmdFifo_Addr <= InfoFifoOut(CommandAddrRng_c);
WrCmdFifo_Size <= InfoFifoOut(CommandSizeRng_c);
i_axi : entity work.psi_common_axi_master_full
generic map (
AxiAddrWidth_g => 32,
AxiDataWidth_g => AxiDataWidth_g,
AxiMaxBeats_g => AxiMaxBeats_g,
AxiMaxOpenTrasactions_g => AxiMaxOpenTrasactions_g,
UserTransactionSizeBits_g => 32,
DataFifoDepth_g => DataFifoDepth_g,
DataWidth_g => 64,
ImplRead_g => false,
ImplWrite_g => true,
RamBehavior_g => RamBehavior_g
)
port map (
-- Control Signals
M_Axi_Aclk => Clk,
M_Axi_Aresetn => Rst_n,
-- User Command Interface Write
CmdWr_Addr => WrCmdFifo_Addr,
CmdWr_Size => WrCmdFifo_Size,
CmdWr_LowLat => '0',
CmdWr_Vld => WrCmdFifo_Vld,
CmdWr_Rdy => WrCmdFifo_Rdy,
-- User Command Interface Read (unused)
CmdRd_Addr => (others => '0'),
CmdRd_Size => (others => '0'),
CmdRd_LowLat => '0',
CmdRd_Vld => '0',
CmdRd_Rdy => open,
-- Write Data
WrDat_Data => Dat_Data,
WrDat_Vld => Dat_Vld,
WrDat_Rdy => Dat_Rdy,
-- Read Data (unused)
RdDat_Data => open,
RdDat_Vld => open,
RdDat_Rdy => '0',
-- Response
Wr_Done => DoneI,
Wr_Error => ErrorI,
Rd_Done => open,
Rd_Error => open,
-- AXI Address Write Channel
M_Axi_AwAddr => M_Axi_AwAddr,
M_Axi_AwLen => M_Axi_AwLen,
M_Axi_AwSize => M_Axi_AwSize,
M_Axi_AwBurst => M_Axi_AwBurst,
M_Axi_AwLock => M_Axi_AwLock,
M_Axi_AwCache => M_Axi_AwCache,
M_Axi_AwProt => M_Axi_AwProt,
M_Axi_AwValid => M_Axi_AwValid,
M_Axi_AwReady => M_Axi_AwReady,
-- AXI Write Data Channel
M_Axi_WData => M_Axi_WData,
M_Axi_WStrb => M_Axi_WStrb,
M_Axi_WLast => M_Axi_WLast,
M_Axi_WValid => M_Axi_WValid,
M_Axi_WReady => M_Axi_WReady,
-- AXI Write Response Channel
M_Axi_BResp => M_Axi_BResp,
M_Axi_BValid => M_Axi_BValid,
M_Axi_BReady => M_Axi_BReady,
-- AXI Read Address Channel
M_Axi_ArAddr => M_Axi_ArAddr,
M_Axi_ArLen => M_Axi_ArLen,
M_Axi_ArSize => M_Axi_ArSize,
M_Axi_ArBurst => M_Axi_ArBurst,
M_Axi_ArLock => M_Axi_ArLock,
M_Axi_ArCache => M_Axi_ArCache,
M_Axi_ArProt => M_Axi_ArProt,
M_Axi_ArValid => M_Axi_ArValid,
M_Axi_ArReady => M_Axi_ArReady,
-- AXI Read Data Channel
M_Axi_RData => M_Axi_RData,
M_Axi_RResp => M_Axi_RResp,
M_Axi_RLast => M_Axi_RLast,
M_Axi_RValid => M_Axi_RValid,
M_Axi_RReady => M_Axi_RReady
);
Done <= DoneI or ErrorI;
end;

View File

@ -38,6 +38,7 @@ entity psi_ms_daq_daq_sm is
GlbEna : in std_logic; -- $$ proc=control; lowactive=true $$
StrEna : in std_logic_vector(Streams_g-1 downto 0); -- $$ proc=control; lowactive=true $$
StrIrq : out std_logic_vector(Streams_g-1 downto 0); -- $$ proc=control,dma_resp,dma_cmd; $$
StrLastWin : out WinType_a(Streams_g-1 downto 0);
-- Input logic Connections
Inp_HasLast : in std_logic_vector(Streams_g-1 downto 0); -- $$ proc=control $$
@ -113,8 +114,9 @@ architecture rtl of psi_ms_daq_daq_sm is
signal IrqFifoEmpty : std_logic;
signal IrqFifoGenIrq : std_logic;
signal IrqFifoStream : std_logic_vector(log2ceil(Streams_g)-1 downto 0);
signal IrqFifoIn : std_logic_vector(log2ceil(Streams_g) downto 0);
signal IrqFifoOut : std_logic_vector(log2ceil(Streams_g) downto 0);
signal IrqLastWinNr : std_logic_vector(log2ceil(Windows_g)-1 downto 0);
signal IrqFifoIn : std_logic_vector(log2ceil(Streams_g)+log2ceil(Windows_g) downto 0);
signal IrqFifoOut : std_logic_vector(log2ceil(Streams_g)+log2ceil(Windows_g) downto 0);
-- Types
type State_t is (Idle_s, CheckPrio1_s, CheckPrio2_s, CheckPrio3_s, CheckResp_s, TlastCheck_s, ReadCtxStr_s, First_s, ReadCtxWin_s, CalcAccess0_s, CalcAccess1_s, ProcResp0_s, NextWin_s, WriteCtx_s);
@ -144,6 +146,7 @@ architecture rtl of psi_ms_daq_daq_sm is
HndlOverwrite : std_logic;
HndlWincnt : std_logic_vector(log2ceil(Windows_g)-1 downto 0);
HndlWincur : std_logic_vector(log2ceil(Windows_g)-1 downto 0);
HndlLastWinNr : std_logic_vector(log2ceil(Windows_g)-1 downto 0);
HndlBufstart : std_logic_vector(31 downto 0);
HndlWinSize : std_logic_vector(31 downto 0);
HndlPtr0 : std_logic_vector(31 downto 0);
@ -169,6 +172,7 @@ architecture rtl of psi_ms_daq_daq_sm is
IrqFifoWrite : std_logic;
IrqFifoRead : std_logic;
StrIrq : std_logic_vector(Streams_g-1 downto 0);
StrLastWin : WinType_a(Streams_g-1 downto 0);
EndByTrig : std_logic;
end record;
signal r, r_next : two_process_r;
@ -179,7 +183,7 @@ begin
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process( r, Inp_HasLast, Inp_Level, Ts_Vld, Ts_Data, Dma_Resp, Dma_Resp_Vld, CtxStr_Resp, CtxWin_Resp, GlbEna, StrEna, TfDone, IrqFifoGenIrq, IrqFifoStream,
p_comb : process( r, Inp_HasLast, Inp_Level, Ts_Vld, Ts_Data, Dma_Resp, Dma_Resp_Vld, CtxStr_Resp, CtxWin_Resp, GlbEna, StrEna, TfDone, IrqFifoGenIrq, IrqFifoStream, IrqLastWinNr,
GrantVld, GrantPrio1, GrantPrio2, GrantPrio3, IrqFifoAlmFull, IrqFifoEmpty)
variable v : two_process_r;
begin
@ -440,7 +444,8 @@ begin
if unsigned(Dma_Resp.Size) /= 0 then
v.IrqFifoWrite := '1';
end if;
-- Switch to next window if required
-- Switch to next window if required
v.HndlLastWinNr := r.HndlWincur;
if ((r.HndlPtr1 = r.HndlWinEnd) and (r.HndlRingbuf = '0')) or (Dma_Resp.Trigger = '1') then
v.HndlWinDone := '1';
v.NewBuffer(r.HndlStream) := '1';
@ -545,7 +550,8 @@ begin
v.TfDoneCnt := std_logic_vector(unsigned(v.TfDoneCnt) - 1);
-- Generate IRQ if required
if IrqFifoGenIrq = '1' then
v.StrIrq(to_integer(unsigned(IrqFifoStream))) := '1';
v.StrIrq(to_integer(unsigned(IrqFifoStream))) := '1';
v.StrLastWin(to_integer(unsigned(IrqFifoStream))) := std_logic_vector(resize(unsigned(IrqLastWinNr), 5));
end if;
end if;
@ -562,6 +568,7 @@ begin
Dma_Resp_Rdy <= r.Dma_Resp_Rdy;
Ts_Rdy <= r.Ts_Rdy;
StrIrq <= r.StrIrq;
StrLastWin <= r.StrLastWin;
--------------------------------------------
-- Sequential Process
@ -592,6 +599,7 @@ begin
r.IrqFifoWrite <= '0';
r.IrqFifoRead <= '0';
r.StrIrq <= (others => '0');
r.StrLastWin <= (others => (others => '0'));
end if;
end if;
end process;
@ -644,13 +652,14 @@ begin
-- *** IRQ Information FIFO ***
-- input assembly
IrqFifoIn(IrqFifoIn'high-1 downto 0) <= std_logic_vector(to_unsigned(r.HndlStream, log2ceil(Streams_g)));
IrqFifoIn(IrqFifoIn'high) <= r.HndlWinDone;
IrqFifoIn(log2ceil(Streams_g)-1 downto 0) <= std_logic_vector(to_unsigned(r.HndlStream, log2ceil(Streams_g)));
IrqFifoIn(log2ceil(Streams_g)+log2ceil(Windows_g)-1 downto log2ceil(Streams_g)) <= r.HndlLastWinNr;
IrqFifoIn(IrqFifoIn'high) <= r.HndlWinDone;
-- Instantiation
i_irq_fifo : entity work.psi_common_sync_fifo
generic map (
Width_g => log2ceil(Streams_g)+1,
Width_g => log2ceil(Streams_g)+log2ceil(Windows_g)+1,
Depth_g => Streams_g*4,
AlmFullOn_g => true,
AlmFullLevel_g => Streams_g*3,
@ -668,7 +677,8 @@ begin
);
-- Output disassembly
IrqFifoStream <= IrqFifoOut(IrqFifoOut'high-1 downto 0);
IrqFifoStream <= IrqFifoOut(log2ceil(Streams_g)-1 downto 0);
IrqLastWinNr <= IrqFifoOut(log2ceil(Streams_g)+log2ceil(Windows_g)-1 downto log2ceil(Streams_g));
IrqFifoGenIrq <= IrqFifoOut(IrqFifoOut'high);

View File

@ -39,8 +39,8 @@ entity psi_ms_daq_input is
Str_Ts : in std_logic_vector(63 downto 0); -- $$ proc=stream $$
-- Configuration Signals
ClkTmem : in std_logic;
RstTmem : in std_logic;
ClkReg : in std_logic;
RstReg : in std_logic;
PostTrigSpls : in std_logic_vector(31 downto 0); -- $$ proc=daq $$
Mode : in RecMode_t; -- $$ proc=daq $$
Arm : in std_logic; -- $$ proc=stream $$
@ -48,8 +48,8 @@ entity psi_ms_daq_input is
IsRecording : out std_logic; -- $$ proc=stream $$
-- DAQ control signals
ClkSmem : in std_logic; -- $$ type=clk; freq=200e6; proc=daq,stream $$
RstSmem : in std_logic; -- $$ type=rst; clk=Clk $$
ClkMem : in std_logic; -- $$ type=clk; freq=200e6; proc=daq,stream $$
RstMem : in std_logic; -- $$ type=rst; clk=Clk $$
-- DAQ logic Connections
Daq_Vld : out std_logic; -- $$ proc=daq $$
@ -130,7 +130,7 @@ architecture rtl of psi_ms_daq_input is
signal PostTrigSpls_Sync : std_logic_vector(PostTrigSpls'range);
signal Mode_Sync : RecMode_t;
signal Arm_Sync : std_logic;
signal RstTmem_Sync : std_logic;
signal RstReg_Sync : std_logic;
signal RstAcq_Sync : std_logic;
begin
@ -336,9 +336,9 @@ begin
--------------------------------------------
-- Output Side TLAST handling
--------------------------------------------
p_outlast : process(ClkSmem)
p_outlast : process(ClkMem)
begin
if rising_edge(ClkSmem) then
if rising_edge(ClkMem) then
-- Default Value
Daq_HasLast_I <= '0';
@ -353,7 +353,7 @@ begin
end if;
-- Reset
if RstSmem = '1' then
if RstMem = '1' then
OutTlastCnt <= (others => '0');
end if;
end if;
@ -363,13 +363,13 @@ begin
--------------------------------------------
-- Component Instantiation
--------------------------------------------
-- *** TMEM clock crossings ***
i_cc_tmem_status : entity work.psi_common_status_cc
-- *** Register Interface clock crossings ***
i_cc_reg_status : entity work.psi_common_status_cc
generic map (
DataWidth_g => 34
)
port map (
ClkA => ClkTmem,
ClkA => ClkReg,
RstInA => '0',
DataA(31 downto 0) => PostTrigSpls,
DataA(33 downto 32) => Mode,
@ -386,17 +386,17 @@ begin
port map (
BitsA(0) => r.IsArmed,
BitsA(1) => r.RecEna,
ClkB => ClkTmem,
ClkB => ClkReg,
BitsB(0) => IsArmed,
BitsB(1) => IsRecording
);
i_cc_tmem_pulse : entity work.psi_common_pulse_cc
i_cc_reg_pulse : entity work.psi_common_pulse_cc
generic map (
NumPulses_g => 1
)
port map (
ClkA => ClkTmem,
ClkA => ClkReg,
RstInA => '0',
PulseA(0) => Arm,
ClkB => Str_Clk,
@ -408,26 +408,26 @@ begin
-- *** Reset Handling ***
icc_tmem_rst : entity work.psi_common_bit_cc
icc_reg_rst : entity work.psi_common_bit_cc
generic map (
NumBits_g => 1
)
port map (
BitsA(0) => RstTmem,
BitsA(0) => RstReg,
ClkB => Str_Clk,
BitsB(0) => RstTmem_Sync
BitsB(0) => RstReg_Sync
);
icc_smem_rst : entity work.psi_common_bit_cc
icc_mem_rst : entity work.psi_common_bit_cc
generic map (
NumBits_g => 1
)
port map (
BitsA(0) => RstSmem,
BitsA(0) => RstMem,
ClkB => Str_Clk,
BitsB(0) => RstAcq_Sync
);
Str_Rst <= RstTmem_Sync or RstAcq_Sync;
Str_Rst <= RstReg_Sync or RstAcq_Sync;
-- *** Acquisition Clock Crossing ***
-- Clock crossing for reset and TLAST counter
@ -440,7 +440,7 @@ begin
RstInA => Str_Rst,
RstOutA => open,
DataA => r.TLastCnt,
ClkB => ClkSmem,
ClkB => ClkMem,
RstInB => '0',
DataB => InTlastCnt
);
@ -463,7 +463,7 @@ begin
port map (
InClk => Str_Clk,
InRst => Str_Rst,
OutClk => ClkSmem,
OutClk => ClkMem,
OutRst => '0',
InData => DataFifo_InData,
InVld => r.DataFifoVld,
@ -501,7 +501,7 @@ begin
port map (
InClk => Str_Clk,
InRst => Str_Rst,
OutClk => ClkSmem,
OutClk => ClkMem,
OutRst => '0',
InData => r.TsLatch,
InVld => TsFifo_InVld,
@ -526,9 +526,9 @@ begin
--------------------------------------------
-- Assertions
--------------------------------------------
p_assert : process(ClkSmem)
p_assert : process(ClkMem)
begin
if rising_edge(ClkSmem) then
if rising_edge(ClkMem) then
assert StreamWidth_g = 8 or StreamWidth_g = 16 or StreamWidth_g = 32 or StreamWidth_g = 64 report "###ERROR###: psi_ms_daq_input: StreamWidth_g must be 8, 16, 32 or 64" severity error;
end if;
end process;

View File

@ -16,6 +16,7 @@ package psi_ms_daq_pkg is
constant MaxStreams_c : integer := 32;
constant MaxWindows_c : integer := 32;
constant MaxStreamsBits_c : integer := log2ceil(MaxStreams_c);
constant MaxWindowsBits_c : integer := log2ceil(MaxWindows_c);
subtype RecMode_t is std_logic_vector(1 downto 0);
constant RecMode_Continuous_c : RecMode_t := std_logic_vector(to_unsigned(0, RecMode_t'length));
@ -23,6 +24,9 @@ package psi_ms_daq_pkg is
constant RecMode_SingleShot_c : RecMode_t := std_logic_vector(to_unsigned(2, RecMode_t'length));
constant RecMode_ManuelMode_c : RecMode_t := std_logic_vector(to_unsigned(3, RecMode_t'length));
subtype WinType_t is std_logic_vector(MaxWindowsBits_c-1 downto 0);
type WinType_a is array (natural range <>) of WinType_t;
type Input2Daq_Data_t is record
Last : std_logic;
Data : std_logic_vector(63 downto 0);

566
hdl/psi_ms_daq_reg_axi.vhd Normal file
View File

@ -0,0 +1,566 @@
------------------------------------------------------------------------------
-- Libraries
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_common_logic_pkg.all;
use work.psi_ms_daq_pkg.all;
use work.axi_slave_ipif_package.all;
------------------------------------------------------------------------------
-- Entity Declaration
------------------------------------------------------------------------------
entity psi_ms_daq_reg_axi is
generic (
Streams_g : in integer range 1 to 32;
MaxWindows_g : in integer range 1 to 32
);
port (
-- AXI Control Signals
S_Axi_Aclk : in std_logic;
S_Axi_Aresetn : in std_logic;
-- AXI Read address channel
S_Axi_ArAddr : in std_logic_vector(15 downto 0);
S_Axi_Arlen : in std_logic_vector(7 downto 0);
S_Axi_ArSize : in std_logic_vector(2 downto 0);
S_Axi_ArBurst : in std_logic_vector(1 downto 0);
S_Axi_ArLock : in std_logic;
S_Axi_ArCache : in std_logic_vector(3 downto 0);
S_Axi_ArProt : in std_logic_vector(2 downto 0);
S_Axi_ArValid : in std_logic;
S_Axi_ArReady : out std_logic;
-- AXI Read data channel
S_Axi_RData : out std_logic_vector(31 downto 0);
S_Axi_RResp : out std_logic_vector(1 downto 0);
S_Axi_RLast : out std_logic;
S_Axi_RValid : out std_logic;
S_Axi_RReady : in std_logic;
-- AXI Write address channel
S_Axi_AwAddr : in std_logic_vector(15 downto 0);
S_Axi_AwLen : in std_logic_vector(7 downto 0);
S_Axi_AwSize : in std_logic_vector(2 downto 0);
S_Axi_AwBurst : in std_logic_vector(1 downto 0);
S_Axi_AwLock : in std_logic;
S_Axi_AwCache : in std_logic_vector(3 downto 0);
S_Axi_AwProt : in std_logic_vector(2 downto 0);
S_Axi_AwValid : in std_logic;
S_Axi_AwReady : out std_logic;
-- AXI Write data channel
S_Axi_WData : in std_logic_vector(31 downto 0);
S_Axi_WStrb : in std_logic_vector(3 downto 0);
S_Axi_WLast : in std_logic;
S_Axi_WValid : in std_logic;
S_Axi_WReady : out std_logic;
-- AXI Write response channel
S_Axi_BResp : out std_logic_vector(1 downto 0);
S_Axi_BValid : out std_logic;
S_Axi_BReady : in std_logic;
-- Control Signals (AXI-S Clk)
Arm : out std_logic_vector(Streams_g-1 downto 0);
IsArmed : in std_logic_vector(Streams_g-1 downto 0);
IsRecording : in std_logic_vector(Streams_g-1 downto 0);
PostTrig : out t_aslv32(Streams_g-1 downto 0);
RecMode : out t_aslv2(Streams_g-1 downto 0);
IrqOut : out std_logic;
-- Memory Interfae Clock domain control singals
ClkMem : in std_logic;
RstMem : in std_logic;
-- Context Memory Interface (MemClk)
CtxStr_Cmd : in ToCtxStr_t;
CtxStr_Resp : out FromCtx_t;
CtxWin_Cmd : in ToCtxWin_t;
CtxWin_Resp : out FromCtx_t;
-- Logic Interface (MemClk)
StrIrq : in std_logic_vector(Streams_g-1 downto 0);
StrLastWin : in WinType_a(Streams_g-1 downto 0);
StrEna : out std_logic_vector(Streams_g-1 downto 0);
GlbEna : out std_logic;
InLevel : in t_aslv16(Streams_g-1 downto 0)
);
end entity;
architecture rtl of psi_ms_daq_reg_axi is
-- Two process method
type two_process_r is record
Reg_Gcfg_Ena : std_logic;
Reg_Gcfg_IrqEna : std_logic;
Reg_IrqVec : std_logic_vector(Streams_g-1 downto 0);
Reg_IrqEna : std_logic_vector(Streams_g-1 downto 0);
Reg_StrEna : std_logic_vector(Streams_g-1 downto 0);
Reg_PostTrig : t_aslv32(Streams_g-1 downto 0);
Reg_Mode_Recm : t_aslv2(Streams_g-1 downto 0);
Reg_Mode_Arm : std_logic_vector(Streams_g-1 downto 0);
Irq : std_logic;
RegRdval : std_logic_vector(31 downto 0);
AddrReg : std_logic_vector(15 downto 0);
MaxLvlClr : std_logic_vector(Streams_g-1 downto 0);
end record;
signal r, r_next : two_process_r;
constant DwWrite_c : std_logic_vector(3 downto 0) := "1111";
constant DepthCtxStr_c : integer := Streams_g*32/8;
constant CtxStrAddrHigh_c : integer := log2ceil(Streams_g*32)-1;
signal CtxStr_WeLo : std_logic;
signal CtxStr_WeHi : std_logic;
signal CtxStr_Rdval : std_logic_vector(63 downto 0);
signal CtxStr_AddrB : std_logic_vector(log2ceil(DepthCtxStr_c)-1 downto 0);
signal AddrCtxStr : boolean;
constant DepthCtxWin_c : integer := Streams_g*MaxWindows_g*16/8;
constant CtxWinAddrHigh_c : integer := log2ceil(Streams_g*MaxWindows_g*16)-1;
signal CtxWin_WeLo : std_logic;
signal CtxWin_WeHi : std_logic;
signal CtxWin_Rdval : std_logic_vector(63 downto 0);
signal CtxWin_AddrB : std_logic_vector(log2ceil(DepthCtxWin_c)-1 downto 0);
signal AddrCtxWin : boolean;
-- High active reset
signal A_Axi_Areset : std_logic;
-- Maximum Level Latching
signal MaxLevel : t_aslv16(Streams_g-1 downto 0);
-- Clock Crossing Signals
signal StrIrq_Sync : std_logic_vector(Streams_g-1 downto 0);
signal StrLastWin_Sync : WinType_a(Streams_g-1 downto 0);
signal MaxLevel_Sync : t_aslv16(Streams_g-1 downto 0);
signal MaxLevelClr_Sync : std_logic_vector(Streams_g-1 downto 0);
-- Axi Accesses
signal AccAddr : std_logic_vector(15 downto 0);
signal AccAddrOffs : std_logic_vector(15 downto 0);
signal AccWr : std_logic_vector(3 downto 0);
signal AccWrData : std_logic_vector(31 downto 0);
signal AccRdData : std_logic_vector(31 downto 0);
signal RegWrVal : slv_reg_type(0 to 15);
signal RegRdVal : slv_reg_type(0 to 15) := (others => (others => '0'));
signal RegWr : std_logic_vector(15 downto 0);
begin
A_Axi_Areset <= not S_Axi_Aresetn;
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process( r, AccAddr, AccWr, AccWrData, StrIrq_Sync, IsArmed, IsRecording, CtxStr_Rdval, CtxWin_Rdval, MaxLevel, StrLastWin_Sync, RegWr, RegWrVal)
variable v : two_process_r;
variable Stream_v : integer range 0 to Streams_g-1;
begin
-- *** Hold variables stable ***
v := r;
-- *** General Register Accesses ***
-- GCFG
if RegWr(16#00#/4) = '1' then
v.Reg_Gcfg_Ena := RegWrVal(16#00#/4)(0);
v.Reg_Gcfg_IrqEna := RegWrVal(16#00#/4)(8);
end if;
RegRdVal(16#00#/4)(0) <= r.Reg_Gcfg_Ena;
RegRdVal(16#00#/4)(8) <= r.Reg_Gcfg_IrqEna;
-- GSTAT
if RegWr(16#04#/4) = '1' then
null;
end if;
RegRdVal(16#04#/4) <= (others => '0');
-- IRQVEC
if RegWr(16#10#/4) = '1' then
v.Reg_IrqVec := r.Reg_IrqVec and (not RegWrVal(16#10#/4)(Streams_g-1 downto 0));
end if;
RegRdVal(16#10#/4)(Streams_g-1 downto 0) <= r.Reg_IrqVec;
-- IRQENA
if RegWr(16#14#/4) = '1' then
v.Reg_IrqEna := RegWrVal(16#14#/4)(Streams_g-1 downto 0);
end if;
RegRdVal(16#14#/4)(Streams_g-1 downto 0) <= r.Reg_IrqEna;
-- STRENA
if RegWr(16#20#/4) = '1' then
v.Reg_StrEna := RegWrVal(16#20#/4)(Streams_g-1 downto 0);
end if;
RegRdVal(16#20#/4)(Streams_g-1 downto 0) <= r.Reg_StrEna;
-- *** Stream Register Accesses ***
v.RegRdval := (others => '0');
v.Reg_Mode_Arm := (others => '0');
v.MaxLvlClr := (others => '0');
if AccAddr(15 downto 9) = X"0" & "001" then
Stream_v := to_integer(unsigned(AccAddr(8 downto 4)));
-- MAXLVLn
if AccAddr(3 downto 0) = X"0" then
if AccWr = DwWrite_c then
v.MaxLvlClr(Stream_v) := '1';
end if;
v.RegRdval(15 downto 0) := MaxLevel(Stream_v);
end if;
-- POSTTRIGn
if AccAddr(3 downto 0) = X"4" then
if AccWr = DwWrite_c then
v.Reg_PostTrig(Stream_v) := AccWrData;
end if;
v.RegRdval := r.Reg_PostTrig(Stream_v);
end if;
-- MODEn / LASTWINn
if AccAddr(3 downto 0) = X"8" then
if AccWr(0) = '1' then
v.Reg_Mode_Recm(Stream_v) := AccWrData(1 downto 0);
end if;
if AccWr(1) = '1' then
v.Reg_Mode_Arm(Stream_v) := AccWrData(8);
end if;
v.RegRdval(1 downto 0) := r.Reg_Mode_Recm(Stream_v);
v.RegRdval(8) := IsArmed(Stream_v);
v.RegRdval(16) := IsRecording(Stream_v);
end if;
-- LASTWINn
if AccAddr(3 downto 0) = X"C" then
-- LASTWINn
v.RegRdval(MaxWindowsBits_c-1 downto 0) := StrLastWin_Sync(Stream_v);
end if;
end if;
-- *** Read Data MUX ***
v.AddrReg := AccAddr;
AccRdData <= (others => '0');
if r.AddrReg(15 downto 12) = X"0" then
AccRdData <= r.RegRdval;
elsif r.AddrReg(15 downto 12) = X"1" then
-- High-low dword in different memories
if r.AddrReg(2) = '0' then
AccRdData <= CtxStr_Rdval(31 downto 0);
else
AccRdData <= CtxStr_Rdval(63 downto 32);
end if;
elsif r.AddrReg(15 downto 14) = "01" then
-- High-low dword in different memories
if r.AddrReg(2) = '0' then
AccRdData <= CtxWin_Rdval(31 downto 0);
else
AccRdData <= CtxWin_Rdval(63 downto 32);
end if;
end if;
-- *** IRQ Handling ***
for i in 0 to Streams_g-1 loop
if (StrIrq_Sync(i) = '1') and (r.Reg_StrEna(i) = '1') then
v.Reg_IrqVec(i) := '1';
end if;
end loop;
if ((r.Reg_IrqVec and r.Reg_IrqEna) /= ZerosVector(Streams_g)) and (r.Reg_Gcfg_IrqEna = '1') then
v.Irq := '1';
else
v.Irq := '0';
end if;
-- *** Assign to signal ***
r_next <= v;
end process;
-- *** Registered Outputs ***
IrqOut <= r.Irq;
PostTrig <= r.Reg_PostTrig;
Arm <= r.Reg_Mode_Arm;
RecMode <= r.Reg_Mode_Recm;
--------------------------------------------
-- Sequential Process
--------------------------------------------
p_seq : process(S_Axi_Aclk)
begin
if rising_edge(S_Axi_Aclk) then
r <= r_next;
if A_Axi_Areset = '1' then
r.Reg_Gcfg_Ena <= '0';
r.Reg_Gcfg_IrqEna <= '0';
r.Reg_IrqVec <= (others => '0');
r.Reg_IrqEna <= (others => '0');
r.Reg_StrEna <= (others => '0');
r.Irq <= '0';
r.Reg_PostTrig <= (others => (others => '0'));
r.Reg_Mode_Recm <= (others => (others => '0'));
r.Reg_Mode_Arm <= (others => '0');
end if;
end if;
end process;
--------------------------------------------
-- Maximum Level Latching (MemClk)
--------------------------------------------
p_maxlvl : process(ClkMem)
begin
if rising_edge(ClkMem) then
if RstMem = '1' then
MaxLevel <= (others => (others => '0'));
else
-- Latch maximum level
for i in 0 to Streams_g-1 loop
if MaxLevelClr_Sync(i) = '1' then
MaxLevel(i) <= (others => '0');
elsif unsigned(InLevel(i)) > unsigned(MaxLevel(i)) then
MaxLevel(i) <= InLevel(i);
end if;
end loop;
end if;
end if;
end process;
--------------------------------------------
-- Component Instantiations
--------------------------------------------
-- *** AXI Interface ***
i_axi : entity work.axi_slave_ipif_reg_mem
generic map (
C_NUM_REG => 16,
C_RESET_VAL => (0 => (others => '0'), 1 => (others => '0'), 2 => (others => '0'), 3 => (others => '0'),
4 => (others => '0'), 5 => (others => '0'), 6 => (others => '0'), 7 => (others => '0'),
8 => (others => '0'), 9 => (others => '0'), 10 => (others => '0'), 11 => (others => '0'),
12 => (others => '0'), 13 => (others => '0'), 14 => (others => '0'), 15 => (others => '0')),
C_S_AXI_ID_WIDTH => 0,
C_S_AXI_DATA_WIDTH => 32,
C_S_AXI_ADDR_WIDTH => 16,
C_S_AXI_ARUSER_WIDTH => 0,
C_S_AXI_RUSER_WIDTH => 0,
C_S_AXI_AWUSER_WIDTH => 0,
C_S_AXI_WUSER_WIDTH => 0,
C_S_AXI_BUSER_WIDTH => 0
)
port map (
s_axi_aclk => S_Axi_Aclk,
s_axi_aresetn => S_Axi_Aresetn,
s_axi_arid => (others => '0'),
s_axi_araddr => S_Axi_ArAddr,
s_axi_arlen => S_Axi_Arlen,
s_axi_arsize => S_Axi_ArSize,
s_axi_arburst => S_Axi_ArBurst,
s_axi_arlock => S_Axi_ArLock,
s_axi_arcache => S_Axi_ArCache,
s_axi_arprot => S_Axi_ArProt,
s_axi_arqos => (others => '0'),
s_axi_arregion => (others => '0'),
s_axi_aruser => (others => '0'),
s_axi_arvalid => S_Axi_ArValid,
s_axi_arready => S_Axi_ArReady,
s_axi_rid => open,
s_axi_rdata => S_Axi_RData,
s_axi_rresp => S_Axi_RResp,
s_axi_rlast => S_Axi_RLast,
s_axi_ruser => open,
s_axi_rvalid => S_Axi_RValid,
s_axi_rready => S_Axi_RReady,
s_axi_awid => (others => '0'),
s_axi_awaddr => S_Axi_AwAddr,
s_axi_awlen => S_Axi_AwLen,
s_axi_awsize => S_Axi_AwSize,
s_axi_awburst => S_Axi_AwBurst,
s_axi_awlock => S_Axi_AwLock,
s_axi_awcache => S_Axi_AwCache,
s_axi_awprot => S_Axi_AwProt,
s_axi_awqos => (others => '0'),
s_axi_awregion => (others => '0'),
s_axi_awuser => (others => '0'),
s_axi_awvalid => S_Axi_AwValid,
s_axi_awready => S_Axi_AwReady,
s_axi_wdata => S_Axi_WData,
s_axi_wstrb => S_Axi_WStrb,
s_axi_wlast => S_Axi_WLast,
s_axi_wuser => (others => '0'),
s_axi_wvalid => S_Axi_WValid,
s_axi_wready => S_Axi_WReady,
s_axi_bid => open,
s_axi_bresp => S_Axi_BResp,
s_axi_buser => open,
s_axi_bvalid => S_Axi_BValid,
s_axi_bready => S_Axi_BReady,
o_reg_rd => open,
i_reg_rdata => RegRdVal,
o_reg_wr => RegWr,
o_reg_wdata => RegWrVal,
o_mem_addr => AccAddrOffs,
o_mem_wr => AccWr,
o_mem_wdata => AccWrData,
i_mem_rdata => AccRdData
);
AccAddr <= std_logic_vector(unsigned(AccAddrOffs) + 16*4);
-- *** Clock Crossings ***
blk_cc_irq : block
begin
g_in : for i in 0 to Streams_g-1 generate
i_cc_irq : entity work.psi_common_simple_cc
generic map (
DataWidth_g => log2ceil(MaxWindows_c)
)
port map (
ClkA => ClkMem,
RstInA => RstMem,
DataA => StrLastWin(i),
VldA => StrIrq(i),
ClkB => S_Axi_Aclk,
RstInB => A_Axi_Areset,
DataB => StrLastWin_Sync(i),
VldB => StrIrq_Sync(i)
);
end generate;
end block;
blk_cc_mem_out : block
signal ccIn, ccOut : std_logic_vector(Streams_g downto 0);
begin
-- Input Assembly
ccIn(Streams_g-1 downto 0) <= r.Reg_StrEna;
ccIn(Streams_g) <= r.Reg_Gcfg_Ena;
-- Instantiation
i_cc_mem_out : entity work.psi_common_bit_cc
generic map (
NumBits_g => Streams_g+1
)
port map (
BitsA => ccIn,
ClkB => ClkMem,
BitsB => ccOut
);
-- Output assembly
StrEna <= ccOut(Streams_g-1 downto 0);
GlbEna <= ccOut(Streams_g);
end block;
i_cc_mem_out_pulse : entity work.psi_common_pulse_cc
generic map (
NumPulses_g => Streams_g
)
port map (
ClkA => S_Axi_Aclk,
RstInA => A_Axi_Areset,
PulseA => r.MaxLvlClr,
ClkB => ClkMem,
RstInB => RstMem,
PulseB => MaxLevelClr_Sync
);
-- *** Stream Context Memory ***
-- Signal Assembly
AddrCtxStr <= AccAddr(15 downto 12) = X"1";
CtxStr_WeLo <= '1' when AccWr = DwWrite_c and AddrCtxStr and AccAddr(2) = '0' else '0';
CtxStr_WeHi <= '1' when AccWr = DwWrite_c and AddrCtxStr and AccAddr(2) = '1' else '0';
CtxStr_AddrB <= std_logic_vector(to_unsigned(CtxStr_Cmd.Stream, log2ceil(Streams_g))) & CtxStr_Cmd.Sel;
-- Memory is split organized as 64 bit memory for historical reasons (Tosca TMEM is 64-bit)
-- Low DWORD memory
i_mem_ctx_lo : entity work.psi_common_tdp_ram
generic map (
Depth_g => DepthCtxStr_c,
Width_g => 32,
Behavior_g => "RBW"
)
port map (
ClkA => S_Axi_Aclk,
AddrA => AccAddr(CtxStrAddrHigh_c downto 3),
WrA => CtxStr_WeLo,
DinA => AccWrData,
DoutA => CtxStr_Rdval(31 downto 0),
ClkB => ClkMem,
AddrB => CtxStr_AddrB,
WrB => CtxStr_Cmd.WenLo,
DinB => CtxStr_Cmd.WdatLo,
DoutB => CtxStr_Resp.RdatLo
);
-- High DWORD memory
i_mem_ctx_hi : entity work.psi_common_tdp_ram
generic map (
Depth_g => DepthCtxStr_c,
Width_g => 32,
Behavior_g => "RBW"
)
port map (
ClkA => S_Axi_Aclk,
AddrA => AccAddr(CtxStrAddrHigh_c downto 3),
WrA => CtxStr_WeHi,
DinA => AccWrData,
DoutA => CtxStr_Rdval(63 downto 32),
ClkB => ClkMem,
AddrB => CtxStr_AddrB,
WrB => CtxStr_Cmd.WenHi,
DinB => CtxStr_Cmd.WdatHi,
DoutB => CtxStr_Resp.RdatHi
);
-- *** Window Context Memory ***
-- Signal Assembly
AddrCtxWin <= AccAddr(15 downto 14) = "01";
CtxWin_WeLo <= '1' when AccWr = DwWrite_c and AddrCtxWin and AccAddr(2) = '0' else '0';
CtxWin_WeHi <= '1' when AccWr = DwWrite_c and AddrCtxWin and AccAddr(2) = '1' else '0';
CtxWin_AddrB <= std_logic_vector(to_unsigned(CtxWin_Cmd.Stream, log2ceil(Streams_g))) &
std_logic_vector(to_unsigned(CtxWin_Cmd.Window, log2ceil(MaxWindows_g))) &
CtxWin_Cmd.Sel;
-- Memory is split organized as 64 bit memory for historical reasons (Tosca TMEM is 64-bit)
-- Low DWORD memory
i_mem_win_lo : entity work.psi_common_tdp_ram
generic map (
Depth_g => DepthCtxWin_c,
Width_g => 32,
Behavior_g => "RBW"
)
port map (
ClkA => S_Axi_Aclk,
AddrA => AccAddr(CtxWinAddrHigh_c downto 3),
WrA => CtxWin_WeLo,
DinA => AccWrData,
DoutA => CtxWin_Rdval(31 downto 0),
ClkB => ClkMem,
AddrB => CtxWin_AddrB,
WrB => CtxWin_Cmd.WenLo,
DinB => CtxWin_Cmd.WdatLo,
DoutB => CtxWin_Resp.RdatLo
);
-- High DWORD memory
i_mem_win_hi : entity work.psi_common_tdp_ram
generic map (
Depth_g => DepthCtxWin_c,
Width_g => 32,
Behavior_g => "RBW"
)
port map (
ClkA => S_Axi_Aclk,
AddrA => AccAddr(CtxWinAddrHigh_c downto 3),
WrA => CtxWin_WeHi,
DinA => AccWrData,
DoutA => CtxWin_Rdval(63 downto 32),
ClkB => ClkMem,
AddrB => CtxWin_AddrB,
WrB => CtxWin_Cmd.WenHi,
DinB => CtxWin_Cmd.WdatHi,
DoutB => CtxWin_Resp.RdatHi
);
end architecture;

View File

@ -46,6 +46,7 @@ entity psi_ms_daq_reg_tmem is
-- Logic Interface (SMEM Clk)
StrIrq : in std_logic_vector(Streams_g-1 downto 0);
StrLastWin : in WinType_a(Streams_g-1 downto 0);
StrEna : out std_logic_vector(Streams_g-1 downto 0);
GlbEna : out std_logic;
InLevel : in t_aslv16(Streams_g-1 downto 0)
@ -96,13 +97,14 @@ architecture rtl of psi_ms_daq_reg_tmem is
-- Clock Crossing Signals
signal StrIrq_Sync : std_logic_vector(Streams_g-1 downto 0);
signal StrLastWin_Sync : WinType_a(Streams_g-1 downto 0);
signal MaxLevel_Sync : t_aslv16(Streams_g-1 downto 0);
signal MaxLevelClr_Sync : std_logic_vector(Streams_g-1 downto 0);
begin
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process( r, TmemRqst, StrIrq_Sync, IsArmed, IsRecording, CtxStr_Rdval, CtxWin_Rdval, MaxLevel)
p_comb : process( r, TmemRqst, StrIrq_Sync, IsArmed, IsRecording, CtxStr_Rdval, CtxWin_Rdval, MaxLevel, StrLastWin_Sync)
variable v : two_process_r;
variable Stream_v : integer range 0 to Streams_g-1;
begin
@ -173,7 +175,7 @@ begin
v.RegRdval(63 downto 32) := r.Reg_PostTrig(Stream_v);
end if;
-- MODEn
-- MODEn / LASTWINn
if TmemRqst.ADD(3 downto 0) = X"8" then
-- MODEn
if TmemRqst.WE(0) = '1' then
@ -185,7 +187,10 @@ begin
v.RegRdval(1 downto 0) := r.Reg_Mode_Recm(Stream_v);
v.RegRdval(8) := IsArmed(Stream_v);
v.RegRdval(16) := IsRecording(Stream_v);
-- LASTWINn
v.RegRdval(StrLastWin_Sync(Stream_v)'high+32 downto 32) := StrLastWin_Sync(Stream_v);
end if;
end if;
end if;
@ -276,19 +281,27 @@ begin
--------------------------------------------
-- *** Clock Crossings ***
i_cc_smem_in : entity work.psi_common_pulse_cc
generic map (
NumPulses_g => Streams_g
)
port map (
ClkA => ClkSmem,
RstInA => RstSmem,
PulseA => StrIrq,
ClkB => ClkTmem,
RstInB => RstTmem,
PulseB => StrIrq_Sync
);
blk_cc_irq : block
begin
g_in : for i in 0 to Streams_g-1 generate
i_cc_irq : entity work.psi_common_simple_cc
generic map (
DataWidth_g => log2ceil(MaxWindows_c)
)
port map (
ClkA => ClkSmem,
RstInA => RstSmem,
DataA => StrLastWin(i),
VldA => StrIrq(i),
ClkB => ClkTmem,
RstInB => RstTmem,
DataB => StrLastWin_Sync(i),
VldB => StrIrq_Sync(i)
);
end generate;
end block;
blk_cc_smem_out : block
signal ccIn, ccOut : std_logic_vector(Streams_g downto 0);
begin

View File

@ -15,7 +15,7 @@ library work;
------------------------------------------------------------------------------
-- Entity Declaration
------------------------------------------------------------------------------
entity psi_ms_daq is
entity psi_ms_daq_tosca is
generic (
Streams_g : positive range 1 to 32 := 2;
StreamWidth_g : t_ainteger := (16, 16);
@ -26,8 +26,8 @@ entity psi_ms_daq is
StreamTsFifoDepth_g : t_ainteger := (16, 16);
StreamUseTs_g : t_abool := (true, true);
MaxWindows_g : positive range 1 to 32 := 16;
MinBurstSize_g : integer := 512;
MaxBurstSize_g : integer := 512
MinBurstSize_g : integer range 1 to 512 := 512;
MaxBurstSize_g : integer range 1 to 512 := 512
);
port (
-- Data Stream Input
@ -58,7 +58,7 @@ end entity;
------------------------------------------------------------------------------
-- Architecture Declaration
------------------------------------------------------------------------------
architecture rtl of psi_ms_daq is
architecture rtl of psi_ms_daq_tosca is
-- Control Signals
signal Rst : std_logic;
@ -104,6 +104,7 @@ architecture rtl of psi_ms_daq is
-- Status
signal Stat_StrIrq : std_logic_vector(Streams_g-1 downto 0);
signal Stat_StrLastWin : WinType_a(Streams_g-1 downto 0);
signal Stat_IsArmed : std_logic_vector(Streams_g-1 downto 0);
signal Stat_IsRecording : std_logic_vector(Streams_g-1 downto 0);
@ -145,6 +146,7 @@ begin
CtxWin_Resp => CtxWin_Resp,
InLevel => InpSm_Level,
StrIrq => Stat_StrIrq,
StrLastWin => Stat_StrLastWin,
StrEna => Cfg_StrEna,
GlbEna => Cfg_GlbEna
);
@ -177,15 +179,15 @@ begin
Str_Data => StrInput,
Str_Trig => Str_Trig(str),
Str_Ts => Str_Ts(str),
ClkTmem => Tmem_Clk,
RstTmem => Tmem_Rst,
ClkReg => Tmem_Clk,
RstReg => Tmem_Rst,
PostTrigSpls => Cfg_PostTrig(str),
Mode => Cfg_RecMode(str),
Arm => Cfg_Arm(str),
IsArmed => Stat_IsArmed(str),
IsRecording => Stat_IsRecording(str),
ClkSmem => Smem_Clk,
RstSmem => InRst,
ClkMem => Smem_Clk,
RstMem => InRst,
Daq_Vld => InpDma_Vld(str),
Daq_Rdy => InpDma_Rdy(str),
Daq_Data => InpDma_Data(str),
@ -219,6 +221,7 @@ begin
GlbEna => Cfg_GlbEna,
StrEna => Cfg_StrEna,
StrIrq => Stat_StrIrq,
StrLastWin => Stat_StrLastWin,
Inp_HasLast => Sm_HasLast,
Inp_Level => InpSm_Level,
Ts_Vld => InpSm_TsVld,

View File

@ -18,6 +18,7 @@ add_sources $LibPath {
psi_tb/hdl/psi_tb_activity_pkg.vhd \
psi_common/hdl/psi_common_array_pkg.vhd \
psi_common/hdl/psi_common_math_pkg.vhd \
psi_tb/hdl/psi_tb_axi_pkg.vhd \
psi_common/hdl/psi_common_logic_pkg.vhd \
psi_common/hdl/psi_common_sdp_ram.vhd \
psi_common/hdl/psi_common_pulse_cc.vhd \
@ -28,8 +29,12 @@ add_sources $LibPath {
psi_common/hdl/psi_common_arb_priority.vhd \
psi_common/hdl/psi_common_sync_fifo.vhd \
psi_common/hdl/psi_common_tdp_ram.vhd \
psi_common/hdl/psi_common_axi_master_simple.vhd \
psi_common/hdl/psi_common_wconv_n2xn.vhd \
psi_common/hdl/psi_common_axi_master_full.vhd \
../../BoardSupport/IFC1210/smem_master/hdl/smem_master_types_pkg.vhd \
../../BoardSupport/IFC1210/smem_master/hdl/smem_master_write.vhd \
../VivadoIp/axi_slave_ipif_package/hdl/axi_slave_ipif_package.vhd \
} -tag lib
# project sources
@ -39,7 +44,10 @@ add_sources "../hdl" {
psi_ms_daq_daq_sm.vhd \
psi_ms_daq_daq_dma.vhd \
psi_ms_daq_reg_tmem.vhd \
psi_ms_daq.vhd \
psi_ms_daq_tosca.vhd \
psi_ms_daq_axi_if.vhd \
psi_ms_daq_reg_axi.vhd \
psi_ms_daq_axi.vhd \
} -tag src
# testbenches
@ -73,12 +81,18 @@ add_sources "../tb" {
psi_ms_daq_daq_dma/psi_ms_daq_daq_dma_tb_case_aligned.vhd \
psi_ms_daq_daq_dma/psi_ms_daq_daq_dma_tb_case_errors.vhd \
psi_ms_daq_daq_dma/psi_ms_daq_daq_dma_tb.vhd \
psi_ms_daq/psi_ms_daq_tb_pkg.vhd \
psi_ms_daq/psi_ms_daq_tb_str0_pkg.vhd \
psi_ms_daq/psi_ms_daq_tb_str1_pkg.vhd \
psi_ms_daq/psi_ms_daq_tb_str2_pkg.vhd \
psi_ms_daq/psi_ms_daq_tb_str3_pkg.vhd \
psi_ms_daq/psi_ms_daq_tb.vhd \
psi_ms_daq_tosca/psi_ms_daq_tosca_tb_pkg.vhd \
psi_ms_daq_tosca/psi_ms_daq_tosca_tb_str0_pkg.vhd \
psi_ms_daq_tosca/psi_ms_daq_tosca_tb_str1_pkg.vhd \
psi_ms_daq_tosca/psi_ms_daq_tosca_tb_str2_pkg.vhd \
psi_ms_daq_tosca/psi_ms_daq_tosca_tb_str3_pkg.vhd \
psi_ms_daq_tosca/psi_ms_daq_tosca_tb.vhd \
psi_ms_daq_axi/psi_ms_daq_axi_tb_pkg.vhd \
psi_ms_daq_axi/psi_ms_daq_axi_tb_str0_pkg.vhd \
psi_ms_daq_axi/psi_ms_daq_axi_tb_str1_pkg.vhd \
psi_ms_daq_axi/psi_ms_daq_axi_tb_str2_pkg.vhd \
psi_ms_daq_axi/psi_ms_daq_axi_tb_str3_pkg.vhd \
psi_ms_daq_axi/psi_ms_daq_axi_tb.vhd \
} -tag tb
#TB Runs
@ -98,7 +112,10 @@ add_tb_run
create_tb_run "psi_ms_daq_daq_dma_tb"
add_tb_run
create_tb_run "psi_ms_daq_tb"
create_tb_run "psi_ms_daq_tosca_tb"
add_tb_run
create_tb_run "psi_ms_daq_axi_tb"
add_tb_run

View File

@ -0,0 +1,424 @@
------------------------------------------------------------
-- Testbench generated by TbGen.py
------------------------------------------------------------
-- see Library/Python/TbGenerator
------------------------------------------------------------
-- Libraries
------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_ms_daq_pkg.all;
library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.psi_tb_axi_pkg.all;
use work.psi_ms_daq_axi_tb_pkg.all;
use work.psi_ms_daq_axi_tb_str0_pkg.all;
use work.psi_ms_daq_axi_tb_str1_pkg.all;
use work.psi_ms_daq_axi_tb_str2_pkg.all;
use work.psi_ms_daq_axi_tb_str3_pkg.all;
------------------------------------------------------------
-- Entity Declaration
------------------------------------------------------------
entity psi_ms_daq_axi_tb is
end entity;
------------------------------------------------------------
-- Architecture
------------------------------------------------------------
architecture sim of psi_ms_daq_axi_tb is
-- TB Control
signal TbRunning : boolean := true;
signal PrintIrq_c : boolean := PrintDefault_c;
-- Constants
constant StrCount_c : integer := 4;
constant ClkFreq_c : t_areal := (0=>250.0e6, 1=>125.0e6, 2=>80.0e6, 3=>200.0e6);
-- Axi Memory
constant ID_WIDTH : integer := 1;
constant ADDR_WIDTH : integer := 32;
constant USER_WIDTH : integer := 1;
constant DATA_WIDTH : integer := 64;
constant BYTE_WIDTH : integer := DATA_WIDTH/8;
subtype ID_RANGE is natural range ID_WIDTH-1 downto 0;
subtype ADDR_RANGE is natural range ADDR_WIDTH-1 downto 0;
subtype USER_RANGE is natural range USER_WIDTH-1 downto 0;
subtype DATA_RANGE is natural range DATA_WIDTH-1 downto 0;
subtype BYTE_RANGE is natural range BYTE_WIDTH-1 downto 0;
subtype axi_ms_t is axi_ms_r ( arid(ID_RANGE), awid(ID_RANGE),
araddr(ADDR_RANGE), awaddr(ADDR_RANGE),
aruser(USER_RANGE), awuser(USER_RANGE), wuser(USER_RANGE),
wdata(DATA_RANGE),
wstrb(BYTE_RANGE));
subtype axi_sm_t is axi_sm_r ( rid(ID_RANGE), bid(ID_RANGE),
ruser(USER_RANGE), buser(USER_RANGE),
rdata(DATA_RANGE));
-- Axi Registers
constant REG_ID_WIDTH : integer := 1;
constant REG_ADDR_WIDTH : integer := 16;
constant REG_USER_WIDTH : integer := 1;
constant REG_DATA_WIDTH : integer := 32;
constant REG_BYTE_WIDTH : integer := REG_DATA_WIDTH/8;
subtype REG_ID_RANGE is natural range REG_ID_WIDTH-1 downto 0;
subtype REG_ADDR_RANGE is natural range REG_ADDR_WIDTH-1 downto 0;
subtype REG_USER_RANGE is natural range REG_USER_WIDTH-1 downto 0;
subtype REG_DATA_RANGE is natural range REG_DATA_WIDTH-1 downto 0;
subtype REG_BYTE_RANGE is natural range REG_BYTE_WIDTH-1 downto 0;
subtype reg_axi_ms_t is axi_ms_r ( arid(REG_ID_RANGE), awid(REG_ID_RANGE),
araddr(REG_ADDR_RANGE), awaddr(REG_ADDR_RANGE),
aruser(REG_USER_RANGE), awuser(REG_USER_RANGE), wuser(REG_USER_RANGE),
wdata(REG_DATA_RANGE),
wstrb(REG_BYTE_RANGE));
subtype reg_axi_sm_t is axi_sm_r ( rid(REG_ID_RANGE), bid(REG_ID_RANGE),
ruser(REG_USER_RANGE), buser(REG_USER_RANGE),
rdata(REG_DATA_RANGE));
-- Port signals
signal Str_Clk : std_logic_vector(StrCount_c-1 downto 0) := (others => '0');
signal Str0_Data : std_logic_vector(7 downto 0) := (others => '0');
signal Str1_Data : std_logic_vector(15 downto 0) := (others => '0');
signal Str2_Data : std_logic_vector(15 downto 0) := (others => '0');
signal Str3_Data : std_logic_vector(31 downto 0) := (others => '0');
signal Timestamp : t_aslv64(StrCount_c-1 downto 0) := (others => (others => '0'));
signal Str_Vld : std_logic_vector(StrCount_c-1 downto 0) := (others => '0');
signal Str_Rdy : std_logic_vector(StrCount_c-1 downto 0) := (others => '0');
signal Str_Trig : std_logic_vector(StrCount_c-1 downto 0) := (others => '0');
signal M_Axi_Aclk : std_logic := '0';
signal S_Axi_Aclk : std_logic := '0';
signal M_Axi_Aresetn : std_logic := '0';
signal S_Axi_Aresetn : std_logic := '0';
signal Irq : std_logic := '0';
signal axi_ms : axi_ms_t;
signal axi_sm : axi_sm_t;
signal reg_axi_ms : reg_axi_ms_t;
signal reg_axi_sm : reg_axi_sm_t;
procedure IrqHandler( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
variable v : integer;
variable slv : std_logic_vector(31 downto 0);
begin
print("###################################### IRQ Detected #########################################", PrintIrq_c);
wait until rising_edge(clk);
AxiRead32(16#0010#, v, clk, rqst, rsp);
slv := std_logic_vector(to_unsigned(v, 32));
AxiWrite32(16#0010#, v, clk, rqst, rsp);
wait until rising_edge(clk);
for i in 0 to StrCount_c-1 loop
if slv(i) = '1' then
case i is
when 0 => Str0Handler(clk, rqst, rsp);
when 1 => Str1Handler(clk, rqst, rsp);
when 2 => Str2Handler(clk, rqst, rsp);
when 3 => Str3Handler(clk, rqst, rsp);
when others => null;
end case;
end if;
end loop;
-- Delay to ensure IRQ is cleared
for i in 0 to 5 loop
wait until rising_edge(clk);
end loop;
end procedure;
begin
------------------------------------------------------------
-- DUT Instantiation
------------------------------------------------------------
i_dut : entity work.psi_ms_daq_axi
generic map (
Streams_g => StrCount_c,
StreamWidth_g => (0=>8, 1=>16, 2=>16, 3=>32),
StreamPrio_g => (0=>1, 1=>3, 2=>2, 3=>2),
StreamBuffer_g => (0=>32, 1=>128, 2=>128, 3=>128),
StreamTimeout_g => (0=>5.0e-6, 1=>1.0e-3, 2=>1.0e-3, 3=>1.0e-3),
StreamClkFreq_g => ClkFreq_c,
StreamTsFifoDepth_g => (0=>16, 1=>16, 2=>16, 3=>16),
StreamUseTs_g => (0=>true, 1=>true, 2=>true, 3=>false),
MaxWindows_g => work.psi_ms_daq_axi_tb_pkg.MaxWindows_c,
MinBurstSize_g => 16,
MaxBurstSize_g => 128,
AxiFifoDepth_g => 512
)
port map (
Str_Clk => Str_Clk,
Str_Data(0)(7 downto 0) => Str0_Data,
Str_Data(0)(63 downto 8) => (others => '0'),
Str_Data(1)(15 downto 0) => Str1_Data,
Str_Data(1)(63 downto 16) => (others => '0'),
Str_Data(2)(15 downto 0) => Str2_Data,
Str_Data(2)(63 downto 16) => (others => '0'),
Str_Data(3)(31 downto 0) => Str3_Data,
Str_Data(3)(63 downto 32) => (others => '0'),
Str_Ts => Timestamp,
Str_Vld => Str_Vld,
Str_Rdy => Str_Rdy,
Str_Trig => Str_Trig,
Irq => Irq,
S_Axi_Aclk => S_Axi_Aclk,
S_Axi_Aresetn => S_Axi_Aresetn,
S_Axi_ArAddr => reg_axi_ms.araddr,
S_Axi_Arlen => reg_axi_ms.arlen,
S_Axi_ArSize => reg_axi_ms.arsize,
S_Axi_ArBurst => reg_axi_ms.arburst,
S_Axi_ArLock => reg_axi_ms.arlock,
S_Axi_ArCache => reg_axi_ms.arcache,
S_Axi_ArProt => reg_axi_ms.arprot,
S_Axi_ArValid => reg_axi_ms.arvalid,
S_Axi_ArReady => reg_axi_sm.arready,
S_Axi_RData => reg_axi_sm.rdata,
S_Axi_RResp => reg_axi_sm.rresp,
S_Axi_RLast => reg_axi_sm.rlast,
S_Axi_RValid => reg_axi_sm.rvalid,
S_Axi_RReady => reg_axi_ms.rready,
S_Axi_AwAddr => reg_axi_ms.awaddr,
S_Axi_AwLen => reg_axi_ms.awlen,
S_Axi_AwSize => reg_axi_ms.awsize,
S_Axi_AwBurst => reg_axi_ms.awburst,
S_Axi_AwLock => reg_axi_ms.awlock,
S_Axi_AwCache => reg_axi_ms.awcache,
S_Axi_AwProt => reg_axi_ms.awprot,
S_Axi_AwValid => reg_axi_ms.awvalid,
S_Axi_AwReady => reg_axi_sm.awready,
S_Axi_WData => reg_axi_ms.wdata,
S_Axi_WStrb => reg_axi_ms.wstrb,
S_Axi_WLast => reg_axi_ms.wlast,
S_Axi_WValid => reg_axi_ms.wvalid,
S_Axi_WReady => reg_axi_sm.wready,
S_Axi_BResp => reg_axi_sm.bresp,
S_Axi_BValid => reg_axi_sm.bvalid,
S_Axi_BReady => reg_axi_ms.bready,
M_Axi_Aclk => M_Axi_Aclk,
M_Axi_Aresetn => M_Axi_Aresetn,
M_Axi_AwAddr => axi_ms.awaddr,
M_Axi_AwLen => axi_ms.awlen,
M_Axi_AwSize => axi_ms.awsize,
M_Axi_AwBurst => axi_ms.awburst,
M_Axi_AwLock => axi_ms.awlock,
M_Axi_AwCache => axi_ms.awcache,
M_Axi_AwProt => axi_ms.awprot,
M_Axi_AwValid => axi_ms.awvalid,
M_Axi_AwReady => axi_sm.awready,
M_Axi_WData => axi_ms.wdata,
M_Axi_WStrb => axi_ms.wstrb,
M_Axi_WLast => axi_ms.wlast,
M_Axi_WValid => axi_ms.wvalid,
M_Axi_WReady => axi_sm.wready,
M_Axi_BResp => axi_sm.bresp,
M_Axi_BValid => axi_sm.bvalid,
M_Axi_BReady => axi_ms.bready,
M_Axi_ArAddr => axi_ms.araddr,
M_Axi_ArLen => axi_ms.arlen,
M_Axi_ArSize => axi_ms.arsize,
M_Axi_ArBurst => axi_ms.arburst,
M_Axi_ArLock => axi_ms.arlock,
M_Axi_ArCache => axi_ms.arcache,
M_Axi_ArProt => axi_ms.arprot,
M_Axi_ArValid => axi_ms.arvalid,
M_Axi_ArReady => axi_sm.arready,
M_Axi_RData => axi_sm.rdata,
M_Axi_RResp => axi_sm.rresp,
M_Axi_RLast => axi_sm.rlast,
M_Axi_RValid => axi_sm.rvalid,
M_Axi_RReady => axi_ms.rready
);
------------------------------------------------------------
-- Emulate Memory
------------------------------------------------------------
p_mem : process
variable Address_v : integer;
variable Size_v : integer;
begin
axi_slave_init(axi_sm);
wait until rising_edge(M_Axi_Aclk);
while TbRunning loop
axi_sm.awready <= '1';
wait until (rising_edge(M_Axi_Aclk) and axi_ms.awvalid = '1') or (not TbRunning);
if TbRunning then
axi_sm.awready <= '0';
axi_sm.wready <= '1';
Address_v := to_integer(unsigned(axi_ms.awaddr));
Size_v := to_integer(unsigned(axi_ms.awlen))+1;
for qw in 0 to Size_v-1 loop
wait until rising_edge(M_Axi_Aclk) and axi_ms.wvalid = '1';
for byte in 0 to 7 loop
if axi_ms.wstrb(byte) = '1' then
Memory(Address_v+qw*8+byte) <= axi_ms.wdata(byte*8+7 downto byte*8);
end if;
end loop;
end loop;
StdlCompare(1, axi_ms.wlast, "Last not received at end of burst");
axi_sm.wready <= '0';
axi_sm.bresp <= xRESP_OKAY_c;
axi_sm.bvalid <= '1';
wait until rising_edge(M_Axi_Aclk) and axi_ms.bready = '1';
axi_sm.bvalid <= '0';
end if;
end loop;
wait;
end process;
------------------------------------------------------------
-- Clocks
------------------------------------------------------------
p_clk_axi_mem : process
constant Frequency_c : real := real(200e6);
begin
while TbRunning loop
wait for 0.5*(1 sec)/Frequency_c;
M_Axi_Aclk <= not M_Axi_Aclk;
end loop;
wait;
end process;
p_clk_axi_reg : process
constant Frequency_c : real := real(166e6);
begin
while TbRunning loop
wait for 0.5*(1 sec)/Frequency_c;
S_Axi_Aclk <= not S_Axi_Aclk;
end loop;
wait;
end process;
g_clk_str : for i in 0 to StrCount_c-1 generate
p_clk_str : process
begin
while TbRunning loop
wait for 0.5*(1 sec)/(ClkFreq_c(i)+0.1e6);
Str_Clk(i) <= not Str_Clk(i);
end loop;
wait;
end process;
end generate;
------------------------------------------------------------
-- Reg-Access Process
------------------------------------------------------------
p_regacc : process
variable StartTime_v : time;
variable Stream1Armed_v : boolean := false;
variable Stream2Armed_v : boolean := false;
begin
print("*** Info ***");
print("This testbench does not print any status information by default (only errors).");
print("To change this behavior, change the constant PrintDefault_c in psi_ms_daq_axi_tb_pkg.");
axi_master_init(reg_axi_ms);
wait for 1 us;
S_Axi_Aresetn <= '1';
M_Axi_Aresetn <= '1';
-- *** Initial Configuration ***
AxiExpect32(16#0010#, 0, S_Axi_Aclk, reg_axi_ms, reg_axi_sm, "Inital IRQVEC");
AxiWriteAndRead32(16#0014#, 16#000F#, S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
AxiWriteAndRead32(16#0020#, 16#000F#, S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
-- Stream Setup
Str0Setup(S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
Str1Setup(S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
Str2Setup(S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
Str3Setup(S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
-- Enable
AxiWriteAndRead32(16#0000#, 16#0101#, S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
-- *** Run Test ***
StartTime_v := now;
while now < StartTime_v+150 us loop
wait until rising_edge(S_Axi_Aclk);
-- IRQ Handling
if Irq = '1' then
IrqHandler(S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
end if;
-- Regular actions
Str0Update(S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
Str1Update(S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
Str2Update(S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
Str3Update(S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
end loop;
TbRunning <= false;
-- *** Check end state ***
assert Str0WinCheck >= 4 report "###ERROR###: Stream 0 checks not completed" severity error;
assert Str1WinCheck = 1 report "###ERROR###: Stream 1 checks not completed" severity error;
assert Str2WinCheck = 2 report "###ERROR###: Stream 2 checks not completed" severity error;
assert Str3WinCheck = 2 report "###ERROR###: Stream 3 checks not completed" severity error;
wait;
end process;
------------------------------------------------------------
-- Timestamp Processes
------------------------------------------------------------
g_ts : for i in 0 to StrCount_c-1 generate
p_ts : process
begin
while TbRunning loop
wait until rising_edge(Str_Clk(0));
Timestamp(0) <= std_logic_vector(unsigned(Timestamp(0)) + 1);
end loop;
wait;
end process;
end generate;
------------------------------------------------------------
-- Data Generation Processes
------------------------------------------------------------
p_str0 : process
variable IrqOn : boolean := false;
begin
wait until rising_edge(Str_Clk(0));
while TbRunning loop
Str0Sample(Str_Clk(0), Str_Vld(0), Str_Trig(0), Str0_Data);
end loop;
wait;
end process;
p_str1 : process
begin
Str1Data(Str_Clk(1), Str_Vld(1), Str_Trig(1), Str1_Data);
wait;
end process;
p_str2 : process
begin
Str2Data(Str_Clk(2), Str_Vld(2), Str_Trig(2), Str2_Data);
wait;
end process;
p_str3 : process
begin
Str3Data(Str_Clk(3), Str_Vld(3), Str_Trig(3), Str3_Data);
wait;
end process;
------------------------------------------------------------
-- Check Process
------------------------------------------------------------
end;

View File

@ -0,0 +1,477 @@
------------------------------------------------------------
-- Libraries
------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_ms_daq_pkg.all;
library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.psi_tb_axi_pkg.all;
------------------------------------------------------------
-- Package Header
------------------------------------------------------------
package psi_ms_daq_axi_tb_pkg is
--------------------------------------------------------
-- Global Stuff
--------------------------------------------------------
constant MemSize_c : integer := 16#10000#;
signal Memory : t_aslv8(0 to MemSize_c-1);
constant MaxWindows_c : integer := 16;
constant PrintDefault_c : boolean := false;
--------------------------------------------------------
-- Register MAP
--------------------------------------------------------
constant REG_CONF_REGION : integer := 16#0000#;
constant REG_CONF_GCFG_ADDR : integer := REG_CONF_REGION+16#000#;
constant REG_CONF_GSTAT_ADDR : integer := REG_CONF_REGION+16#004#;
constant REG_CONF_IRQVEC_ADDR : integer := REG_CONF_REGION+16#010#;
constant REG_CONF_IRQENA_ADDR : integer := REG_CONF_REGION+16#014#;
constant REG_CONF_STRENA_ADDR : integer := REG_CONF_REGION+16#020#;
constant REG_CONF_Xn_STEP : integer := 16#10#;
constant REG_CONF_MAXLVLn : integer := 16#200#;
constant REG_CONF_POSTTRIGn : integer := 16#204#;
constant REG_CONF_MODEn : integer := 16#208#;
constant REG_CONF_LASTWINn : integer := 16#20C#;
constant VAL_MODE_RECM_CONT : integer := 0*2**0;
constant VAL_MODE_RECM_TRIGMASK : integer := 1*2**0;
constant VAL_MODE_RECM_SINGLE : integer := 2*2**0;
constant VAL_MODE_RECM_MANUAL : integer := 3*2**0;
constant VAL_MODE_ARM : integer := 1*2**8;
constant VAL_MODE_RECORDING : integer := 1*2**16;
constant REG_CTX_REGION : integer := 16#1000#;
constant REG_CTX_Xn_STEP : integer := 16#20#;
constant REG_CTX_SCFGn : integer := 16#00#;
constant VAL_SCFG_RINGBUF : integer := 1*2**0;
constant VAL_SCFG_OVERWRITE : integer := 1*2**8;
constant SFT_SCFG_WINCNT : integer := 16;
constant SFT_SCFG_WINCUR : integer := 24;
constant MSK_SCFG_WINCUR : integer := 16#1F000000#;
constant REG_CTX_BUFSTARTn : integer := 16#04#;
constant REG_CTX_WINSIZEn : integer := 16#08#;
constant REG_CTX_PTRn : integer := 16#0C#;
constant REG_WIN_REGION : integer := 16#4000#;
constant REG_WIN_STRn_STEP : integer := MaxWindows_c*16#10#;
constant REG_WIN_WINn_STEP : integer := 16#10#;
constant REG_WIN_WINCNT : integer := 16#00#;
constant MSK_WIN_WINCNT_CNT : integer := 16#7FFFFFFF#;
constant REG_WIN_WINLAST : integer := 16#04#;
constant REG_WIN_TSLO : integer := 16#08#;
constant REG_WIN_TSHI : integer := 16#0C#;
--------------------------------------------------------
-- Helper Procedures
--------------------------------------------------------
function IntAnd( int : in integer;
op : in integer) return integer;
procedure print( str : in string;
ena : in boolean);
--------------------------------------------------------
-- Axi Procedures
--------------------------------------------------------
procedure AxiWrite32( address : in integer;
value : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r);
procedure AxiRead32( address : in integer;
value : out integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r);
procedure AxiExpect32( address : in integer;
value : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
msg : in string := "");
procedure AxiWriteAndRead32( address : in integer;
value : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
msg : in string := "");
--------------------------------------------------------
-- High Level Procedures
--------------------------------------------------------
procedure HlCheckMaxLvl( str : in integer;
expLevel : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r);
procedure HlSetPostTrig( str : in integer;
val : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r);
procedure HlSetMode( str : in integer;
val : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r);
procedure HlConfStream( str : in integer;
bufstart : in integer;
ringbuf : in boolean;
overwrite : in boolean;
wincnt : in integer;
winsize : in integer;
signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
procedure HlIsRecording( str : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out boolean);
procedure HlGetPtr( str : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer);
procedure HlGetMaxLvl( str : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer);
procedure HlGetLastWin( str : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer);
procedure HlGetCurWin( str : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer);
procedure HlGetWinCnt( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer);
procedure HlIsTrigWin( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out boolean);
procedure HlClrWinCnt( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r);
procedure HlGetWinLast( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer);
procedure HlGetTsLo( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer);
procedure HlGetTsHi( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer);
end package;
------------------------------------------------------------
-- Package Body
------------------------------------------------------------
package body psi_ms_daq_axi_tb_pkg is
--------------------------------------------------------
-- Helper Procedures
--------------------------------------------------------
function IntAnd( int : in integer;
op : in integer) return integer is
variable intu, opu : signed(31 downto 0);
begin
intu := to_signed(int, 32);
opu := to_signed(op, 32);
return to_integer(intu and opu);
end function;
procedure print( str : in string;
ena : in boolean) is
begin
if ena then
print(str);
end if;
end procedure;
--------------------------------------------------------
-- Axi Procedures
--------------------------------------------------------
procedure AxiWrite32( address : in integer;
value : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r) is
begin
axi_single_write(address, value, ms, sm, clk);
end procedure;
procedure AxiRead32( address : in integer;
value : out integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r) is
begin
axi_single_read(address, value, ms, sm, clk);
end procedure;
procedure AxiExpect32( address : in integer;
value : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
msg : in string := "") is
begin
axi_single_expect(address, value, ms, sm, clk, msg);
end procedure;
procedure AxiWriteAndRead32( address : in integer;
value : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
msg : in string := "") is
begin
axi_single_write(address, value, ms, sm, clk);
wait for 400 ns;
wait until rising_edge(clk);
axi_single_expect(address, value, ms, sm, clk, msg);
end procedure;
--------------------------------------------------------
-- High Level Procedures
--------------------------------------------------------
procedure HlCheckMaxLvl( str : in integer;
expLevel : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r) is
begin
axi_single_expect(REG_CONF_MAXLVLn+REG_CONF_Xn_STEP*str, expLevel, ms, sm, clk, "HlCheckMaxLvl failed");
end procedure;
procedure HlSetPostTrig( str : in integer;
val : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r) is
begin
AxiWriteAndRead32(REG_CONF_POSTTRIGn+REG_CONF_Xn_STEP*str, val, clk, ms, sm, "HlSetPostTrig failed");
end procedure;
procedure HlSetMode( str : in integer;
val : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r) is
begin
axi_single_write(REG_CONF_MODEn+REG_CONF_Xn_STEP*str, val, ms, sm, clk);
end procedure;
procedure HlConfStream( str : in integer;
bufstart : in integer;
ringbuf : in boolean;
overwrite : in boolean;
wincnt : in integer;
winsize : in integer;
signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
variable v : integer := 0;
begin
AxiWriteAndRead32( REG_CTX_REGION+REG_CTX_BUFSTARTn+REG_CTX_Xn_STEP*str,
bufstart, clk, rqst, rsp, "HlConfStream failed BUFSTART");
AxiWriteAndRead32( REG_CTX_REGION+REG_CTX_WINSIZEn+REG_CTX_Xn_STEP*str,
winsize, clk, rqst, rsp, "HlConfStream failed WINSIZE");
if ringbuf then
v := v + VAL_SCFG_RINGBUF;
end if;
if overwrite then
v := v + VAL_SCFG_OVERWRITE;
end if;
v := v + (2**SFT_SCFG_WINCNT)*(wincnt-1);
AxiWriteAndRead32( REG_CTX_REGION+REG_CTX_SCFGn+REG_CTX_Xn_STEP*str,
v, clk, rqst, rsp, "HlConfStream failed SCFG");
end procedure;
procedure HlIsRecording( str : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out boolean) is
variable v : integer := 0;
begin
axi_single_read(REG_CONF_REGION+REG_CONF_MODEn+REG_CONF_Xn_STEP*str,
v, ms, sm, clk);
if IntAnd(v, VAL_MODE_RECORDING) /= 0 then
val := true;
else
val := false;
end if;
end procedure;
procedure HlGetPtr( str : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer) is
begin
axi_single_read(REG_CTX_REGION+REG_CTX_PTRn+REG_CTX_Xn_STEP*str,
val, ms, sm, clk);
end procedure;
procedure HlGetMaxLvl( str : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer) is
begin
axi_single_read(REG_CONF_REGION+REG_CONF_MAXLVLn+REG_CONF_Xn_STEP*str,
val, ms, sm, clk);
end procedure;
procedure HlGetLastWin( str : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer) is
begin
axi_single_read(REG_CONF_REGION+REG_CONF_LASTWINn+REG_CONF_Xn_STEP*str,
val, ms, sm, clk);
end procedure;
procedure HlGetCurWin( str : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer) is
variable v : integer;
begin
axi_single_read(REG_CTX_REGION+REG_CTX_SCFGn+REG_CTX_Xn_STEP*str,
v, ms, sm, clk);
v := IntAnd(v, MSK_SCFG_WINCUR);
v := v / (2**SFT_SCFG_WINCUR);
val := v;
end procedure;
procedure HlGetWinCnt( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer) is
variable v : integer;
begin
axi_single_read(REG_WIN_REGION+REG_WIN_WINCNT+REG_WIN_STRn_STEP*str+REG_WIN_WINn_STEP*win,
v, ms, sm, clk);
val := IntAnd(v, MSK_WIN_WINCNT_CNT);
end procedure;
procedure HlIsTrigWin( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out boolean) is
variable v : integer;
begin
axi_single_read(REG_WIN_REGION+REG_WIN_WINCNT+REG_WIN_STRn_STEP*str+REG_WIN_WINn_STEP*win,
v, ms, sm, clk);
val := v < 0;
end procedure;
procedure HlClrWinCnt( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r) is
variable v : integer;
begin
axi_single_write(REG_WIN_REGION+REG_WIN_WINCNT+REG_WIN_STRn_STEP*str+REG_WIN_WINn_STEP*win,
0, ms, sm, clk);
end procedure;
procedure HlGetWinLast( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer) is
variable v : integer;
begin
axi_single_read(REG_WIN_REGION+REG_WIN_WINLAST+REG_WIN_STRn_STEP*str+REG_WIN_WINn_STEP*win,
val, ms, sm, clk);
end procedure;
procedure HlGetTsLo( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer) is
variable v : integer;
begin
axi_single_read(REG_WIN_REGION+REG_WIN_TSLO+REG_WIN_STRn_STEP*str+REG_WIN_WINn_STEP*win,
val, ms, sm, clk);
end procedure;
procedure HlGetTsHi( str : in integer;
win : in integer;
signal clk : in std_logic;
signal ms : out axi_ms_r;
signal sm : in axi_sm_r;
val : out integer) is
variable v : integer;
begin
axi_single_read(REG_WIN_REGION+REG_WIN_TSHi+REG_WIN_STRn_STEP*str+REG_WIN_WINn_STEP*win,
val, ms, sm, clk);
end procedure;
end;

View File

@ -0,0 +1,249 @@
------------------------------------------------------------
-- Description
------------------------------------------------------------
-- Stream 0 works in ringbuffer mode (without overwrite). It
-- produces 8-bit data (modulo counter). IRQs are located at samples
-- containing data 30, 60 and 90. IRQs are suppressed until 15 us after
-- simulation to see if IRQ enable works correctly.
-- The IRQ handler also sets the window sample counter to zero to ensure
-- more data can be recorded after the IRQ.
------------------------------------------------------------
-- Libraries
------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_ms_daq_pkg.all;
library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.psi_ms_daq_axi_tb_pkg.all;
use work.psi_tb_axi_pkg.all;
------------------------------------------------------------
-- Package Header
------------------------------------------------------------
package psi_ms_daq_axi_tb_str0_pkg is
constant PrintStr0_c : boolean := PrintDefault_c;
-- Memory
constant Str0BufStart_c : integer := 16#1000#;
constant Str0WinSize_c : integer := 100;
constant Str0Windows_c : integer := 3;
alias Memory0 : t_aslv8(0 to Str0WinSize_c*Str0Windows_c) is Memory(Str0BufStart_c to Str0BufStart_c+Str0WinSize_c*Str0Windows_c);
--------------------------------------------------------
-- Persistent State
--------------------------------------------------------
shared variable Str0NextWin : integer := 0;
shared variable Str0WinCheck : integer := 0;
shared variable Str0LastTs : integer;
shared variable Str0IrqOn : boolean := false;
shared variable Str0Disabled : boolean := false;
--------------------------------------------------------
-- Data Generation
--------------------------------------------------------
procedure Str0Sample( signal clk : in std_logic;
signal vld : out std_logic;
signal trig : out std_logic;
signal data : out std_logic_vector(7 downto 0));
--------------------------------------------------------
-- IRQ Handler
--------------------------------------------------------
procedure Str0Handler( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
--------------------------------------------------------
-- Setup
--------------------------------------------------------
procedure Str0Setup( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
--------------------------------------------------------
-- Update
--------------------------------------------------------
procedure Str0Update( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
end package;
------------------------------------------------------------
-- Package Body
------------------------------------------------------------
package body psi_ms_daq_axi_tb_str0_pkg is
--------------------------------------------------------
-- Data Generation
--------------------------------------------------------
procedure Str0Sample( signal clk : in std_logic;
signal vld : out std_logic;
signal trig : out std_logic;
signal data : out std_logic_vector(7 downto 0)) is
begin
vld <= '1';
if (now > 15 us) and (to_integer(unsigned(data)) = 0) then
Str0IrqOn := true;
end if;
case to_integer(unsigned(data)) is
when 30 | 60 | 90 =>
if Str0IrqOn then
trig <= '1';
end if;
when others => null;
end case;
wait until rising_edge(clk);
vld <= '0';
trig <= '0';
data <= std_logic_vector(unsigned(data)+1);
wait until rising_edge(clk);
end procedure;
--------------------------------------------------------
-- IRQ Handler
--------------------------------------------------------
procedure Str0Handler( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
variable v : integer;
variable curwin : integer;
variable wincnt : integer;
variable winstart, winend : integer;
variable winlast : integer;
variable addr : integer;
variable tslo : integer;
variable firstLoop : boolean := true;
variable HasTrigger : boolean;
begin
print("------------ Stream 0 Handler ------------", PrintStr0_c);
HlGetMaxLvl(0, clk, rqst, rsp, v);
print("MAXLVL: " & to_string(v), PrintStr0_c);
HlGetCurWin(0, clk, rqst, rsp, curwin);
print("CURWIN: " & to_string(curwin), PrintStr0_c);
print("", PrintStr0_c);
if Str0Disabled then
print("Skipped, stream disabled", PrintStr0_c);
print("", PrintStr0_c);
else
HlIsTrigWin(0, Str0NextWin, clk, rqst, rsp, HasTrigger);
-- curwin = nextwin can occur if al lwindows are filled. In all cases we only interpret windows containing triggers.
while ((Str0NextWin /= curwin) or firstLoop) and HasTrigger loop
firstLoop := false;
print("*** Window " & to_string(Str0NextWin) & " / Number: " & to_string(Str0WinCheck) & " ***", PrintStr0_c);
HlGetWinCnt(0, Str0NextWin, clk, rqst, rsp, wincnt);
print("WINCNT: " & to_string(wincnt), PrintStr0_c);
HlClrWinCnt(0, Str0NextWin, clk, rqst, rsp);
HlGetWinLast(0, Str0NextWin, clk, rqst, rsp, winlast);
print("WINLAST: " & to_string(winlast), PrintStr0_c);
HlGetTsLo(0, Str0NextWin, clk, rqst, rsp, tslo);
print("WINTSLO: " & to_string(tslo), PrintStr0_c);
HlGetTsHi(0, Str0NextWin, clk, rqst, rsp, v);
print("WINTSHI: " & to_string(v), PrintStr0_c);
winstart := Str0BufStart_c + Str0NextWin*Str0WinSize_c;
winend := winstart + Str0WinSize_c - 1;
case Str0WinCheck is
when 0 =>
-- Windows full because dat received for quite some time
IntCompare(Str0WinSize_c, wincnt, "Stream0: WINCNT wrong");
-- Check Values
addr := winlast;
for i in 256+30+3-99 to 256+30+3 loop
if addr = winend then
addr := winstart;
else
addr := addr + 1;
end if;
StdlvCompareInt (i mod 256, Memory(addr), "Stream0: Wrong value at 0x" & to_hstring(to_unsigned(addr,32)), false);
end loop;
when 1 =>
-- Trigger following each other with 30 samples difference
IntCompare(30, wincnt, "Stream0: WINCNT wrong");
IntCompare(30*2, tslo-Str0LastTs, "Stream0: TS difference wrong");
-- Check Values
addr := winstart;
for i in 34 to 63 loop
StdlvCompareInt (i, Memory(addr), "Stream0: Wrong value", false);
addr := addr + 1; -- does never wrap
end loop;
when 2 =>
-- Trigger following each other with 30 samples difference
IntCompare(30, wincnt, "Stream0: WINCNT wrong");
IntCompare(30*2, tslo-Str0LastTs, "Stream0: TS difference wrong");
-- Check Values
addr := winstart;
for i in 64 to 93 loop
StdlvCompareInt (i, Memory(addr), "Stream0: Wrong value", false);
addr := addr + 1; -- does never wrap
end loop;
when 3 =>
-- Full buffer recorded after emptying first buffer
IntCompare(100, wincnt, "Stream0: WINCNT wrong");
IntCompare((256-2*30)*2, tslo-Str0LastTs, "Stream0: TS difference wrong");
-- Disable stream IRQ
AxiRead32(REG_CONF_IRQENA_ADDR, v, clk, rqst, rsp);
v := IntAnd(v, 16#0FE#);
AxiWrite32(REG_CONF_IRQENA_ADDR, v, clk, rqst, rsp);
AxiRead32(REG_CONF_STRENA_ADDR, v, clk, rqst, rsp);
v := IntAnd(v, 16#0FE#);
AxiWrite32(REG_CONF_STRENA_ADDR, v, clk, rqst, rsp);
Str0Disabled := true;
-- Check Values
addr := winlast + 1;
for i in 256+30+3-99 to 256+30+3 loop
StdlvCompareInt (i mod 256, Memory(addr), "Stream0: Wrong value", false);
if addr = winend then
addr := winstart;
else
addr := addr + 1;
end if;
end loop;
when others => null;
end case;
print("", PrintStr0_c);
Str0LastTs := tslo;
Str0NextWin := (Str0NextWin + 1) mod 3;
Str0WinCheck := Str0WinCheck + 1;
end loop;
end if;
end procedure;
--------------------------------------------------------
-- Setup
--------------------------------------------------------
procedure Str0Setup( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
begin
HlCheckMaxLvl(0, 0, clk, rqst, rsp);
HlSetPostTrig(0, 3, clk, rqst, rsp);
HlSetMode(0, VAL_MODE_RECM_CONT, clk, rqst, rsp);
HlConfStream( str => 0, bufstart => Str0BufStart_c, ringbuf => true, overwrite => false, wincnt => Str0Windows_c, winsize => Str0WinSize_c,
clk => clk, rqst => rqst, rsp => rsp);
end procedure;
--------------------------------------------------------
-- Update
--------------------------------------------------------
procedure Str0Update( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
begin
end;
end;

View File

@ -0,0 +1,172 @@
------------------------------------------------------------
-- Description
------------------------------------------------------------
-- Stream 1 works in manual recording mode. The data is arriving
-- in bursts (samples back-to-back withing bursts) and does
-- not contain any trigger events.
------------------------------------------------------------
-- Libraries
------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_ms_daq_pkg.all;
library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.psi_ms_daq_axi_tb_pkg.all;
use work.psi_tb_axi_pkg.all;
------------------------------------------------------------
-- Package Header
------------------------------------------------------------
package psi_ms_daq_axi_tb_str1_pkg is
constant PrintStr1_c : boolean := PrintDefault_c;
-- Memory
constant Str1BufStart_c : integer := 16#2000#;
constant Str1WinSize_c : integer := 500;
constant Str1Windows_c : integer := 1;
alias Memory1 : t_aslv8(0 to Str1WinSize_c*Str1Windows_c) is Memory(Str1BufStart_c to Str1BufStart_c+Str1WinSize_c*Str1Windows_c);
--------------------------------------------------------
-- Persistent State
--------------------------------------------------------
shared variable Str1WinCheck : integer := 0;
shared variable Str1DataCnt : integer := 0;
--------------------------------------------------------
-- Data Generation
--------------------------------------------------------
procedure Str1Data( signal clk : in std_logic;
signal vld : out std_logic;
signal trig : out std_logic;
signal data : out std_logic_vector(15 downto 0));
--------------------------------------------------------
-- IRQ Handler
--------------------------------------------------------
procedure Str1Handler( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
--------------------------------------------------------
-- Setup
--------------------------------------------------------
procedure Str1Setup( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
--------------------------------------------------------
-- Update
--------------------------------------------------------
procedure Str1Update( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
end package;
------------------------------------------------------------
-- Package Body
------------------------------------------------------------
package body psi_ms_daq_axi_tb_str1_pkg is
--------------------------------------------------------
-- Data Generation
--------------------------------------------------------
procedure Str1Data( signal clk : in std_logic;
signal vld : out std_logic;
signal trig : out std_logic;
signal data : out std_logic_vector(15 downto 0)) is
begin
while now < 10 us loop
wait until rising_edge(clk);
end loop;
for i in 0 to 19 loop
vld <= '1';
for k in 0 to 49 loop
data <= std_logic_vector(to_unsigned(Str1DataCnt, 16));
Str1DataCnt := Str1DataCnt + 1;
wait until rising_edge(clk);
end loop;
vld <= '0';
wait for 1 us;
wait until rising_edge(clk);
end loop;
end procedure;
--------------------------------------------------------
-- IRQ Handler
--------------------------------------------------------
procedure Str1Handler( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
variable v : integer;
variable curwin : integer;
variable wincnt : integer;
variable winlast : integer;
variable valRead : unsigned(15 downto 0);
begin
print("------------ Stream 1 Handler ------------", PrintStr1_c);
HlGetMaxLvl(1, clk, rqst, rsp, v);
print("MAXLVL: " & to_string(v), PrintStr1_c);
HlGetPtr(1, clk, rqst, rsp, v);
print("PTR: " & to_string(v), PrintStr1_c);
HlGetCurWin(1, clk, rqst, rsp, curwin);
print("CURWIN: " & to_string(curwin), PrintStr1_c);
IntCompare(0, curwin, "Stream1: CURWIN wrong");
-- Check window content
HlGetWinCnt(1, 0, clk, rqst, rsp, wincnt);
print("WINCNT: " & to_string(wincnt), PrintStr1_c);
IntCompare(250, wincnt, "Stream1:WINCNT wrong");
HlGetWinLast(1, 0, clk, rqst, rsp, winlast);
print("WINLAST: " & to_string(winlast), PrintStr1_c);
IntCompare(16#2000#+498, winlast, "Stream1:WINLAST wrong");
for spl in 0 to 249 loop
valRead(7 downto 0) := unsigned(Memory1(spl*2));
valRead(15 downto 8) := unsigned(Memory1(spl*2+1));
-- first 100 samples are before arming
StdlvCompareInt (spl+100, std_logic_vector(valRead), "Stream1:Wrong value", false);
end loop;
print("", PrintStr1_c);
Str1WinCheck := Str1WinCheck + 1;
end procedure;
--------------------------------------------------------
-- Setup
--------------------------------------------------------
procedure Str1Setup( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
begin
HlCheckMaxLvl(1, 0, clk, rqst, rsp);
HlSetPostTrig(1, 250, clk, rqst, rsp);
HlSetMode(1, VAL_MODE_RECM_MANUAL, clk, rqst, rsp);
HlConfStream( str => 1, bufstart => Str1BufStart_c, ringbuf => false, overwrite => false, wincnt => Str1Windows_c, winsize => Str1WinSize_c,
clk => clk, rqst => rqst, rsp => rsp);
end procedure;
--------------------------------------------------------
-- Update
--------------------------------------------------------
procedure Str1Update( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
variable Stream1Armed_v : boolean := false;
begin
-- ARM recorder at required point in time
if Str1DataCnt = 99 and not Stream1Armed_v then
Stream1Armed_v := true;
HlSetMode(1, VAL_MODE_RECM_MANUAL + VAL_MODE_ARM, clk, rqst, rsp);
end if;
end;
end;

View File

@ -0,0 +1,209 @@
------------------------------------------------------------
-- Description
------------------------------------------------------------
-- Stream 2 works in siingle recording mode. The data is arriving
-- in bursts (samples back-to-back withing bursts) and does
-- contain trigger events at the really begining (sample 0).
------------------------------------------------------------
-- Libraries
------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_ms_daq_pkg.all;
library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.psi_ms_daq_axi_tb_pkg.all;
use work.psi_tb_axi_pkg.all;
------------------------------------------------------------
-- Package Header
------------------------------------------------------------
package psi_ms_daq_axi_tb_str2_pkg is
constant PrintStr2_c : boolean := PrintDefault_c;
-- Memory
constant Str2BufStart_c : integer := 16#3000#;
constant Str2WinSize_c : integer := 256;
constant Str2Windows_c : integer := 3;
constant Str2PostTrig_c : integer := 127;
alias Memory2 : t_aslv8(0 to Str2WinSize_c*Str2Windows_c) is Memory(Str2BufStart_c to Str2BufStart_c+Str2WinSize_c*Str2Windows_c);
--------------------------------------------------------
-- Persistent State
--------------------------------------------------------
shared variable Str2FrameCnt : integer := 0;
shared variable Str2SplCnt : integer := 0;
shared variable Str2WinCheck : integer := 0;
shared variable Str2ExpFrame : integer := 0;
shared variable Stream2Armed_v : boolean := false;
--------------------------------------------------------
-- Data Generation
--------------------------------------------------------
procedure Str2Data( signal clk : in std_logic;
signal vld : out std_logic;
signal trig : out std_logic;
signal data : out std_logic_vector(15 downto 0));
--------------------------------------------------------
-- IRQ Handler
--------------------------------------------------------
procedure Str2Handler( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
--------------------------------------------------------
-- Setup
--------------------------------------------------------
procedure Str2Setup( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
--------------------------------------------------------
-- Update
--------------------------------------------------------
procedure Str2Update( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
end package;
------------------------------------------------------------
-- Package Body
------------------------------------------------------------
package body psi_ms_daq_axi_tb_str2_pkg is
--------------------------------------------------------
-- Data Generation
--------------------------------------------------------
procedure Str2Data( signal clk : in std_logic;
signal vld : out std_logic;
signal trig : out std_logic;
signal data : out std_logic_vector(15 downto 0)) is
begin
while now < 8.5 us loop
wait until rising_edge(clk);
end loop;
for i in 0 to 19 loop
vld <= '1';
Str2SplCnt := 0;
trig <= '1';
for k in 0 to 199 loop
data <= std_logic_vector(to_unsigned(Str2FrameCnt*256+Str2SplCnt, 16));
Str2SplCnt := Str2SplCnt + 1;
wait until rising_edge(clk);
trig <= '0';
end loop;
Str2FrameCnt := Str2FrameCnt + 1;
vld <= '0';
wait for 1 us;
wait until rising_edge(clk);
end loop;
end procedure;
--------------------------------------------------------
-- IRQ Handler
--------------------------------------------------------
procedure Str2Handler( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
variable v : integer;
variable curwin : integer;
variable lastwin : integer;
variable wincnt : integer;
variable spladdr : integer;
variable splNr : integer;
variable valRead : unsigned(15 downto 0);
variable splInWin : integer;
variable isTrig : boolean;
begin
print("------------ Stream 2 Handler ------------", PrintStr2_c);
HlGetMaxLvl(2, clk, rqst, rsp, v);
print("MAXLVL: " & to_string(v), PrintStr2_c);
HlGetPtr(2, clk, rqst, rsp, v);
print("PTR: " & to_string(v), PrintStr2_c);
HlGetCurWin(2, clk, rqst, rsp, curwin);
print("CURWIN: " & to_string(curwin), PrintStr2_c);
-- Calculate window to read
if curwin = 0 then
curwin := Str2Windows_c-1;
else
curwin := curwin-1;
end if;
-- Read window data
-- Check if recording is finished
HlIsTrigWin(2, curwin, clk, rqst, rsp, isTrig);
-- Check if window is fully written to memory
HlGetLastWin(2, clk, rqst, rsp, lastwin);
-- Execute
if not isTrig then
print("Skipped: not a trigger window", PrintStr2_c);
elsif curwin /= lastwin then
print("Skipped: not written to memory yet " & str(curwin) & " " & str(lastwin), PrintStr2_c);
else
-- Check Data (last 128 samples)
splNr := Str2PostTrig_c;
while splNr >= 0 loop
print("check window " & to_string(curwin), PrintStr2_c);
HlGetWinLast(2, curwin, clk, rqst, rsp, spladdr);
print("WINLAST: " & to_string(spladdr), PrintStr2_c);
while (splNr >= 0) and (spladdr >= Str2BufStart_c+curwin*Str2WinSize_c) loop
StdlvCompareInt(splNr, Memory(spladdr), "Stream2: Sample " & to_string(Str2ExpFrame) & ":" & to_string(splNr) & " wrong CNT [addr=" & str(spladdr) & "]", false);
StdlvCompareInt(Str2ExpFrame, Memory(spladdr+1), "Stream2: Sample " & to_string(Str2ExpFrame) & ":" & to_string(splNr) & " wrong FRAME [addr=" & str(spladdr) & "]", false);
spladdr := spladdr - 2;
splNr := splNr - 1;
end loop;
-- Next Window
if curwin = 0 then
curwin := Str2Windows_c-1;
else
curwin := curwin-1;
end if;
end loop;
Str2WinCheck := Str2WinCheck + 1;
end if;
print("", PrintStr2_c);
end procedure;
--------------------------------------------------------
-- Setup
--------------------------------------------------------
procedure Str2Setup( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
begin
HlCheckMaxLvl(2, 0, clk, rqst, rsp);
HlSetPostTrig(2, Str2PostTrig_c, clk, rqst, rsp);
HlSetMode(2, VAL_MODE_RECM_SINGLE, clk, rqst, rsp);
HlConfStream( str => 2, bufstart => Str2BufStart_c, ringbuf => false, overwrite => true, wincnt => Str2Windows_c, winsize => Str2WinSize_c,
clk => clk, rqst => rqst, rsp => rsp);
end procedure;
--------------------------------------------------------
-- Update
--------------------------------------------------------
procedure Str2Update( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
begin
-- ARM Stream 2 after 3 bursts
if ((Str2FrameCnt = 2) or (Str2FrameCnt = 12)) and
(Str2SplCnt >= 80) and (Str2SplCnt <= 150) and not Stream2Armed_v then
Stream2Armed_v := true;
HlSetMode(2, VAL_MODE_RECM_SINGLE + VAL_MODE_ARM, clk, rqst, rsp);
Str2ExpFrame := Str2FrameCnt + 1;
elsif Str2FrameCnt = 11 then
Stream2Armed_v := false;
end if;
end;
end;

View File

@ -0,0 +1,214 @@
------------------------------------------------------------
-- Description
------------------------------------------------------------
------------------------------------------------------------
-- Libraries
------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_ms_daq_pkg.all;
library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.psi_ms_daq_axi_tb_pkg.all;
use work.psi_tb_axi_pkg.all;
------------------------------------------------------------
-- Package Header
------------------------------------------------------------
package psi_ms_daq_axi_tb_str3_pkg is
constant PrintStr3_c : boolean := PrintDefault_c;
-- Memory
constant Str3BufStart_c : integer := 16#4000#;
constant Str3WinSize_c : integer := 1024;
constant Str3Windows_c : integer := 3;
constant Str3PostTrig_c : integer := 9;
constant Str3TrigPos_c : integer := 100;
alias Memory3 : t_aslv8(0 to Str3WinSize_c*Str3Windows_c) is Memory(Str3BufStart_c to Str3BufStart_c+Str3WinSize_c*Str3Windows_c);
--------------------------------------------------------
-- Persistent State
--------------------------------------------------------
shared variable Str3ExpFrame : integer := 0;
shared variable Str3FrameCnt : integer := 0;
shared variable Str3SplCnt : integer := 0;
shared variable Str3WinCheck : integer := 0;
shared variable Stream3Armed_v : boolean := false;
--------------------------------------------------------
-- Data Generation
--------------------------------------------------------
procedure Str3Data( signal clk : in std_logic;
signal vld : out std_logic;
signal trig : out std_logic;
signal data : out std_logic_vector(31 downto 0));
--------------------------------------------------------
-- IRQ Handler
--------------------------------------------------------
procedure Str3Handler( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
--------------------------------------------------------
-- Setup
--------------------------------------------------------
procedure Str3Setup( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
--------------------------------------------------------
-- Update
--------------------------------------------------------
procedure Str3Update( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r);
end package;
------------------------------------------------------------
-- Package Body
------------------------------------------------------------
package body psi_ms_daq_axi_tb_str3_pkg is
--------------------------------------------------------
-- Data Generation
--------------------------------------------------------
procedure Str3Data( signal clk : in std_logic;
signal vld : out std_logic;
signal trig : out std_logic;
signal data : out std_logic_vector(31 downto 0)) is
begin
while now < 8 us loop
wait until rising_edge(clk);
end loop;
for i in 0 to 9 loop
vld <= '1';
Str3SplCnt := 0;
for k in 0 to 999 loop
data <= std_logic_vector(to_unsigned(Str3FrameCnt*2**16+Str3SplCnt, 32));
if Str3SplCnt = Str3TrigPos_c then
trig <= '1';
else
trig <= '0';
end if;
Str3SplCnt := Str3SplCnt + 1;
wait until rising_edge(clk);
end loop;
Str3FrameCnt := Str3FrameCnt + 1;
vld <= '0';
wait for 1 us;
wait until rising_edge(clk);
end loop;
end procedure;
--------------------------------------------------------
-- IRQ Handler
--------------------------------------------------------
procedure Str3Handler( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
variable v : integer;
variable curwin : integer;
variable wincnt : integer;
variable winlast : integer;
variable spladdr : integer;
variable splNr : integer;
variable valRead : unsigned(15 downto 0);
variable splInWin : integer;
variable isRecording : boolean;
begin
print("------------ Stream 3 Handler ------------", PrintStr3_c);
HlGetMaxLvl(3, clk, rqst, rsp, v);
print("MAXLVL: " & to_string(v), PrintStr3_c);
HlGetPtr(3, clk, rqst, rsp, v);
print("PTR: " & to_string(v), PrintStr3_c);
HlGetCurWin(3, clk, rqst, rsp, curwin);
print("CURWIN: " & to_string(curwin), PrintStr3_c);
-- Calculate window to read
if curwin = 0 then
curwin := Str3Windows_c-1;
else
curwin := curwin-1;
end if;
-- Check Data from this frame
splNr := Str3TrigPos_c+Str3PostTrig_c;
-- Read window data (Post-Trigger, from this window)
print("check post-trigger", PrintStr3_c);
HlGetWinLast(3, curwin, clk, rqst, rsp, winlast);
print("WINLAST: " & to_string(winlast), PrintStr3_c);
spladdr := winlast;
while splNr >= 0 loop
StdlvCompareInt(splNr, Memory(spladdr+1) & Memory(spladdr), "Stream3: Sample " & to_string(Str3ExpFrame) & ":" & to_string(splNr) & " wrong CNT", false);
StdlvCompareInt(Str3ExpFrame, Memory(spladdr+3) & Memory(spladdr+2), "Stream3: Sample " & to_string(Str3ExpFrame) & ":" & to_string(splNr) & " wrong FRAME", false);
-- Wraparound
if spladdr = Str3BufStart_c+curwin*Str3WinSize_c then
spladdr := Str3BufStart_c+(curwin+1)*Str3WinSize_c-4;
-- Normal Counting
else
spladdr := spladdr - 4;
end if;
splNr := splNr - 1;
end loop;
-- Read window data (Pre-Trigger, from last window)
print("check pre-trigger", PrintStr3_c);
splNr := 999;
while spladdr /= winlast loop
StdlvCompareInt(splNr, Memory(spladdr+1) & Memory(spladdr), "Stream3: Sample " & to_string(Str3ExpFrame-1) & ":" & to_string(splNr) & " wrong CNT", false);
StdlvCompareInt(Str3ExpFrame-1, Memory(spladdr+3) & Memory(spladdr+2), "Stream3: Sample " & to_string(Str3ExpFrame-1) & ":" & to_string(splNr) & " wrong FRAME", false);
-- Wraparound
if spladdr = Str3BufStart_c+curwin*Str3WinSize_c then
spladdr := Str3BufStart_c+(curwin+1)*Str3WinSize_c-4;
-- Normal Counting
else
spladdr := spladdr - 4;
end if;
splNr := splNr - 1;
end loop;
Str3WinCheck := Str3WinCheck + 1;
print("", PrintStr3_c);
end procedure;
--------------------------------------------------------
-- Setup
--------------------------------------------------------
procedure Str3Setup( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
begin
HlCheckMaxLvl(3, 0, clk, rqst, rsp);
HlSetPostTrig(3, Str3PostTrig_c, clk, rqst, rsp);
HlSetMode(3, VAL_MODE_RECM_TRIGMASK, clk, rqst, rsp);
HlConfStream( str => 3, bufstart => Str3BufStart_c, ringbuf => true, overwrite => true, wincnt => Str3Windows_c, winsize => Str3WinSize_c,
clk => clk, rqst => rqst, rsp => rsp);
end procedure;
--------------------------------------------------------
-- Update
--------------------------------------------------------
procedure Str3Update( signal clk : in std_logic;
signal rqst : out axi_ms_r;
signal rsp : in axi_sm_r) is
begin
if ((Str3FrameCnt = 2) or (Str3FrameCnt = 7))
and not Stream3Armed_v then
HlSetMode(3, VAL_MODE_RECM_TRIGMASK + VAL_MODE_ARM, clk, rqst, rsp);
Stream3Armed_v := true;
Str3ExpFrame := Str3FrameCnt;
elsif Str3FrameCnt = 6 then
Stream3Armed_v := false;
end if;
end procedure;
end;

View File

@ -86,6 +86,7 @@ architecture sim of psi_ms_daq_daq_sm_tb is
signal CtxStr_Resp : FromCtx_t := (others => (others => '0'));
signal CtxWin_Cmd : ToCtxWin_t;
signal CtxWin_Resp : FromCtx_t := (others => (others => '0'));
signal StrLastWin : WinType_a(Streams_g-1 downto 0) := (others => (others => '0'));
begin
------------------------------------------------------------
@ -106,6 +107,7 @@ begin
GlbEna => GlbEna,
StrEna => StrEna,
StrIrq => StrIrq,
StrLastWin => StrLastWin,
Inp_HasLast => Inp_HasLast,
Inp_Level => Inp_Level,
Ts_Vld => Ts_Vld,
@ -276,43 +278,43 @@ begin
-- single_simple
wait until NextCase = 0;
ProcessDone(TbProcNr_dma_resp_c) <= '0';
work.psi_ms_daq_daq_sm_tb_case_single_simple.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, Generics_c);
work.psi_ms_daq_daq_sm_tb_case_single_simple.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, StrLastWin, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_dma_resp_c) <= '1';
-- priorities
wait until NextCase = 1;
ProcessDone(TbProcNr_dma_resp_c) <= '0';
work.psi_ms_daq_daq_sm_tb_case_priorities.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, Generics_c);
work.psi_ms_daq_daq_sm_tb_case_priorities.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, StrLastWin, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_dma_resp_c) <= '1';
-- single_window
wait until NextCase = 2;
ProcessDone(TbProcNr_dma_resp_c) <= '0';
work.psi_ms_daq_daq_sm_tb_case_single_window.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, Generics_c);
work.psi_ms_daq_daq_sm_tb_case_single_window.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, StrLastWin, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_dma_resp_c) <= '1';
-- multi_window
wait until NextCase = 3;
ProcessDone(TbProcNr_dma_resp_c) <= '0';
work.psi_ms_daq_daq_sm_tb_case_multi_window.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, Generics_c);
work.psi_ms_daq_daq_sm_tb_case_multi_window.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, StrLastWin, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_dma_resp_c) <= '1';
-- enable
wait until NextCase = 4;
ProcessDone(TbProcNr_dma_resp_c) <= '0';
work.psi_ms_daq_daq_sm_tb_case_enable.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, Generics_c);
work.psi_ms_daq_daq_sm_tb_case_enable.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, StrLastWin, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_dma_resp_c) <= '1';
-- irq
wait until NextCase = 5;
ProcessDone(TbProcNr_dma_resp_c) <= '0';
work.psi_ms_daq_daq_sm_tb_case_irq.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, Generics_c);
work.psi_ms_daq_daq_sm_tb_case_irq.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, StrLastWin, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_dma_resp_c) <= '1';
-- timestamp
wait until NextCase = 6;
ProcessDone(TbProcNr_dma_resp_c) <= '0';
work.psi_ms_daq_daq_sm_tb_case_timestamp.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, Generics_c);
work.psi_ms_daq_daq_sm_tb_case_timestamp.dma_resp(Clk, StrIrq, Dma_Resp, Dma_Resp_Vld, Dma_Resp_Rdy, TfDone, StrLastWin, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_dma_resp_c) <= '1';
wait;

View File

@ -52,6 +52,7 @@ package psi_ms_daq_daq_sm_tb_case_enable is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t);
procedure ctx (
@ -299,6 +300,7 @@ package body psi_ms_daq_daq_sm_tb_case_enable is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t) is
begin
-- Disabled stream does not react (global)

View File

@ -53,6 +53,7 @@ package psi_ms_daq_daq_sm_tb_case_irq is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t);
procedure ctx (
@ -159,7 +160,7 @@ package body psi_ms_daq_daq_sm_tb_case_irq is
wait until rising_edge(Clk) and Dma_Cmd_Vld = '1';
wait until rising_edge(Clk) and Dma_Cmd_Vld = '1';
Inp_Level(0) <= (others => '0');
ControlWaitCompl(Clk);
ControlWaitCompl(Clk);
end procedure;
@ -232,6 +233,7 @@ package body psi_ms_daq_daq_sm_tb_case_irq is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t) is
begin
-- Normal Order
@ -242,7 +244,7 @@ package body psi_ms_daq_daq_sm_tb_case_irq is
StdlvCompareStdlv ("0000", StrIrq, "IRQs asserted unexpectedly");
assert StrIrq'last_event > 200 ns report "###ERROR###: IRQs not idle" severity error;
AssertTfDone(Clk, TfDone);
CheckIrq(MaxWait => (1 us), Stream => 0, Clk => Clk, StrIrq => StrIrq);
CheckIrq(MaxWait => (1 us), Stream => 0, LastWin => 0, Clk => Clk, StrIrq => StrIrq, StrLastWin => StrLastWin);
ProcDone(1) := '1';
-- Flipped Order
@ -253,7 +255,7 @@ package body psi_ms_daq_daq_sm_tb_case_irq is
assert StrIrq'last_event > 200 ns report "###ERROR###: IRQs not idle" severity error;
ApplyDmaRespAuto( Stream => 0, Trigger => '1',
Clk => Clk, Dma_Resp => Dma_Resp, Dma_Resp_Vld => Dma_Resp_Vld, Dma_Resp_Rdy => Dma_Resp_Rdy);
CheckIrq(MaxWait => (1 us), Stream => 0, Clk => Clk, StrIrq => StrIrq);
CheckIrq(MaxWait => (1 us), Stream => 0, LastWin => 0, Clk => Clk, StrIrq => StrIrq, StrLastWin => StrLastWin);
ProcDone(1) := '1';
-- IRQ FIFO full
@ -268,13 +270,13 @@ package body psi_ms_daq_daq_sm_tb_case_irq is
-- Send IRQs
for i in 0 to 11 loop
AssertTfDone(Clk, TfDone);
CheckIrq(MaxWait => (1 us), Stream => 0, Clk => Clk, StrIrq => StrIrq);
CheckIrq(MaxWait => (1 us), Stream => 0, LastWin => i mod 3, Clk => Clk, StrIrq => StrIrq, StrLastWin => StrLastWin);
end loop;
-- Last transfer
ApplyDmaRespAuto( Stream => 0, Trigger => '1',
Clk => Clk, Dma_Resp => Dma_Resp, Dma_Resp_Vld => Dma_Resp_Vld, Dma_Resp_Rdy => Dma_Resp_Rdy);
AssertTfDone(Clk, TfDone);
CheckIrq(MaxWait => (1 us), Stream => 0, Clk => Clk, StrIrq => StrIrq);
CheckIrq(MaxWait => (1 us), Stream => 0, LastWin => 0, Clk => Clk, StrIrq => StrIrq, StrLastWin => StrLastWin);
ProcDone(1) := '1';
-- Multi-Stream
@ -285,7 +287,7 @@ package body psi_ms_daq_daq_sm_tb_case_irq is
end loop;
for i in 3 downto 0 loop
AssertTfDone(Clk, TfDone);
CheckIrq(MaxWait => (1 us), Stream => i, Clk => Clk, StrIrq => StrIrq);
CheckIrq(MaxWait => (1 us), Stream => i, LastWin => 0, Clk => Clk, StrIrq => StrIrq, StrLastWin => StrLastWin);
end loop;
ProcDone(1) := '1';
@ -300,7 +302,7 @@ package body psi_ms_daq_daq_sm_tb_case_irq is
ApplyDmaRespAuto( Stream => 0, Trigger => '0',
Clk => Clk, Dma_Resp => Dma_Resp, Dma_Resp_Vld => Dma_Resp_Vld, Dma_Resp_Rdy => Dma_Resp_Rdy);
AssertTfDone(Clk, TfDone);
CheckIrq(MaxWait => (1 us), Stream => 0, Clk => Clk, StrIrq => StrIrq);
CheckIrq(MaxWait => (1 us), Stream => 0, LastWin => 0, Clk => Clk, StrIrq => StrIrq, StrLastWin => StrLastWin);
wait for 100 ns;
ApplyDmaRespAuto( Stream => 0, Trigger => '0',
Clk => Clk, Dma_Resp => Dma_Resp, Dma_Resp_Vld => Dma_Resp_Vld, Dma_Resp_Rdy => Dma_Resp_Rdy);

View File

@ -51,6 +51,7 @@ package psi_ms_daq_daq_sm_tb_case_multi_window is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t);
procedure ctx (
@ -255,6 +256,7 @@ package body psi_ms_daq_daq_sm_tb_case_multi_window is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t) is
begin
-- Linear write with Overwrite

View File

@ -52,6 +52,7 @@ package psi_ms_daq_daq_sm_tb_case_priorities is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t);
procedure ctx (
@ -183,6 +184,7 @@ package body psi_ms_daq_daq_sm_tb_case_priorities is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t) is
variable Stream_v : integer;
begin

View File

@ -51,6 +51,7 @@ package psi_ms_daq_daq_sm_tb_case_single_simple is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t);
procedure ctx (
@ -281,6 +282,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t) is
variable StartTime_v : time;
begin

View File

@ -51,6 +51,7 @@ package psi_ms_daq_daq_sm_tb_case_single_window is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t);
procedure ctx (
@ -236,6 +237,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_window is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t) is
begin
-- Linear write with Overwrite

View File

@ -53,6 +53,7 @@ package psi_ms_daq_daq_sm_tb_case_timestamp is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t);
procedure ctx (
@ -167,6 +168,7 @@ package body psi_ms_daq_daq_sm_tb_case_timestamp is
signal Dma_Resp_Vld : inout std_logic;
signal Dma_Resp_Rdy : in std_logic;
signal TfDone : inout std_logic;
signal StrLastWin : in WinType_a(Streams_g-1 downto 0);
constant Generics_c : Generics_t) is
begin
-- Timestamp handling

View File

@ -170,9 +170,11 @@ package psi_ms_daq_daq_sm_tb_pkg is
procedure CheckIrq( MaxWait : in time := 1 us; -- Maximum time to wait for the IRQ
Stream : in integer;
LastWin : in integer;
Msg : in string := "";
signal Clk : in std_logic;
signal StrIrq : in std_logic_vector(3 downto 0));
signal StrIrq : in std_logic_vector(3 downto 0);
signal StrLastWin : in WinType_a(3 downto 0));
------------------------------------------------------------
-- High Level (Auto) Functions
@ -642,9 +644,11 @@ package body psi_ms_daq_daq_sm_tb_pkg is
procedure CheckIrq( MaxWait : in time := 1 us; -- Maximum time to wait for the IRQ
Stream : in integer;
LastWin : in integer;
Msg : in string := "";
signal Clk : in std_logic;
signal StrIrq : in std_logic_vector(3 downto 0)) is
signal StrIrq : in std_logic_vector(3 downto 0);
signal StrLastWin : in WinType_a(3 downto 0)) is
variable IrqMask_v : std_logic_vector(StrIrq'range);
variable IdleTimePrior_v : time;
variable ProcStartTime_v : time;
@ -654,6 +658,7 @@ package body psi_ms_daq_daq_sm_tb_pkg is
IrqMask_v(Stream) := '1';
wait until rising_edge(Clk);
wait until (StrIrq = IrqMask_v) and rising_edge(Clk) for MaxWait;
StdlvCompareInt (LastWin, StrLastWin(Stream), "Received wrong LastWin with IRQ - " & Msg);
StdlvCompareStdlv (IrqMask_v, StrIrq, "IRQ was not asserted - " & Msg);
wait until rising_edge(Clk);
StdlvCompareInt (0, StrIrq, "IRQ was not deasserted - " & Msg);

View File

@ -73,10 +73,10 @@ architecture sim of psi_ms_daq_input_tb is
signal Str_Data : std_logic_vector(StreamWidth_g-1 downto 0) := (others => '0');
signal Str_Trig : std_logic := '0';
signal Str_Ts : std_logic_vector(63 downto 0) := (others => '0');
signal ClkTmem : std_logic := '1';
signal RstTmem : std_logic := '1';
signal ClkSmem : std_logic := '1';
signal RstSmem : std_logic := '1';
signal ClkReg : std_logic := '1';
signal RstReg : std_logic := '1';
signal ClkMem : std_logic := '1';
signal RstMem : std_logic := '1';
signal PostTrigSpls : std_logic_vector(31 downto 0) := (others => '0');
signal Mode : RecMode_t := (others => '0');
signal Arm : std_logic := '0';
@ -110,14 +110,14 @@ begin
Str_Data => Str_Data,
Str_Trig => Str_Trig,
Str_Ts => Str_Ts,
ClkTmem => ClkTmem,
RstTmem => RstTmem,
ClkReg => ClkReg,
RstReg => RstReg,
PostTrigSpls => PostTrigSpls,
Mode => Mode,
Arm => Arm,
IsArmed => IsArmed,
ClkSmem => ClkSmem,
RstSmem => RstSmem,
ClkMem => ClkMem,
RstMem => RstMem,
Daq_Vld => Daq_Vld,
Daq_Rdy => Daq_Rdy,
Daq_Data => Daq_Data,
@ -133,7 +133,7 @@ begin
------------------------------------------------------------
p_tb_control : process
begin
wait until RstTmem = '0' and RstSmem = '0';
wait until RstReg = '0' and RstMem = '0';
-- single_frame
NextCase <= 0;
wait until ProcessDone = AllProcessesDone_c;
@ -175,22 +175,22 @@ begin
wait;
end process;
p_clock_ClkSmem : process
p_clock_ClkMem : process
constant Frequency_c : real := real(200e6);
begin
while TbRunning loop
wait for 0.5*(1 sec)/Frequency_c;
ClkSmem <= not ClkSmem;
ClkMem <= not ClkMem;
end loop;
wait;
end process;
p_clock_ClkTmem : process
p_clock_ClkReg : process
constant Frequency_c : real := real(166e6);
begin
while TbRunning loop
wait for 0.5*(1 sec)/Frequency_c;
ClkTmem <= not ClkTmem;
ClkReg <= not ClkReg;
end loop;
wait;
end process;
@ -203,12 +203,12 @@ begin
begin
wait for 1 us;
-- Wait for two clk edges to ensure reset is active for at least one edge
wait until rising_edge(ClkSmem);
wait until rising_edge(ClkSmem);
RstSmem <= '0';
wait until rising_edge(ClkTmem);
wait until rising_edge(ClkTmem);
RstTmem <= '0';
wait until rising_edge(ClkMem);
wait until rising_edge(ClkMem);
RstMem <= '0';
wait until rising_edge(ClkReg);
wait until rising_edge(ClkReg);
RstReg <= '0';
wait;
end process;
@ -222,49 +222,49 @@ begin
-- single_frame
wait until NextCase = 0;
ProcessDone(TbProcNr_stream_c) <= '0';
work.psi_ms_daq_input_tb_case_single_frame.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkTmem, Arm, IsArmed, Generics_c);
work.psi_ms_daq_input_tb_case_single_frame.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkReg, Arm, IsArmed, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_stream_c) <= '1';
-- multi_frame
wait until NextCase = 1;
ProcessDone(TbProcNr_stream_c) <= '0';
work.psi_ms_daq_input_tb_case_multi_frame.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkTmem, Arm, IsArmed, Generics_c);
work.psi_ms_daq_input_tb_case_multi_frame.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkReg, Arm, IsArmed, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_stream_c) <= '1';
-- timeout
wait until NextCase = 2;
ProcessDone(TbProcNr_stream_c) <= '0';
work.psi_ms_daq_input_tb_case_timeout.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkTmem, Arm, IsArmed, Generics_c);
work.psi_ms_daq_input_tb_case_timeout.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkReg, Arm, IsArmed, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_stream_c) <= '1';
-- ts_overflow
wait until NextCase = 3;
ProcessDone(TbProcNr_stream_c) <= '0';
work.psi_ms_daq_input_tb_case_ts_overflow.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkTmem, Arm, IsArmed, Generics_c);
work.psi_ms_daq_input_tb_case_ts_overflow.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkReg, Arm, IsArmed, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_stream_c) <= '1';
-- trig_in_posttrig
wait until NextCase = 4;
ProcessDone(TbProcNr_stream_c) <= '0';
work.psi_ms_daq_input_tb_case_trig_in_posttrig.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkTmem, Arm, IsArmed, Generics_c);
work.psi_ms_daq_input_tb_case_trig_in_posttrig.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkReg, Arm, IsArmed, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_stream_c) <= '1';
-- always_trig
wait until NextCase = 5;
ProcessDone(TbProcNr_stream_c) <= '0';
work.psi_ms_daq_input_tb_case_always_trig.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkTmem, Arm, IsArmed, Generics_c);
work.psi_ms_daq_input_tb_case_always_trig.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkReg, Arm, IsArmed, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_stream_c) <= '1';
-- backpressure
wait until NextCase = 6;
ProcessDone(TbProcNr_stream_c) <= '0';
work.psi_ms_daq_input_tb_case_backpressure.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkTmem, Arm, IsArmed, Generics_c);
work.psi_ms_daq_input_tb_case_backpressure.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkReg, Arm, IsArmed, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_stream_c) <= '1';
-- modes
wait until NextCase = 7;
ProcessDone(TbProcNr_stream_c) <= '0';
work.psi_ms_daq_input_tb_case_modes.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkTmem, Arm, IsArmed, Generics_c);
work.psi_ms_daq_input_tb_case_modes.stream(Str_Clk, Str_Vld, Str_Rdy, Str_Data, Str_Trig, Str_Ts, ClkReg, Arm, IsArmed, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_stream_c) <= '1';
wait;
@ -276,49 +276,49 @@ begin
-- single_frame
wait until NextCase = 0;
ProcessDone(TbProcNr_daq_c) <= '0';
work.psi_ms_daq_input_tb_case_single_frame.daq(ClkSmem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
work.psi_ms_daq_input_tb_case_single_frame.daq(ClkMem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_daq_c) <= '1';
-- multi_frame
wait until NextCase = 1;
ProcessDone(TbProcNr_daq_c) <= '0';
work.psi_ms_daq_input_tb_case_multi_frame.daq(ClkSmem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
work.psi_ms_daq_input_tb_case_multi_frame.daq(ClkMem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_daq_c) <= '1';
-- timeout
wait until NextCase = 2;
ProcessDone(TbProcNr_daq_c) <= '0';
work.psi_ms_daq_input_tb_case_timeout.daq(ClkSmem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
work.psi_ms_daq_input_tb_case_timeout.daq(ClkMem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_daq_c) <= '1';
-- ts_overflow
wait until NextCase = 3;
ProcessDone(TbProcNr_daq_c) <= '0';
work.psi_ms_daq_input_tb_case_ts_overflow.daq(ClkSmem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
work.psi_ms_daq_input_tb_case_ts_overflow.daq(ClkMem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_daq_c) <= '1';
-- trig_in_posttrig
wait until NextCase = 4;
ProcessDone(TbProcNr_daq_c) <= '0';
work.psi_ms_daq_input_tb_case_trig_in_posttrig.daq(ClkSmem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
work.psi_ms_daq_input_tb_case_trig_in_posttrig.daq(ClkMem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_daq_c) <= '1';
-- always_trig
wait until NextCase = 5;
ProcessDone(TbProcNr_daq_c) <= '0';
work.psi_ms_daq_input_tb_case_always_trig.daq(ClkSmem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
work.psi_ms_daq_input_tb_case_always_trig.daq(ClkMem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_daq_c) <= '1';
-- backpressure
wait until NextCase = 6;
ProcessDone(TbProcNr_daq_c) <= '0';
work.psi_ms_daq_input_tb_case_backpressure.daq(ClkSmem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
work.psi_ms_daq_input_tb_case_backpressure.daq(ClkMem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_daq_c) <= '1';
-- modes
wait until NextCase = 7;
ProcessDone(TbProcNr_daq_c) <= '0';
work.psi_ms_daq_input_tb_case_modes.daq(ClkSmem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
work.psi_ms_daq_input_tb_case_modes.daq(ClkMem, PostTrigSpls, Mode, Daq_Vld, Daq_Rdy, Daq_Data, Daq_Level, Daq_HasLast, Ts_Vld, Ts_Rdy, Ts_Data, Generics_c);
wait for 1 ps;
ProcessDone(TbProcNr_daq_c) <= '1';
wait;

View File

@ -19,23 +19,23 @@ library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.smem_master_types_pkg.all;
use work.psi_ms_daq_tb_pkg.all;
use work.psi_ms_daq_tb_str0_pkg.all;
use work.psi_ms_daq_tb_str1_pkg.all;
use work.psi_ms_daq_tb_str2_pkg.all;
use work.psi_ms_daq_tb_str3_pkg.all;
use work.psi_ms_daq_tosca_tb_pkg.all;
use work.psi_ms_daq_tosca_tb_str0_pkg.all;
use work.psi_ms_daq_tosca_tb_str1_pkg.all;
use work.psi_ms_daq_tosca_tb_str2_pkg.all;
use work.psi_ms_daq_tosca_tb_str3_pkg.all;
------------------------------------------------------------
-- Entity Declaration
------------------------------------------------------------
entity psi_ms_daq_tb is
entity psi_ms_daq_tosca_tb is
end entity;
------------------------------------------------------------
-- Architecture
------------------------------------------------------------
architecture sim of psi_ms_daq_tb is
architecture sim of psi_ms_daq_tosca_tb is
-- TB Control
signal TbRunning : boolean := true;
@ -100,7 +100,7 @@ begin
------------------------------------------------------------
-- DUT Instantiation
------------------------------------------------------------
i_dut : entity work.psi_ms_daq
i_dut : entity work.psi_ms_daq_tosca
generic map (
Streams_g => StrCount_c,
StreamWidth_g => (0=>8, 1=>16, 2=>16, 3=>32),
@ -110,7 +110,7 @@ begin
StreamClkFreq_g => ClkFreq_c,
StreamTsFifoDepth_g => (0=>16, 1=>16, 2=>16, 3=>16),
StreamUseTs_g => (0=>true, 1=>true, 2=>true, 3=>false),
MaxWindows_g => work.psi_ms_daq_tb_pkg.MaxWindows_c,
MaxWindows_g => work.psi_ms_daq_tosca_tb_pkg.MaxWindows_c,
MinBurstSize_g => 16,
MaxBurstSize_g => 128
)
@ -221,7 +221,7 @@ begin
begin
print("*** Info ***");
print("This testbench does not print any status information by default (only errors).");
print("To change this behavior, change the constant PrintDefault_c in psi_ms_daq_tb_pkg.");
print("To change this behavior, change the constant PrintDefault_c in psi_ms_daq_tosca_tb_pkg.");
wait for 1 us;
Tmem_Rst <= '0';
@ -243,7 +243,7 @@ begin
-- *** Run Test ***
StartTime_v := now;
while now < StartTime_v+100 us loop
while now < StartTime_v+150 us loop
wait until rising_edge(Tmem_Clk);
-- IRQ Handling
if Irq = '1' then

View File

@ -17,7 +17,7 @@ library work;
------------------------------------------------------------
-- Package Header
------------------------------------------------------------
package psi_ms_daq_tb_pkg is
package psi_ms_daq_tosca_tb_pkg is
--------------------------------------------------------
-- Global Stuff
@ -41,6 +41,7 @@ package psi_ms_daq_tb_pkg is
constant REG_CONF_MAXLVLn : integer := 16#200#;
constant REG_CONF_POSTTRIGn : integer := 16#204#;
constant REG_CONF_MODEn : integer := 16#208#;
constant REG_CONF_LASTWINn : integer := 16#20C#;
constant VAL_MODE_RECM_CONT : integer := 0*2**0;
constant VAL_MODE_RECM_TRIGMASK : integer := 1*2**0;
constant VAL_MODE_RECM_SINGLE : integer := 2*2**0;
@ -154,6 +155,12 @@ package psi_ms_daq_tb_pkg is
signal rsp : in TmemResp_t;
val : out integer);
procedure HlGetLastWin( str : in integer;
signal clk : in std_logic;
signal rqst : out TmemRqst_t;
signal rsp : in TmemResp_t;
val : out integer);
procedure HlGetCurWin( str : in integer;
signal clk : in std_logic;
signal rqst : out TmemRqst_t;
@ -207,7 +214,7 @@ end package;
------------------------------------------------------------
-- Package Body
------------------------------------------------------------
package body psi_ms_daq_tb_pkg is
package body psi_ms_daq_tosca_tb_pkg is
--------------------------------------------------------
-- Helper Procedures
@ -391,6 +398,16 @@ package body psi_ms_daq_tb_pkg is
val, clk, rqst, rsp);
end procedure;
procedure HlGetLastWin( str : in integer;
signal clk : in std_logic;
signal rqst : out TmemRqst_t;
signal rsp : in TmemResp_t;
val : out integer) is
begin
TmemRead32( REG_CONF_REGION+REG_CONF_LASTWINn+REG_CONF_Xn_STEP*str,
val, clk, rqst, rsp);
end procedure;
procedure HlGetCurWin( str : in integer;
signal clk : in std_logic;
signal rqst : out TmemRqst_t;

View File

@ -23,12 +23,12 @@ library work;
library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.psi_ms_daq_tb_pkg.all;
use work.psi_ms_daq_tosca_tb_pkg.all;
------------------------------------------------------------
-- Package Header
------------------------------------------------------------
package psi_ms_daq_tb_str0_pkg is
package psi_ms_daq_tosca_tb_str0_pkg is
constant PrintStr0_c : boolean := PrintDefault_c;
@ -82,7 +82,7 @@ end package;
------------------------------------------------------------
-- Package Body
------------------------------------------------------------
package body psi_ms_daq_tb_str0_pkg is
package body psi_ms_daq_tosca_tb_str0_pkg is
--------------------------------------------------------
-- Data Generation

View File

@ -19,12 +19,12 @@ library work;
library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.psi_ms_daq_tb_pkg.all;
use work.psi_ms_daq_tosca_tb_pkg.all;
------------------------------------------------------------
-- Package Header
------------------------------------------------------------
package psi_ms_daq_tb_str1_pkg is
package psi_ms_daq_tosca_tb_str1_pkg is
constant PrintStr1_c : boolean := PrintDefault_c;
@ -76,7 +76,7 @@ end package;
------------------------------------------------------------
-- Package Body
------------------------------------------------------------
package body psi_ms_daq_tb_str1_pkg is
package body psi_ms_daq_tosca_tb_str1_pkg is
--------------------------------------------------------
-- Data Generation

View File

@ -19,12 +19,12 @@ library work;
library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.psi_ms_daq_tb_pkg.all;
use work.psi_ms_daq_tosca_tb_pkg.all;
------------------------------------------------------------
-- Package Header
------------------------------------------------------------
package psi_ms_daq_tb_str2_pkg is
package psi_ms_daq_tosca_tb_str2_pkg is
constant PrintStr2_c : boolean := PrintDefault_c;
@ -79,7 +79,7 @@ end package;
------------------------------------------------------------
-- Package Body
------------------------------------------------------------
package body psi_ms_daq_tb_str2_pkg is
package body psi_ms_daq_tosca_tb_str2_pkg is
--------------------------------------------------------
-- Data Generation
@ -117,6 +117,7 @@ package body psi_ms_daq_tb_str2_pkg is
signal rsp : in TmemResp_t) is
variable v : integer;
variable curwin : integer;
variable lastwin : integer;
variable wincnt : integer;
variable spladdr : integer;
variable splNr : integer;
@ -140,8 +141,13 @@ package body psi_ms_daq_tb_str2_pkg is
-- Read window data
-- Check if recording is finished
HlIsTrigWin(2, curwin, clk, rqst, rsp, isTrig);
-- Check if window is fully written to memory
HlGetLastWin(2, clk, rqst, rsp, lastwin);
-- Execute
if not isTrig then
print("Skipped: not a trigger window", PrintStr2_c);
elsif curwin /= lastwin then
print("Skipped: not written to memory yet " & str(curwin) & " " & str(lastwin), PrintStr2_c);
else
-- Check Data (last 128 samples)
splNr := Str2PostTrig_c;
@ -150,8 +156,8 @@ package body psi_ms_daq_tb_str2_pkg is
HlGetWinLast(2, curwin, clk, rqst, rsp, spladdr);
print("WINLAST: " & to_string(spladdr), PrintStr2_c);
while (splNr >= 0) and (spladdr >= Str2BufStart_c+curwin*Str2WinSize_c) loop
StdlvCompareInt(splNr, Memory(spladdr), "Stream2: Sample " & to_string(Str2ExpFrame) & ":" & to_string(splNr) & " wrong CNT", false);
StdlvCompareInt(Str2ExpFrame, Memory(spladdr+1), "Stream2: Sample " & to_string(Str2ExpFrame) & ":" & to_string(splNr) & " wrong FRAME", false);
StdlvCompareInt(splNr, Memory(spladdr), "Stream2: Sample " & to_string(Str2ExpFrame) & ":" & to_string(splNr) & " wrong CNT [addr=" & str(spladdr) & "]", false);
StdlvCompareInt(Str2ExpFrame, Memory(spladdr+1), "Stream2: Sample " & to_string(Str2ExpFrame) & ":" & to_string(splNr) & " wrong FRAME [addr=" & str(spladdr) & "]", false);
spladdr := spladdr - 2;
splNr := splNr - 1;
end loop;

View File

@ -17,12 +17,12 @@ library work;
library work;
use work.psi_tb_txt_util.all;
use work.psi_tb_compare_pkg.all;
use work.psi_ms_daq_tb_pkg.all;
use work.psi_ms_daq_tosca_tb_pkg.all;
------------------------------------------------------------
-- Package Header
------------------------------------------------------------
package psi_ms_daq_tb_str3_pkg is
package psi_ms_daq_tosca_tb_str3_pkg is
constant PrintStr3_c : boolean := PrintDefault_c;
@ -78,7 +78,7 @@ end package;
------------------------------------------------------------
-- Package Body
------------------------------------------------------------
package body psi_ms_daq_tb_str3_pkg is
package body psi_ms_daq_tosca_tb_str3_pkg is
--------------------------------------------------------
-- Data Generation