10 Commits

Author SHA1 Message Date
Oliver Bruendler
141d54dd4f DEVEL: Fix testbench (tolerate additional IRQs on stream2) 2019-11-15 13:57:05 +01:00
Oliver Bruendler
8b2211d07a FEATURE: Added claring of the maximum level FIFO to the driver 2019-11-14 07:56:38 +01:00
Oliver Bruendler
7de31cc946 DOC: Fixed documentation (WINCNTw is in samples, not bytes) 2019-11-12 14:39:54 +01:00
Oliver Bruendler
2838d1e3e9 DOC: Fixed documentation (use strHandle instead of ipHandle in example code) 2019-11-12 14:38:42 +01:00
Oliver Bruendler
404af6d979 BUGFIX: Fix data unwrapping (bug found in HIPA LLRF bringup) 2019-11-12 14:37:39 +01:00
Oliver Bruendler
df29e19f6d TIMING: Optimized timing on critical path between input FIFO and DMA
Added pipeline stage after FIFO to reduce requirements of fall-through interface
2019-11-07 07:46:37 +01:00
Oliver Bruendler
7f22ec9050 BUGFIX: Made design working for 1 stream 2019-10-30 11:02:11 +01:00
Oliver Bruendler
3efc256530 Merge branch 'master' of https://github.com/paulscherrerinstitute/psi_multi_stream_daq 2019-10-30 08:06:15 +01:00
Oliver Bruendler
be272f611c DEVEL: Made driver C++ tolerant 2019-10-21 17:41:29 +02:00
Oliver Bruendler
9ad003bc41 DEVEL: Made driver C++ compatible 2019-10-21 17:39:21 +02:00
19 changed files with 817 additions and 91 deletions

View File

@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Driver Documentation: D:/gfa/Libraries/Firmware/VHDL/psi_multi_stream_daq/driver Directory Reference</title>
<title>Driver Documentation: D:/gfa/RF/HIPA/LLRF_v1/post_mortem/Lib/VHDL/psi_multi_stream_daq/driver Directory Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Driver Documentation: D:/gfa/Libraries/Firmware/VHDL/psi_multi_stream_daq/driver/psi_ms_daq.h File Reference</title>
<title>Driver Documentation: D:/gfa/RF/HIPA/LLRF_v1/post_mortem/Lib/VHDL/psi_multi_stream_daq/driver/psi_ms_daq.h File Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>

File diff suppressed because one or more lines are too long

View File

@@ -160,7 +160,7 @@ Public Attributes</h2></td></tr>
</div>
</div>
<hr/>The documentation for this struct was generated from the following file:<ul>
<li>D:/gfa/Libraries/Firmware/VHDL/psi_multi_stream_daq/driver/<a class="el" href="psi__ms__daq_8h_source.html">psi_ms_daq.h</a></li>
<li>D:/gfa/RF/HIPA/LLRF_v1/post_mortem/Lib/VHDL/psi_multi_stream_daq/driver/<a class="el" href="psi__ms__daq_8h_source.html">psi_ms_daq.h</a></li>
</ul>
</div><!-- contents -->
</div><!-- doc-content -->

View File

@@ -255,7 +255,7 @@ Public Attributes</h2></td></tr>
</div>
</div>
<hr/>The documentation for this struct was generated from the following file:<ul>
<li>D:/gfa/Libraries/Firmware/VHDL/psi_multi_stream_daq/driver/<a class="el" href="psi__ms__daq_8h_source.html">psi_ms_daq.h</a></li>
<li>D:/gfa/RF/HIPA/LLRF_v1/post_mortem/Lib/VHDL/psi_multi_stream_daq/driver/<a class="el" href="psi__ms__daq_8h_source.html">psi_ms_daq.h</a></li>
</ul>
</div><!-- contents -->
</div><!-- doc-content -->

View File

@@ -161,7 +161,7 @@ Public Attributes</h2></td></tr>
</div>
</div>
<hr/>The documentation for this struct was generated from the following file:<ul>
<li>D:/gfa/Libraries/Firmware/VHDL/psi_multi_stream_daq/driver/<a class="el" href="psi__ms__daq_8h_source.html">psi_ms_daq.h</a></li>
<li>D:/gfa/RF/HIPA/LLRF_v1/post_mortem/Lib/VHDL/psi_multi_stream_daq/driver/<a class="el" href="psi__ms__daq_8h_source.html">psi_ms_daq.h</a></li>
</ul>
</div><!-- contents -->
</div><!-- doc-content -->

Binary file not shown.

Binary file not shown.

View File

@@ -406,6 +406,18 @@ PsiMsDaq_RetCode_t PsiMsDaq_Str_GetMaxLvl( PsiMsDaq_StrHandle strHndl,
return PsiMsDaq_RetCode_Success;
}
PsiMsDaq_RetCode_t PsiMsDaq_Str_ClrMaxLvl( PsiMsDaq_StrHandle strHndl)
{
//Pointer Cast
PsiMsDaq_StrInst_t* inst_p = (PsiMsDaq_StrInst_t*) strHndl;
PsiMsDaq_IpHandle ipHandle = inst_p->ipHandle;
const uint8_t strNr = inst_p->nr;
//Implementation
SAFE_CALL(PsiMsDaq_RegWrite(ipHandle, PSI_MS_DAQ_REG_MAXLVL(strNr), 0));
//Done
return PsiMsDaq_RetCode_Success;
}
PsiMsDaq_RetCode_t PsiMsDaq_Str_GetFreeWindows( PsiMsDaq_StrHandle strHndl,
uint8_t* const freeWindows_p)
{
@@ -499,7 +511,6 @@ PsiMsDaq_RetCode_t PsiMsDaq_StrWin_GetNoOfSamples( PsiMsDaq_WinInfo_t winInfo,
{
//Pointer Case
PsiMsDaq_Inst_t* ip_p = (PsiMsDaq_Inst_t*)winInfo.ipHandle;
PsiMsDaq_StrInst_t* str_p = (PsiMsDaq_StrInst_t*)winInfo.strHandle;
//Setup
uint8_t strNr;
SAFE_CALL(PsiMsDaq_Str_GetStrNr(winInfo.strHandle, &strNr));
@@ -507,13 +518,11 @@ PsiMsDaq_RetCode_t PsiMsDaq_StrWin_GetNoOfSamples( PsiMsDaq_WinInfo_t winInfo,
SAFE_CALL(CheckStrNr(winInfo.ipHandle, strNr))
SAFE_CALL(CheckWinNr(winInfo.strHandle, winInfo.winNr))
//Implementation
uint32_t noOfBytes;
SAFE_CALL(PsiMsDaq_RegGetField( winInfo.ipHandle,
PSI_MS_DAQ_WIN_WINCNT(strNr, winInfo.winNr, ip_p->strAddrOffs),
PSI_MS_DAQ_WIN_WINCNT_LSB_CNT,
PSI_MS_DAQ_WIN_WINCNT_MSB_CNT,
&noOfBytes));
*noOfSamples_p = noOfBytes / str_p->widthBytes;
noOfSamples_p));
//Done
return PsiMsDaq_RetCode_Success;
}
@@ -601,7 +610,7 @@ PsiMsDaq_RetCode_t PsiMsDaq_StrWin_GetDataUnwrapped( PsiMsDaq_WinInfo_t winInfo,
//Calculate address of last byte and trigger byte (with regard to wrapping)
uint32_t lastSplAddr;
SAFE_CALL(PsiMsDaq_StrWin_GetLastSplAddr(winInfo, &lastSplAddr));
uint32_t trigByteAddr = lastSplAddr - (str_p->postTrig+1)*str_p->widthBytes; //+1 because trigger is not included in postTrigger
uint32_t trigByteAddr = lastSplAddr - str_p->postTrig*str_p->widthBytes;
if (trigByteAddr < winStart) {
trigByteAddr += str_p->winSize;
}
@@ -612,7 +621,7 @@ PsiMsDaq_RetCode_t PsiMsDaq_StrWin_GetDataUnwrapped( PsiMsDaq_WinInfo_t winInfo,
//If all bytes are written without wrap, copy directly
const uint32_t firstByteLinear = lastByteAddr - bytes + 1;
const int64_t firstByteLinear = (int64_t)lastByteAddr - bytes + 1;
if (firstByteLinear >= winStart) {
ip_p->memcpyFct(buffer_p, (void*)(size_t)firstByteLinear, bytes);
}
@@ -620,9 +629,9 @@ PsiMsDaq_RetCode_t PsiMsDaq_StrWin_GetDataUnwrapped( PsiMsDaq_WinInfo_t winInfo,
else {
const uint32_t secondChunkSize = lastByteAddr - winStart + 1;
const uint32_t firstChunkSize = bytes-secondChunkSize;
const uint32_t firstChunkStartAddr = winLast-firstChunkSize+1;
ip_p->memcpyFct(buffer_p, (void*)(size_t)firstChunkStartAddr, firstChunkSize);
ip_p->memcpyFct(buffer_p+firstChunkSize, (void*)(size_t)winStart, secondChunkSize);
const int64_t firstChunkStartAddr = winLast-firstChunkSize+1;
ip_p->memcpyFct(buffer_p, (void*)(size_t)firstChunkStartAddr, firstChunkSize);
ip_p->memcpyFct((void*)((uint32_t)buffer_p+firstChunkSize), (void*)(size_t)winStart, secondChunkSize);
}
//Done

View File

@@ -6,6 +6,10 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
//*******************************************************************************
// Documentation
//*******************************************************************************
@@ -113,13 +117,13 @@
* .winSize = <sizePerWindow>, //in bytes
* .streamWidthBits = <widthInBits>
* };
* PsiMsDaq_Str_Configure(daqHandle, &cfg);
* PsiMsDaq_Str_Configure(daqStrHandle, &cfg);
* //Register ballback
* PsiMsDaq_Str_SetIrqCallbackWin(daqHandle, UserDaqIsr, NULL);
* PsiMsDaq_Str_SetIrqCallbackWin(daqStrHandle, UserDaqIsr, NULL);
* //Enable IRQ
* PsiMsDaq_Str_SetIrqEnable(daqHandle, true);
* PsiMsDaq_Str_SetIrqEnable(daqStrHandle, true);
* //Enable recorder for stream
* PsiMsDaq_Str_SetEnable(daqHandle, true);
* PsiMsDaq_Str_SetEnable(daqStrHandle, true);
*
* //Wait in endless loop for IRQs comming in
* while(1){};
@@ -252,7 +256,7 @@ typedef enum {
PsiMsDaqn_RecMode_Continuous = 0, ///< Continuous recording
PsiMsDaqn_RecMode_TriggerMask = 1, ///< Continuously record pre-trigger data but only detect triggers after PsiMsDaq_Str_Arm() was called
PsiMsDaqn_RecMode_SingleShot = 2, ///< Only record pre-trigger after PsiMsDaq_Str_Arm() was called and stop recording after one trigger
PsiMsDaqn_RecMode_Manual = 3, ///< Manaully control the recording by setting and clearing the arm bit
PsiMsDaqn_RecMode_Manual = 3 ///< Manaully control the recording by setting and clearing the arm bit
} PsiMsDaq_RecMode_t;
/**
@@ -421,6 +425,14 @@ PsiMsDaq_RetCode_t PsiMsDaq_Str_Arm(PsiMsDaq_StrHandle strHndl);
*/
PsiMsDaq_RetCode_t PsiMsDaq_Str_GetMaxLvl( PsiMsDaq_StrHandle strHndl,
uint32_t* const maxLvl_p);
/**
* @brief Clear the maximum input buffer fill level
*
* @param strHndl Driver handle for the stream
* @return Return Code
*/
PsiMsDaq_RetCode_t PsiMsDaq_Str_ClrMaxLvl( PsiMsDaq_StrHandle strHndl);
/**
* @brief Get the number of free windows.
@@ -697,6 +709,10 @@ PsiMsDaq_RetCode_t PsiMsDaq_RegGetBit( PsiMsDaq_IpHandle ipHandle,
const uint32_t addr,
const uint32_t mask,
bool* const value_p);
#ifdef __cplusplus
}
#endif

View File

@@ -68,15 +68,19 @@ architecture rtl of psi_ms_daq_daq_dma is
-- Constants
constant BufferFifoDepth_c : integer := 32;
-- Number of bits to encode stream is at least 1 (otherwise the special case for one stream would require separate code).
-- .. The overhead generated by this is regarded as aceptable (better wasting a few LUTs than much development time)
constant StreamBits_c : integer := max(log2ceil(Streams_g), 1);
-- Component Connection Signals
signal CmdFifo_Level_Dbg : std_logic_vector(log2ceil(Streams_g) downto 0);
signal CmdFifo_Level_Dbg : std_logic_vector(StreamBits_c downto 0);
signal CmdFifo_InData : std_logic_vector(DaqSm2DaqDma_Cmd_Size_c-1 downto 0);
signal CmdFifo_OutData : std_logic_vector(DaqSm2DaqDma_Cmd_Size_c-1 downto 0);
signal CmdFifo_Cmd : DaqSm2DaqDma_Cmd_t;
signal CmdFifo_Vld : std_logic;
signal RspFifo_Level_Dbg : std_logic_vector(log2ceil(Streams_g) downto 0);
signal RspFifo_Level_Dbg : std_logic_vector(StreamBits_c downto 0);
signal RspFifo_InData : std_logic_vector(DaqDma2DaqSm_Resp_Size_c-1 downto 0);
signal RspFifo_OutData : std_logic_vector(DaqDma2DaqSm_Resp_Size_c-1 downto 0);
signal DatFifo_Level_Dbg : std_logic_vector(log2ceil(BufferFifoDepth_c) downto 0);
@@ -95,7 +99,7 @@ architecture rtl of psi_ms_daq_daq_dma is
RspFifo_Vld : std_logic;
RspFifo_Data : DaqDma2DaqSm_Resp_t;
Mem_DataVld : std_logic;
StreamStdlv : std_logic_vector(log2ceil(Streams_g)-1 downto 0);
StreamStdlv : std_logic_vector(StreamBits_c-1 downto 0);
RemWen : std_logic;
RemWrBytes : std_logic_vector(2 downto 0);
RemData : std_logic_vector(63 downto 0);
@@ -300,7 +304,7 @@ begin
i_fifocmd : entity work.psi_common_sync_fifo
generic map (
Width_g => DaqSm2DaqDma_Cmd_Size_c,
Depth_g => Streams_g,
Depth_g => 2**StreamBits_c,
RamStyle_g => "distributed",
RamBehavior_g => "RBW"
)
@@ -322,7 +326,7 @@ begin
i_fiforsp : entity work.psi_common_sync_fifo
generic map (
Width_g => DaqDma2DaqSm_Resp_Size_c,
Depth_g => Streams_g,
Depth_g => 2**StreamBits_c,
RamStyle_g => "distributed",
RamBehavior_g => "RBW"
)
@@ -366,7 +370,7 @@ begin
-- *** Remaining Data RAM ***
i_remram : entity work.psi_common_sdp_ram
generic map (
Depth_g => Streams_g,
Depth_g => 2**StreamBits_c,
Width_g => 1+1+3+64,
IsAsync_g => false,
RamStyle_g => "distributed",

View File

@@ -76,6 +76,10 @@ end entity;
------------------------------------------------------------------------------
architecture rtl of psi_ms_daq_daq_sm is
-- Number of bits to encode stream is at least 1 (otherwise the special case for one stream would require separate code).
-- .. The overhead generated by this is regarded as aceptable (better wasting a few LUTs than much development time)
constant StreamBits_c : integer := max(log2ceil(Streams_g), 1);
-- Function Definitions
function GetBitsOfStreamPrio( InputVector : std_logic_vector;
Prio : integer)
@@ -132,10 +136,10 @@ architecture rtl of psi_ms_daq_daq_sm is
signal IrqFifoAlmFull : std_logic;
signal IrqFifoEmpty : std_logic;
signal IrqFifoGenIrq : std_logic;
signal IrqFifoStream : std_logic_vector(log2ceil(Streams_g)-1 downto 0);
signal IrqFifoStream : std_logic_vector(StreamBits_c-1 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);
signal IrqFifoIn : std_logic_vector(StreamBits_c+log2ceil(Windows_g) downto 0);
signal IrqFifoOut : std_logic_vector(StreamBits_c+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);
@@ -178,7 +182,7 @@ architecture rtl of psi_ms_daq_daq_sm is
HndlWinBytes : std_logic_vector(32 downto 0);
HndlWinLast : std_logic_vector(31 downto 0);
HndlTs : std_logic_vector(63 downto 0);
TfDoneCnt : std_logic_vector(log2ceil(Streams_g)-1 downto 0);
TfDoneCnt : std_logic_vector(StreamBits_c-1 downto 0);
TfDoneReg : std_logic;
HndlWinDone : std_logic;
CtxStr_Cmd : ToCtxStr_t;
@@ -681,15 +685,15 @@ begin
-- *** IRQ Information FIFO ***
-- input assembly
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;
IrqFifoIn(StreamBits_c-1 downto 0) <= std_logic_vector(to_unsigned(r.HndlStream, StreamBits_c));
IrqFifoIn(StreamBits_c+log2ceil(Windows_g)-1 downto StreamBits_c) <= r.HndlLastWinNr;
IrqFifoIn(IrqFifoIn'high) <= r.HndlWinDone;
-- Instantiation
i_irq_fifo : entity work.psi_common_sync_fifo
generic map (
Width_g => log2ceil(Streams_g)+log2ceil(Windows_g)+1,
Depth_g => Streams_g*4,
Width_g => StreamBits_c+log2ceil(Windows_g)+1,
Depth_g => 2**StreamBits_c*4,
AlmFullOn_g => true,
AlmFullLevel_g => Streams_g*3,
RamStyle_g => "distributed"
@@ -706,8 +710,8 @@ begin
);
-- Output disassembly
IrqFifoStream <= IrqFifoOut(log2ceil(Streams_g)-1 downto 0);
IrqLastWinNr <= IrqFifoOut(log2ceil(Streams_g)+log2ceil(Windows_g)-1 downto log2ceil(Streams_g));
IrqFifoStream <= IrqFifoOut(StreamBits_c-1 downto 0);
IrqLastWinNr <= IrqFifoOut(StreamBits_c+log2ceil(Windows_g)-1 downto StreamBits_c);
IrqFifoGenIrq <= IrqFifoOut(IrqFifoOut'high);

View File

@@ -114,6 +114,11 @@ architecture rtl of psi_ms_daq_input is
signal DataFifo_InRdy : std_logic;
signal DataFifo_InData : std_logic_vector(69 downto 0);
signal DataFifo_OutData : std_logic_vector(69 downto 0);
signal DataFifo_PlData : std_logic_vector(69 downto 0);
signal DataFifo_PlVld : std_logic;
signal DataFifo_PlRdy : std_logic;
signal DataFifo_Level : std_logic_vector(log2ceil(StreamBuffer_g) downto 0);
signal DataPl_Level : unsigned(1 downto 0);
-- Internally reused signals
signal Daq_Data_I : Input2Daq_Data_t;
@@ -343,6 +348,7 @@ begin
-- Output Side TLAST handling
--------------------------------------------
p_outlast : process(ClkMem)
variable PlLevel_v : unsigned(DataPl_Level'range);
begin
if rising_edge(ClkMem) then
-- Default Value
@@ -357,11 +363,26 @@ begin
if OutTlastCnt /= InTlastCnt then
Daq_HasLast_I <= '1';
end if;
-- Level Calculation (add samples in PL stage)
PlLevel_v := DataPl_Level;
if DataFifo_PlRdy = '1' and DataFifo_PlVld = '1' then
PlLevel_v := PlLevel_v + 1;
end if;
if Daq_Vld_I = '1' and Daq_Rdy = '1' then
PlLevel_v := PlLevel_v - 1;
end if;
DataPl_Level <= PlLevel_v;
-- We calculate the level one cycle late but this does not play any role (the DAQ FSM only runs after data is transferred)
Daq_Level <= std_logic_vector(resize(unsigned(DataFifo_Level), Daq_Level'length) + DataPl_Level);
-- Reset
if RstMem = '1' then
OutTlastCnt <= (others => '0');
end if;
OutTlastCnt <= (others => '0');
Daq_Level <= (others => '0');
DataPl_Level <= (others => '0');
end if;
end if;
end process;
Daq_HasLast <= Daq_HasLast_I;
@@ -455,8 +476,8 @@ begin
-- Data FIFO
DataFifo_InData(63 downto 0) <= r.DataSftReg;
DataFifo_InData(67 downto 64) <= std_logic_vector(r.DataFifoBytes);
DataFifo_InData(68) <= r.DataFifoIsTo;
DataFifo_InData(69) <= r.DataFifoIsTrig;
DataFifo_InData(68) <= r.DataFifoIsTo;
DataFifo_InData(69) <= r.DataFifoIsTrig;
i_dfifo : entity work.psi_common_async_fifo
@@ -474,12 +495,28 @@ begin
InData => DataFifo_InData,
InVld => r.DataFifoVld,
InRdy => DataFifo_InRdy,
OutData => DataFifo_OutData,
OutVld => Daq_Vld_I,
OutRdy => Daq_Rdy,
OutLevel => Daq_Level(log2ceil(StreamBuffer_g) downto 0)
OutData => DataFifo_PlData,
OutVld => DataFifo_PlVld,
OutRdy => DataFifo_PlRdy,
OutLevel => DataFifo_Level
);
-- An additional pipeline stage after the FIFO is required for timing reasons
i_dplstage : entity work.psi_common_pl_stage
generic map (
Width_g => 70,
UseRdy_g => true
)
port map (
Clk => ClkMem,
Rst => RstMem,
InVld => DataFifo_PlVld,
InRdy => DataFifo_PlRdy,
InData => DataFifo_PlData,
OutVld => Daq_Vld_I,
OutRdy => Daq_Rdy,
OutData => DataFifo_OutData
);
Daq_Level(Daq_Level'high downto log2ceil(StreamBuffer_g)+1) <= (others => '0');
Str_Rdy <= DataFifo_InRdy;
Daq_Data_I.Data <= DataFifo_OutData(63 downto 0);

View File

@@ -206,7 +206,7 @@ begin
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)));
Stream_v := work.psi_common_math_pkg.min(to_integer(unsigned(AccAddr(8 downto 4))), Streams_g-1);
-- MAXLVLn
if AccAddr(3 downto 0) = X"0" then

View File

@@ -90,6 +90,8 @@ add_sources "../tb" {
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 \
psi_ms_daq_axi_1s/psi_ms_daq_axi_1s_tb_str0_pkg.vhd \
psi_ms_daq_axi_1s/psi_ms_daq_axi_1s_tb.vhd \
} -tag tb
#TB Runs
@@ -112,6 +114,9 @@ add_tb_run
create_tb_run "psi_ms_daq_axi_tb"
add_tb_run
create_tb_run "psi_ms_daq_axi_1s_tb"
add_tb_run

View File

@@ -378,7 +378,7 @@ begin
-- *** 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 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;

View File

@@ -0,0 +1,393 @@
------------------------------------------------------------------------------
-- Copyright (c) 2019 by Paul Scherrer Institute, Switzerland
-- All rights reserved.
-- Authors: Oliver Bruendler
------------------------------------------------------------------------------
------------------------------------------------------------
-- 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_1s_tb_str0_pkg.all;
------------------------------------------------------------
-- Entity Declaration
------------------------------------------------------------
entity psi_ms_daq_axi_1s_tb is
end entity;
------------------------------------------------------------
-- Architecture
------------------------------------------------------------
architecture sim of psi_ms_daq_axi_1s_tb is
-- TB Control
signal TbRunning : boolean := true;
signal PrintIrq_c : boolean := PrintDefault_c;
-- Constants
constant StrCount_c : integer := 1;
constant ClkFreq_c : t_areal := (0=>250.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 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 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),
StreamPrio_g => (0=>1),
StreamBuffer_g => (0=>32),
StreamTimeout_g => (0=>5.0e-6),
StreamClkFreq_g => (ClkFreq_c, ClkFreq_c),
StreamTsFifoDepth_g => (0=>16, 1=>16),
StreamUseTs_g => (0=>true, 1=>true),
MaxWindows_g => work.psi_ms_daq_axi_tb_pkg.MaxWindows_c,
MinBurstSize_g => 16,
MaxBurstSize_g => 128,
AxiFifoDepth_g => 512,
AxiSlaveIdWidth_g => 1
)
port map (
Str_Clk => Str_Clk,
Str_Data(0)(7 downto 0) => Str0_Data,
Str_Data(0)(63 downto 8) => (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_ArId => reg_axi_ms.arid,
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_RId => reg_axi_sm.rid,
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_AwId => reg_axi_ms.awid,
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_BId => reg_axi_sm.bid,
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_1s_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#0001#, S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
AxiWriteAndRead32(16#0020#, 16#0001#, S_Axi_Aclk, reg_axi_ms, reg_axi_sm);
-- Stream Setup
Str0Setup(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);
end loop;
TbRunning <= false;
-- *** Check end state ***
assert Str0WinCheck >= 4 report "###ERROR###: Stream 0 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;
------------------------------------------------------------
-- Check Process
------------------------------------------------------------
end;

View File

@@ -0,0 +1,258 @@
------------------------------------------------------------------------------
-- Copyright (c) 2019 by Paul Scherrer Institute, Switzerland
-- All rights reserved.
-- Authors: Oliver Bruendler
------------------------------------------------------------------------------
------------------------------------------------------------
-- 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_1s_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_1s_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 lastwin : 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);
HlGetLastWin(0, clk, rqst, rsp, lastwin);
print("LASTWIN: " & to_string(lastwin), 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);
-- lastwin = nextwin can occur if al lwindows are filled. In all cases we only interpret windows containing triggers.
while ((Str0NextWin /= ((lastwin+1) mod 3)) 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;