24 Commits

Author SHA1 Message Date
Waldemar Koprek
f4c0185f31 Merge pull request #8 from paulscherrerinstitute/feature/se32
New features in branch feature/se32
2024-08-08 12:41:58 +02:00
01de9bd1a9 Add register to control caching behavior on AXI link that performs the dma transfer 2024-08-08 11:53:32 +02:00
16f13e64d7 Add internal data width as generic parameter 2024-08-08 11:49:45 +02:00
Waldemar Koprek
0dfa3ef76b Merge pull request #7 from paulscherrerinstitute/6-interrupts-not-reliably-generated-when-window-is-switched
Adapt interrupt generation logic to solve problem with missing interr…
2024-07-30 08:47:23 +02:00
3957ce32b5 Adapt interrupt generation logic to solve problem with missing interrupts. 2024-07-25 15:39:24 +02:00
a0f4eddf91 Updated instantiation of psi_common_async_fifo due to change of the port name 2024-01-26 10:48:07 +01:00
Waldemar Koprek
69a9c03486 Merge pull request #5 from paulscherrerinstitute/feature/timeout_ctrl
Adaptions in timeout handling at the stream input stage
2023-09-21 12:47:32 +02:00
12c010fe45 Add timeout control bits and logic to ignore timeout or configure framebased timeout in input logic. 2023-09-19 16:09:12 +02:00
f6178e9dbd Refactoring and compliant with 3.0.0 release psi_common 2023-04-14 17:36:50 +02:00
28b79e93a9 DOC: Updated Changelog.md 2020-09-30 14:28:16 +02:00
7a45fa8df8 DOC: Updated Readme.md 2020-04-02 10:47:05 +02:00
Oliver Bründler
a0464c6a9d DOC: Updated Readme.md 2019-12-19 07:57:00 +01:00
Oliver Bruendler
5390c0c3c0 BUGFIX: Workaround for ISE tools implementing memory as FFs in case of 1 stream 2019-11-25 10:23:36 +01:00
Oliver Bruendler
cec193edca DEVEL: Updated documentation for release 2019-11-19 10:58:25 +01:00
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
35 changed files with 3716 additions and 2923 deletions

View File

@@ -1,3 +1,19 @@
## 1.2.3
* Doc
* Changed repository mantainer
## 1.2.2
* Bugfixes
* Workaround for ISE tools implementing memory as FFs in case of 1 stream
## 1.2.1
* Bugfixes
* Optimized timing between input FIFO and DMA
* Fix data unwrapping in driver
* Corrected several issues in documentation
* Made driver C++ tolerant
* Made code working for only one streamgit
## 1.2.0
* First Open Source Release (older versions not kept in history)
* Added license and copyright headers

View File

@@ -1,7 +1,10 @@
# General Information
## Maintainer
Oliver Bründler [oliver.bruendler@psi.ch]
Daniele Felici [daniele.felici@psi.ch]
## Author
Oliver Bründler [oli.bruendler@gmx.ch]
## License
This library is published under [PSI HDL Library License](License.txt), which is [LGPL](LGPL2_1.txt) plus some additional exceptions to clarify the LGPL terms in the context of firmware development.
@@ -30,8 +33,8 @@ Alternatively the repository [psi\_fpga\_all](https://github.com/paulscherrerins
* TCL
* [PsiSim](https://github.com/paulscherrerinstitute/PsiSim) (2.1.0 or higher, for development only)
* VHDL
* [psi\_common](https://github.com/paulscherrerinstitute/psi_common) (2.5.0 or higher)
* [psi\_tb](https://github.com/paulscherrerinstitute/psi_tb) (2.2.2 or higher, for development only)
* [psi\_common](https://github.com/paulscherrerinstitute/psi_common) (3.0.0 or higher)
* [psi\_tb](https://github.com/paulscherrerinstitute/psi_tb) (3.0.0 or higher, for development only)
* [**psi\_multi\_stream\_daq**](https://github.com/paulscherrerinstitute/psi_multi_stream_daq)
<!-- END OF PARSED SECTION -->

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

@@ -8,448 +8,472 @@
-- 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;
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;
AxiMaxBurstBeats_g : integer range 1 to 256 := 256;
AxiMaxOpenTrasactions_g : natural range 1 to 8 := 8;
AxiFifoDepth_g : natural := 1024;
-- Axi Slave
AxiSlaveIdWidth_g : integer := 0
);
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_ArId : in std_logic_vector(AxiSlaveIdWidth_g-1 downto 0);
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_RId : out std_logic_vector(AxiSlaveIdWidth_g-1 downto 0);
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_AwId : in std_logic_vector(AxiSlaveIdWidth_g-1 downto 0);
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_BId : out std_logic_vector(AxiSlaveIdWidth_g-1 downto 0);
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
);
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
IntDataWidth_g : positive := 64;
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;
AxiMaxBurstBeats_g : integer range 1 to 256 := 256;
AxiMaxOpenTrasactions_g : natural range 1 to 8 := 8;
AxiFifoDepth_g : natural := 1024;
-- Axi Slave
AxiSlaveIdWidth_g : integer := 0
);
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_ArId : in std_logic_vector(AxiSlaveIdWidth_g - 1 downto 0);
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_RId : out std_logic_vector(AxiSlaveIdWidth_g - 1 downto 0);
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_AwId : in std_logic_vector(AxiSlaveIdWidth_g - 1 downto 0);
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_BId : out std_logic_vector(AxiSlaveIdWidth_g - 1 downto 0);
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
-- Config Arrays with correct size
constant StreamWidth_c : t_ainteger(0 to Streams_g-1) := StreamWidth_g(0 to Streams_g-1);
constant StreamPrio_c : t_ainteger(0 to Streams_g-1) := StreamPrio_g(0 to Streams_g-1);
constant StreamBuffer_c : t_ainteger(0 to Streams_g-1) := StreamBuffer_g(0 to Streams_g-1);
constant StreamTimeout_c : t_areal(0 to Streams_g-1) := StreamTimeout_g(0 to Streams_g-1);
constant StreamClkFreq_c : t_areal(0 to Streams_g-1) := StreamClkFreq_g(0 to Streams_g-1);
constant StreamTsFifoDepth_c : t_ainteger(0 to Streams_g-1) := StreamTsFifoDepth_g(0 to Streams_g-1);
constant StreamUseTs_c : t_abool(0 to Streams_g-1) := StreamUseTs_g(0 to Streams_g-1);
-- Config Arrays with correct size
constant StreamWidth_c : t_ainteger(0 to Streams_g - 1) := StreamWidth_g(0 to Streams_g - 1);
constant StreamPrio_c : t_ainteger(0 to Streams_g - 1) := StreamPrio_g(0 to Streams_g - 1);
constant StreamBuffer_c : t_ainteger(0 to Streams_g - 1) := StreamBuffer_g(0 to Streams_g - 1);
constant StreamTimeout_c : t_areal(0 to Streams_g - 1) := StreamTimeout_g(0 to Streams_g - 1);
constant StreamClkFreq_c : t_areal(0 to Streams_g - 1) := StreamClkFreq_g(0 to Streams_g - 1);
constant StreamTsFifoDepth_c : t_ainteger(0 to Streams_g - 1) := StreamTsFifoDepth_g(0 to Streams_g - 1);
constant StreamUseTs_c : t_abool(0 to Streams_g - 1) := StreamUseTs_g(0 to Streams_g - 1);
-- 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)(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) 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(IntDataWidth_g-1 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);
signal Cfg_ToDisable : std_logic_vector(Streams_g -1 downto 0);
signal Cfg_FrameTo : std_logic_vector(Streams_g -1 downto 0);
signal AWCache : t_aslv4(2 downto 0) := (others => (others => '0'));
signal AWProt : t_aslv3(2 downto 0) := (others => (others => '0'));
signal ARCache : t_aslv4(2 downto 0) := (others => (others => '0'));
signal ARProt : t_aslv3(2 downto 0) := (others => (others => '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
-- 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,
AxiSlaveIdWidth_g => AxiSlaveIdWidth_g
)
port map (
S_Axi_Aclk => S_Axi_Aclk,
S_Axi_Aresetn => S_Axi_Aresetn,
S_Axi_ArId => S_Axi_ArId,
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_RId => S_Axi_RId,
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_AwId => S_Axi_AwId,
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_BId => S_Axi_BId,
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
);
M_Axi_Areset <= not M_Axi_Aresetn;
S_Axi_Areset <= not S_Axi_Aresetn;
--------------------------------------------
-- Input Logic Instantiation
--------------------------------------------
g_input : for str in 0 to Streams_g-1 generate
signal InRst : std_logic;
signal StrInput : std_logic_vector(StreamWidth_c(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_c(str),
StreamBuffer_g => StreamBuffer_c(str),
StreamTimeout_g => StreamTimeout_c(str),
StreamClkFreq_g => StreamClkFreq_c(str),
StreamTsFifoDepth_g => StreamTsFifoDepth_c(str),
StreamUseTs_g => StreamUseTs_c(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_c,
StreamWidth_g => StreamWidth_c,
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
);
-- Sync quasi static vecctors
sync_apc_reg : process(M_Axi_Aclk)
begin
if rising_edge(M_Axi_Aclk) then
for i in 1 to 2 loop
AWProt(i) <= AWProt(i-1);
AWCache(i) <= AWCache(i-1);
ARProt(i) <= ARProt(i-1);
ARCache(i) <= ARCache(i-1);
end loop;
end if;
end process;
M_Axi_AwCache <= AWCache(2);
M_Axi_AwProt <= AWProt(2);
M_Axi_ArCache <= ARCache(2);
M_Axi_ArProt <= ARProt(2);
--------------------------------------------
-- 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 => AxiMaxBurstBeats_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;
--------------------------------------------
-- Register Interface
--------------------------------------------
i_reg : entity work.psi_ms_daq_reg_axi
generic map(
Streams_g => Streams_g,
MaxWindows_g => MaxWindows_g,
AxiSlaveIdWidth_g => AxiSlaveIdWidth_g
)
port map(
S_Axi_Aclk => S_Axi_Aclk,
S_Axi_Aresetn => S_Axi_Aresetn,
S_Axi_ArId => S_Axi_ArId,
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_RId => S_Axi_RId,
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_AwId => S_Axi_AwId,
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_BId => S_Axi_BId,
S_Axi_BResp => S_Axi_BResp,
S_Axi_BValid => S_Axi_BValid,
S_Axi_BReady => S_Axi_BReady,
IrqOut => Irq,
AWCache => AWCache(0),
AWProt => AWProt(0),
ARCache => ARCache(0),
ARProt => ARProt(0),
PostTrig => Cfg_PostTrig,
Arm => Cfg_Arm,
IsArmed => Stat_IsArmed,
IsRecording => Stat_IsRecording,
RecMode => Cfg_RecMode,
ToDisable => Cfg_ToDisable,
FrameTo => Cfg_FrameTo,
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_c(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_c(str),
StreamBuffer_g => StreamBuffer_c(str),
StreamTimeout_g => StreamTimeout_c(str),
StreamClkFreq_g => StreamClkFreq_c(str),
StreamTsFifoDepth_g => StreamTsFifoDepth_c(str),
StreamUseTs_g => StreamUseTs_c(str),
IntDataWidth_g => IntDataWidth_g
)
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),
ToDisable => Cfg_ToDisable(str),
FrameTo => Cfg_FrameTo(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_c,
StreamWidth_g => StreamWidth_c,
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,
IntDataWidth_g => IntDataWidth_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(
IntDataWidth_g => IntDataWidth_g,
AxiDataWidth_g => AxiDataWidth_g,
AxiMaxBeats_g => AxiMaxBurstBeats_g,
AxiMaxOpenTrasactions_g => AxiMaxOpenTrasactions_g,
MaxOpenCommands_g => max(2, Streams_g), -- ISE tools implement memory as FFs for one stream. Reason is unkown, so we always implement two streams for resource optimization reasons.
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 => open, --M_Axi_AwCache
M_Axi_AwProt => open, --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 => open, --M_Axi_ArCache
M_Axi_ArProt => open, --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;

View File

@@ -8,217 +8,204 @@
-- Libraries
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_math_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
);
generic(
IntDataWidth_g : positive := 64;
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(IntDataWidth_g - 1 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;
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);
Rst <= not Rst_n;
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;
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,
ram_style_g => "distributed"
)
port map(
clk_i => Clk,
rst_i => Rst,
dat_i => InfoFifoIn,
vld_i => Cmd_Vld,
rdy_o => Cmd_Rdy,
dat_o => InfoFifoOut,
vld_o => WrCmdFifo_Vld,
rdy_i => WrCmdFifo_Rdy
);
WrCmdFifo_Addr <= InfoFifoOut(CommandAddrRng_c);
WrCmdFifo_Size <= InfoFifoOut(CommandSizeRng_c);
i_axi : entity work.psi_common_axi_master_full
generic map(
axi_addr_width_g => 32,
axi_data_width_g => AxiDataWidth_g,
axi_max_beats_g => AxiMaxBeats_g,
axi_max_open_trasactions_g => AxiMaxOpenTrasactions_g,
user_transaction_size_bits_g => 32,
data_fifo_depth_g => DataFifoDepth_g,
data_width_g => IntDataWidth_g,
impl_read_g => false,
impl_write_g => true,
ram_behavior_g => RamBehavior_g
)
port map(
-- Control Signals
m_axi_aclk => Clk,
m_axi_aresetn => Rst_n,
-- User Command Interface Write
cmd_wr_addr_i => WrCmdFifo_Addr,
cmd_wr_size_i => WrCmdFifo_Size,
cmd_wr_low_lat_i => '0',
cmd_wr_vld_i => WrCmdFifo_Vld,
cmd_wr_rdy_o => WrCmdFifo_Rdy,
-- User Command Interface Read (unused)
cmd_rd_addr_i => (others => '0'),
cmd_rd_size_o => (others => '0'),
cmd_rd_low_lat_i => '0',
cmd_rd_vld_i => '0',
cmd_rd_rdy_o => open,
-- Write Data
wr_dat_i => Dat_Data,
wr_vld_i => Dat_Vld,
wr_rdy_o => Dat_Rdy,
-- Read Data (unused)
rd_dat_o => open,
rd_vld_o => open,
rd_rdy_i => '0',
-- Response
wr_done_o => DoneI,
wr_error_o => ErrorI,
rd_done_o => open,
rd_error_o => 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

@@ -13,14 +13,14 @@
-- Libraries
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_logic_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_ms_daq_pkg.all;
use work.psi_common_math_pkg.all;
use work.psi_common_logic_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_ms_daq_pkg.all;
------------------------------------------------------------------------------
-- Entity Declaration
@@ -29,368 +29,372 @@ library work;
-- $$ processes=control,input,mem_cmd,mem_dat $$
-- $$ tbpkg=work.psi_tb_txt_util,work.psi_tb_compare_pkg,work.psi_tb_activity_pkg $$
entity psi_ms_daq_daq_dma is
generic (
Streams_g : positive range 1 to 32 := 4 -- $$ constant=4 $$
);
port (
-- Control signals
Clk : in std_logic; -- $$ type=clk; freq=200e6; proc=control,input,mem_dat,mem_cmd $$
Rst : in std_logic; -- $$ type=rst; clk=Clk; proc=control $$
generic(
Streams_g : positive range 1 to 32 := 4; -- $$ constant=4 $$
IntDataWidth_g : positive := 64 -- $$ constant=64 $$
);
port(
-- Control signals
Clk : in std_logic; -- $$ type=clk; freq=200e6; proc=control,input,mem_dat,mem_cmd $$
Rst : in std_logic; -- $$ type=rst; clk=Clk; proc=control $$
-- DAQ Statemachione Connections
DaqSm_Cmd : in DaqSm2DaqDma_Cmd_t; -- $$ proc=control $$
DaqSm_Cmd_Vld : in std_logic; -- $$ proc=control $$
DaqSm_Resp : out DaqDma2DaqSm_Resp_t; -- $$ proc=control $$
DaqSm_Resp_Vld : out std_logic; -- $$ proc=control $$
DaqSm_Resp_Rdy : in std_logic; -- $$ proc=control $$
DaqSm_HasLast : out std_logic_vector(Streams_g-1 downto 0); -- $$ proc=control $$
-- Input handling connections
Inp_Vld : in std_logic_vector(Streams_g-1 downto 0); -- $$ proc=input $$
Inp_Rdy : out std_logic_vector(Streams_g-1 downto 0); -- $$ proc=input $$
Inp_Data : in Input2Daq_Data_a(Streams_g-1 downto 0); -- $$ proc=input $$
-- Memory interface connections
Mem_CmdAddr : out std_logic_vector(31 downto 0); -- $$ proc=mem_cmd $$
Mem_CmdSize : out std_logic_vector(31 downto 0); -- $$ proc=mem_cmd $$
Mem_CmdVld : out std_logic; -- $$ proc=mem_cmd $$
Mem_CmdRdy : in std_logic; -- $$ proc=mem_cmd $$
Mem_DatData : out std_logic_vector(63 downto 0); -- $$ proc=mem_dat $$
Mem_DatVld : out std_logic; -- $$ proc=mem_dat $$
Mem_DatRdy : in std_logic -- $$ proc=mem_dat $$
);
-- DAQ Statemachione Connections
DaqSm_Cmd : in DaqSm2DaqDma_Cmd_t; -- $$ proc=control $$
DaqSm_Cmd_Vld : in std_logic; -- $$ proc=control $$
DaqSm_Resp : out DaqDma2DaqSm_Resp_t; -- $$ proc=control $$
DaqSm_Resp_Vld : out std_logic; -- $$ proc=control $$
DaqSm_Resp_Rdy : in std_logic; -- $$ proc=control $$
DaqSm_HasLast : out std_logic_vector(Streams_g - 1 downto 0); -- $$ proc=control $$
-- Input handling connections
Inp_Vld : in std_logic_vector(Streams_g - 1 downto 0); -- $$ proc=input $$
Inp_Rdy : out std_logic_vector(Streams_g - 1 downto 0); -- $$ proc=input $$
Inp_Data : in Input2Daq_Data_a(Streams_g - 1 downto 0)(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0)); -- $$ proc=input $$
-- Memory interface connections
Mem_CmdAddr : out std_logic_vector(31 downto 0); -- $$ proc=mem_cmd $$
Mem_CmdSize : out std_logic_vector(31 downto 0); -- $$ proc=mem_cmd $$
Mem_CmdVld : out std_logic; -- $$ proc=mem_cmd $$
Mem_CmdRdy : in std_logic; -- $$ proc=mem_cmd $$
Mem_DatData : out std_logic_vector(IntDataWidth_g-1 downto 0); -- $$ proc=mem_dat $$
Mem_DatVld : out std_logic; -- $$ proc=mem_dat $$
Mem_DatRdy : in std_logic -- $$ proc=mem_dat $$
);
end entity;
------------------------------------------------------------------------------
-- Architecture Declaration
------------------------------------------------------------------------------
architecture rtl of psi_ms_daq_daq_dma is
-- Constants
constant BufferFifoDepth_c : integer := 32;
-- Constants
constant BufferFifoDepth_c : integer := 32;
-- Component Connection Signals
signal CmdFifo_Level_Dbg : std_logic_vector(log2ceil(Streams_g) 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_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);
signal DatFifo_AlmFull : std_logic;
signal Rem_RdBytes : std_logic_vector(2 downto 0);
signal Rem_Data : std_logic_vector(63 downto 0);
signal Rem_Trigger : std_logic;
signal Rem_Last : std_logic;
-- Types
type State_t is (Idle_s, RemRd1_s, RemRd2_s, Transfer_s, Done_s, Cmd_s);
-- 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);
constant IntDataBytes_c : positive := IntDataWidth_g/8;
constant BytesWidth_c : positive := log2ceil(IntDataBytes_c);
-- Component Connection Signals
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(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);
signal DatFifo_AlmFull : std_logic;
signal Rem_RdBytes : std_logic_vector(BytesWidth_c - 1 downto 0);
signal Rem_Data : std_logic_vector(IntDataWidth_g - 1 downto 0);
signal Rem_Trigger : std_logic;
signal Rem_Last : std_logic;
signal Rem_Data_Fifo_In : std_logic_vector(BytesWidth_c + IntDataWidth_g + 1 downto 0);
signal Rem_Data_Fifo_Out : std_logic_vector(BytesWidth_c + IntDataWidth_g + 1 downto 0);
-- Types
type State_t is (Idle_s, RemRd1_s, RemRd2_s, Transfer_s, Done_s, Cmd_s);
-- Two process method
type two_process_r is record
CmdFifo_Rdy : std_logic;
RspFifo_Vld : std_logic;
RspFifo_Data : DaqDma2DaqSm_Resp_t;
Mem_DataVld : std_logic;
StreamStdlv : std_logic_vector(StreamBits_c - 1 downto 0);
RemWen : std_logic;
RemWrBytes : std_logic_vector(BytesWidth_c - 1 downto 0);
RemData : std_logic_vector(IntDataWidth_g - 1 downto 0);
RemTrigger : std_logic;
RemLast : std_logic;
RemWrTrigger : std_logic;
RemWrLast : std_logic;
State : State_t;
HndlMaxSize : unsigned(15 downto 0);
RdBytes : unsigned(15 downto 0);
WrBytes : unsigned(15 downto 0);
HndlStream : integer range 0 to MaxStreams_c - 1;
HndlAddress : std_logic_vector(31 downto 0);
UpdateLast : std_logic;
HndlSft : unsigned(BytesWidth_c-1 downto 0);
FirstDma : std_logic_vector(Streams_g - 1 downto 0);
Mem_CmdVld : std_logic;
Trigger : std_logic;
Last : std_logic;
DataSft : std_logic_vector(2*IntDataWidth_g - 1 downto 0);
NextDone : std_logic;
DataWritten : std_logic;
HasLast : std_logic_vector(Streams_g - 1 downto 0);
end record;
signal r, r_next : two_process_r;
-- Two process method
type two_process_r is record
CmdFifo_Rdy : std_logic;
RspFifo_Vld : std_logic;
RspFifo_Data : DaqDma2DaqSm_Resp_t;
Mem_DataVld : std_logic;
StreamStdlv : std_logic_vector(log2ceil(Streams_g)-1 downto 0);
RemWen : std_logic;
RemWrBytes : std_logic_vector(2 downto 0);
RemData : std_logic_vector(63 downto 0);
RemTrigger : std_logic;
RemLast : std_logic;
RemWrTrigger : std_logic;
RemWrLast : std_logic;
State : State_t;
HndlMaxSize : unsigned(15 downto 0);
RdBytes : unsigned(15 downto 0);
WrBytes : unsigned(15 downto 0);
HndlStream : integer range 0 to MaxStreams_c-1;
HndlAddress : std_logic_vector(31 downto 0);
UpdateLast : std_logic;
HndlSft : unsigned(2 downto 0);
FirstDma : std_logic_vector(Streams_g-1 downto 0);
Mem_CmdVld : std_logic;
Trigger : std_logic;
Last : std_logic;
DataSft : std_logic_vector(127 downto 0);
NextDone : std_logic;
DataWritten : std_logic;
HasLast : std_logic_vector(Streams_g-1 downto 0);
end record;
signal r, r_next : two_process_r;
begin
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process( r, DaqSm_Cmd, DaqSm_Cmd_Vld, DaqSm_Resp_Rdy, Inp_Vld, Inp_Data, Mem_CmdRdy, Mem_DatRdy,
CmdFifo_Cmd, CmdFifo_Vld, DatFifo_AlmFull, Rem_RdBytes, Rem_Data, Rem_Trigger, Rem_Last)
variable v : two_process_r;
variable ThisByte_v : std_logic_vector(7 downto 0);
variable RemSft_v : integer range 0 to 7;
begin
-- *** Hold variables stable ***
v := r;
-- *** Default Values ***
v.CmdFifo_Rdy := '0';
Inp_Rdy <= (others => '0');
v.Mem_DataVld := '0';
v.RspFifo_Vld := '0';
v.RemWen := '0';
v.UpdateLast := '0';
-- *** State Machine ***
case r.State is
when Idle_s =>
v.HndlMaxSize := unsigned(CmdFifo_Cmd.MaxSize);
v.HndlStream := CmdFifo_Cmd.Stream;
v.StreamStdlv := std_logic_vector(to_unsigned(CmdFifo_Cmd.Stream, v.StreamStdlv'length));
v.HndlAddress := CmdFifo_Cmd.Address;
v.Trigger := '0';
v.Last := '0';
if CmdFifo_Vld = '1' then
v.CmdFifo_Rdy := '1';
v.State := RemRd1_s;
end if;
when RemRd1_s =>
v.State := RemRd2_s;
when RemRd2_s =>
-- Prevent RAM data from before reset to have an influence
v.WrBytes := (others => '0');
if r.FirstDma(r.HndlStream) = '1' then
v.HndlSft := (others => '0');
v.RdBytes := (others => '0');
v.DataSft := (others => '0');
v.RemTrigger := '0';
v.RemLast := '0';
else
v.HndlSft := unsigned(Rem_RdBytes);
v.DataSft(127 downto 64) := Rem_Data;
v.RdBytes := resize(unsigned(Rem_RdBytes), v.RdBytes'length);
v.RemTrigger := Rem_Trigger;
v.RemLast := Rem_Last;
end if;
v.FirstDma(r.HndlStream) := '0';
v.State := Transfer_s;
v.NextDone := '0';
v.DataWritten := '0';
when Transfer_s =>
-- TF done because of maximum size reached
if r.WrBytes >= r.HndlMaxSize then
v.State := Done_s;
elsif DatFifo_AlmFull = '0' then
if r.NextDone = '0' and Inp_Vld(r.HndlStream) = '1' and r.RemLast = '0' then
v.RdBytes := r.RdBytes + unsigned(Inp_Data(r.HndlStream).Bytes);
end if;
v.WrBytes := r.WrBytes + 8;
-- Combinatorial handling because of fall-through interface at input
if r.RdBytes < r.HndlMaxSize and r.NextDone = '0' and r.RemLast = '0' then
Inp_Rdy(r.HndlStream) <= '1';
end if;
-- Handling of last frame
if (Inp_Data(r.HndlStream).Last = '1') or (r.RemLast = '1') then
-- Do one more word if not all data can be transferred in the current beat (NextDone = 1)
if (r.HndlSft + unsigned(Inp_Data(r.HndlStream).Bytes) <= 8) or (r.RemLast = '1') then
v.State := Done_s;
else
v.NextDone := '1';
end if;
if (Inp_Data(r.HndlStream).IsTrig = '1') or (r.RemTrigger = '1') then
v.Trigger :='1';
end if;
v.Last := '1';
end if;
if r.NextDone = '1' or Inp_Vld(r.HndlStream) = '0' then
v.State := Done_s;
end if;
-- Data handling
v.DataSft(63 downto 0) := r.DataSft(127 downto 64);
v.DataSft(8*to_integer(r.HndlSft)+63 downto 8*to_integer(r.HndlSft)) := Inp_Data(r.HndlStream).Data;
if Inp_Vld(r.HndlStream) = '1' or r.HndlSft /= 0 then
v.Mem_DataVld := '1';
v.DataWritten := '1';
end if;
end if;
when Done_s =>
RemSft_v := to_integer(resize(r.HndlMaxSize, 3));
v.RemWrTrigger := '0';
v.RemWrLast := '0';
if r.HndlMaxSize < r.RdBytes then
v.RemWrBytes := std_logic_vector(resize(r.RdBytes - r.HndlMaxSize, v.RemWrBytes'length));
v.RdBytes := r.HndlMaxSize;
v.RemWrTrigger := r.Trigger;
v.RemWrLast := r.Last;
v.HasLast(r.HndlStream) := r.Last;
else
v.RemWrBytes := (others => '0');
v.HasLast(r.HndlStream) := '0';
end if;
v.RemData := v.DataSft(8*RemSft_v+63 downto 8*RemSft_v);
v.State := Cmd_s;
if r.DataWritten = '1' then
v.Mem_CmdVld := '1';
end if;
v.RemWen := '1';
when Cmd_s =>
if Mem_CmdRdy = '1' or r.Mem_CmdVld = '0' then
v.State := Idle_s;
v.Mem_CmdVld := '0';
v.RspFifo_Vld := '1';
v.RspFifo_Data.Size := std_logic_vector(r.RdBytes);
-- Only mark as trigger if all samples are completely written to memory (no remaining samples in REM RAM)
if (unsigned(r.RemWrBytes) = 0) and (r.Trigger = '1') then
v.RspFifo_Data.Trigger := '1';
else
v.RspFifo_Data.Trigger := '0';
end if;
v.RspFifo_Data.Stream := r.HndlStream;
end if;
when others => null;
end case;
-- *** Assign to signal ***
r_next <= v;
end process;
-- *** Registered Outputs ***
Mem_CmdAddr <= r.HndlAddress;
Mem_CmdSize(r.RdBytes'range) <= std_logic_vector(r.RdBytes);
Mem_CmdSize(Mem_CmdSize'high downto r.RdBytes'high+1) <= (others => '0');
Mem_CmdVld <= r.Mem_CmdVld;
DaqSm_HasLast <= r.HasLast;
--------------------------------------------
-- Sequential Process
--------------------------------------------
p_seq : process(Clk)
begin
if rising_edge(Clk) then
r <= r_next;
if Rst = '1' then
r.CmdFifo_Rdy <= '0';
r.RspFifo_Vld <= '0';
r.Mem_DataVld <= '0';
r.RemWen <= '0';
r.State <= Idle_s;
r.FirstDma <= (others => '1');
r.Mem_CmdVld <= '0';
r.HasLast <= (others => '0');
end if;
end if;
end process;
--------------------------------------------
-- Component Instantiation
--------------------------------------------
-- *** Command FIFO ***
CmdFifo_InData <= DaqSm2DaqDma_Cmd_ToStdlv(DaqSm_Cmd);
i_fifocmd : entity work.psi_common_sync_fifo
generic map (
Width_g => DaqSm2DaqDma_Cmd_Size_c,
Depth_g => Streams_g,
RamStyle_g => "distributed",
RamBehavior_g => "RBW"
)
port map (
Clk => Clk,
Rst => Rst,
InData => CmdFifo_InData,
InVld => DaqSm_Cmd_Vld,
OutData => CmdFifo_OutData,
OutVld => CmdFifo_Vld,
OutRdy => r.CmdFifo_Rdy,
OutLevel => CmdFifo_Level_Dbg
);
CmdFifo_Cmd <= DaqSm2DaqDma_Cmd_FromStdlv(CmdFifo_OutData);
-- *** Response FIFO ***
-- Ready not required for system reasons: There is never more commands open than streams.
RspFifo_InData <= DaqDma2DaqSm_Resp_ToStdlv(r.RspFifo_Data);
i_fiforsp : entity work.psi_common_sync_fifo
generic map (
Width_g => DaqDma2DaqSm_Resp_Size_c,
Depth_g => Streams_g,
RamStyle_g => "distributed",
RamBehavior_g => "RBW"
)
port map (
Clk => Clk,
Rst => Rst,
InData => RspFifo_InData,
InVld => r.RspFifo_Vld,
OutData => RspFifo_OutData,
OutVld => DaqSm_Resp_Vld,
OutRdy => DaqSm_Resp_Rdy,
OutLevel => RspFifo_Level_Dbg
);
DaqSm_Resp <= DaqDme2DaqSm_Resp_FromStdlv(RspFifo_OutData);
-- *** Buffer FIFO ***
-- This FIFO allows buffering data for the time the state machine requires to react on a "memory interface not ready for more data" situation.
-- As a result, the backpressure must not handled in the complete pipeline of this block.
-- Rdy is not required since the data pipeline is stopped based on the almost full flag
i_fifodata : entity work.psi_common_sync_fifo
generic map (
Width_g => 64,
Depth_g => BufferFifoDepth_c,
AlmFullOn_g => true,
AlmFullLevel_g => BufferFifoDepth_c/2,
RamStyle_g => "distributed",
RamBehavior_g => "RBW"
)
port map (
Clk => Clk,
Rst => Rst,
InData => r.DataSft(63 downto 0),
InVld => r.Mem_DataVld,
OutData => Mem_DatData,
OutVld => Mem_DatVld,
OutRdy => Mem_DatRdy,
OutLevel => DatFifo_Level_Dbg,
AlmFull => DatFifo_AlmFull
);
-- *** Remaining Data RAM ***
i_remram : entity work.psi_common_sdp_ram
generic map (
Depth_g => Streams_g,
Width_g => 1+1+3+64,
IsAsync_g => false,
RamStyle_g => "distributed",
Behavior_g => "RBW"
)
port map (
Clk => Clk,
RdClk => Rst,
WrAddr => r.StreamStdlv,
Wr => r.RemWen,
WrData(68) => r.RemWrLast,
WrData(67) => r.RemWrTrigger,
WrData(66 downto 64) => r.RemWrBytes,
WrData(63 downto 0) => r.RemData,
RdAddr => r.StreamStdlv,
RdDAta(68) => Rem_Last,
RdData(67) => Rem_Trigger,
RdData(66 downto 64) => Rem_RdBytes,
RdData(63 downto 0) => Rem_Data
);
end;
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process(r, DaqSm_Cmd, DaqSm_Cmd_Vld, DaqSm_Resp_Rdy, Inp_Vld, Inp_Data, Mem_CmdRdy, Mem_DatRdy, CmdFifo_Cmd, CmdFifo_Vld, DatFifo_AlmFull, Rem_RdBytes, Rem_Data, Rem_Trigger, Rem_Last)
variable v : two_process_r;
variable ThisByte_v : std_logic_vector(7 downto 0);
variable RemSft_v : integer range 0 to 7;
begin
-- *** Hold variables stable ***
v := r;
-- *** Default Values ***
v.CmdFifo_Rdy := '0';
Inp_Rdy <= (others => '0');
v.Mem_DataVld := '0';
v.RspFifo_Vld := '0';
v.RemWen := '0';
v.UpdateLast := '0';
-- *** State Machine ***
case r.State is
when Idle_s =>
v.HndlMaxSize := unsigned(CmdFifo_Cmd.MaxSize);
v.HndlStream := CmdFifo_Cmd.Stream;
v.StreamStdlv := std_logic_vector(to_unsigned(CmdFifo_Cmd.Stream, v.StreamStdlv'length));
v.HndlAddress := CmdFifo_Cmd.Address;
v.Trigger := '0';
v.Last := '0';
if CmdFifo_Vld = '1' then
v.CmdFifo_Rdy := '1';
v.State := RemRd1_s;
end if;
when RemRd1_s =>
v.State := RemRd2_s;
when RemRd2_s =>
-- Prevent RAM data from before reset to have an influence
v.WrBytes := (others => '0');
if r.FirstDma(r.HndlStream) = '1' then
v.HndlSft := (others => '0');
v.RdBytes := (others => '0');
v.DataSft := (others => '0');
v.RemTrigger := '0';
v.RemLast := '0';
else
v.HndlSft := unsigned(Rem_RdBytes);
v.DataSft(2*IntDataWidth_g - 1 downto IntDataWidth_g) := Rem_Data;
v.RdBytes := resize(unsigned(Rem_RdBytes), v.RdBytes'length);
v.RemTrigger := Rem_Trigger;
v.RemLast := Rem_Last;
end if;
v.FirstDma(r.HndlStream) := '0';
v.State := Transfer_s;
v.NextDone := '0';
v.DataWritten := '0';
when Transfer_s =>
-- TF done because of maximum size reached
if r.WrBytes >= r.HndlMaxSize then
v.State := Done_s;
elsif DatFifo_AlmFull = '0' then
if r.NextDone = '0' and Inp_Vld(r.HndlStream) = '1' and r.RemLast = '0' then
v.RdBytes := r.RdBytes + unsigned(Inp_Data(r.HndlStream).Bytes);
end if;
v.WrBytes := r.WrBytes + IntDataBytes_c;
-- Combinatorial handling because of fall-through interface at input
if r.RdBytes < r.HndlMaxSize and r.NextDone = '0' and r.RemLast = '0' then
Inp_Rdy(r.HndlStream) <= '1';
end if;
-- Handling of last frame
if (Inp_Data(r.HndlStream).Last = '1') or (r.RemLast = '1') then
-- Do one more word if not all data can be transferred in the current beat (NextDone = 1)
if (r.HndlSft + unsigned(Inp_Data(r.HndlStream).Bytes) <= IntDataBytes_c) or (r.RemLast = '1') then
v.State := Done_s;
else
v.NextDone := '1';
end if;
if (Inp_Data(r.HndlStream).IsTrig = '1') or (r.RemTrigger = '1') then
v.Trigger := '1';
end if;
v.Last := '1';
end if;
if r.NextDone = '1' or Inp_Vld(r.HndlStream) = '0' then
v.State := Done_s;
end if;
-- Data handling
v.DataSft(IntDataWidth_g - 1 downto 0) := r.DataSft(2*IntDataWidth_g - 1 downto IntDataWidth_g);
v.DataSft(8 * to_integer(r.HndlSft) + IntDataWidth_g - 1 downto 8 * to_integer(r.HndlSft)) := Inp_Data(r.HndlStream).Data;
if Inp_Vld(r.HndlStream) = '1' or r.HndlSft /= 0 then
v.Mem_DataVld := '1';
v.DataWritten := '1';
end if;
end if;
when Done_s =>
RemSft_v := to_integer(resize(r.HndlMaxSize, 3));
v.RemWrTrigger := '0';
v.RemWrLast := '0';
if r.HndlMaxSize < r.RdBytes then
v.RemWrBytes := std_logic_vector(resize(r.RdBytes - r.HndlMaxSize, v.RemWrBytes'length));
v.RdBytes := r.HndlMaxSize;
v.RemWrTrigger := r.Trigger;
v.RemWrLast := r.Last;
v.HasLast(r.HndlStream) := r.Last;
else
v.RemWrBytes := (others => '0');
v.HasLast(r.HndlStream) := '0';
end if;
v.RemData := v.DataSft(8 * RemSft_v + IntDataWidth_g - 1 downto 8 * RemSft_v);
v.State := Cmd_s;
if r.DataWritten = '1' then
v.Mem_CmdVld := '1';
end if;
v.RemWen := '1';
when Cmd_s =>
if Mem_CmdRdy = '1' or r.Mem_CmdVld = '0' then
v.State := Idle_s;
v.Mem_CmdVld := '0';
v.RspFifo_Vld := '1';
v.RspFifo_Data.Size := std_logic_vector(r.RdBytes);
-- Only mark as trigger if all samples are completely written to memory (no remaining samples in REM RAM)
if (unsigned(r.RemWrBytes) = 0) and (r.Trigger = '1') then
v.RspFifo_Data.Trigger := '1';
else
v.RspFifo_Data.Trigger := '0';
end if;
v.RspFifo_Data.Stream := r.HndlStream;
end if;
when others => null;
end case;
-- *** Assign to signal ***
r_next <= v;
end process;
-- *** Registered Outputs ***
Mem_CmdAddr <= r.HndlAddress;
Mem_CmdSize(r.RdBytes'range) <= std_logic_vector(r.RdBytes);
Mem_CmdSize(Mem_CmdSize'high downto r.RdBytes'high + 1) <= (others => '0');
Mem_CmdVld <= r.Mem_CmdVld;
DaqSm_HasLast <= r.HasLast;
--------------------------------------------
-- Sequential Process
--------------------------------------------
p_seq : process(Clk)
begin
if rising_edge(Clk) then
r <= r_next;
if Rst = '1' then
r.CmdFifo_Rdy <= '0';
r.RspFifo_Vld <= '0';
r.Mem_DataVld <= '0';
r.RemWen <= '0';
r.State <= Idle_s;
r.FirstDma <= (others => '1');
r.Mem_CmdVld <= '0';
r.HasLast <= (others => '0');
end if;
end if;
end process;
--------------------------------------------
-- Component Instantiation
--------------------------------------------
-- *** Command FIFO ***
CmdFifo_InData <= DaqSm2DaqDma_Cmd_ToStdlv(DaqSm_Cmd);
i_fifocmd : entity work.psi_common_sync_fifo
generic map(
width_g => DaqSm2DaqDma_Cmd_Size_c,
depth_g => 2**StreamBits_c,
ram_style_g => "distributed",
ram_behavior_g => "RBW"
)
port map(
clk_i => Clk,
rst_i => Rst,
dat_i => CmdFifo_InData,
vld_i => DaqSm_Cmd_Vld,
dat_o => CmdFifo_OutData,
vld_o => CmdFifo_Vld,
rdy_i => r.CmdFifo_Rdy,
out_level_o => CmdFifo_Level_Dbg
);
CmdFifo_Cmd <= DaqSm2DaqDma_Cmd_FromStdlv(CmdFifo_OutData);
-- *** Response FIFO ***
-- Ready not required for system reasons: There is never more commands open than streams.
RspFifo_InData <= DaqDma2DaqSm_Resp_ToStdlv(r.RspFifo_Data);
i_fiforsp : entity work.psi_common_sync_fifo
generic map(
width_g => DaqDma2DaqSm_Resp_Size_c,
depth_g => 2**StreamBits_c,
ram_style_g => "distributed",
ram_behavior_g => "RBW"
)
port map(
clk_i => Clk,
rst_i => Rst,
dat_i => RspFifo_InData,
vld_i => r.RspFifo_Vld,
dat_o => RspFifo_OutData,
vld_o => DaqSm_Resp_Vld,
rdy_i => DaqSm_Resp_Rdy,
out_level_o => RspFifo_Level_Dbg
);
DaqSm_Resp <= DaqDme2DaqSm_Resp_FromStdlv(RspFifo_OutData);
-- *** Buffer FIFO ***
-- This FIFO allows buffering data for the time the state machine requires to react on a "memory interface not ready for more data" situation.
-- As a result, the backpressure must not handled in the complete pipeline of this block.
-- Rdy is not required since the data pipeline is stopped based on the almost full flag
i_fifodata : entity work.psi_common_sync_fifo
generic map(
width_g => IntDataWidth_g,
depth_g => BufferFifoDepth_c,
alm_full_on_g => true,
alm_full_level_g => BufferFifoDepth_c / 2,
ram_style_g => "distributed",
ram_behavior_g => "RBW"
)
port map(
clk_i => Clk,
rst_i => Rst,
dat_i => r.DataSft(IntDataWidth_g-1 downto 0),
vld_i => r.Mem_DataVld,
dat_o => Mem_DatData,
vld_o => Mem_DatVld,
rdy_i => Mem_DatRdy,
out_level_o => DatFifo_Level_Dbg,
alm_full_o => DatFifo_AlmFull
);
-- *** Remaining Data RAM ***
Rem_Data_Fifo_In(BytesWidth_c + IntDataWidth_g + 1) <= r.RemWrLast;
Rem_Data_Fifo_In(BytesWidth_c + IntDataWidth_g) <= r.RemWrTrigger;
Rem_Data_Fifo_In(BytesWidth_c + IntDataWidth_g - 1 downto IntDataWidth_g) <= r.RemWrBytes;
Rem_Data_Fifo_In(IntDataWidth_g - 1 downto 0) <= r.RemData;
i_remram : entity work.psi_common_sdp_ram
generic map(
depth_g => 2**StreamBits_c,
width_g => 1 + 1 + BytesWidth_c + IntDataWidth_g,
is_async_g => false,
ram_style_g => "distributed",
ram_behavior_g => "RBW"
)
port map(
wr_clk_i => Clk,
rd_clk_i => Rst,
wr_addr_i => r.StreamStdlv,
wr_i => r.RemWen,
wr_dat_i => Rem_Data_Fifo_In,
rd_addr_i => r.StreamStdlv,
rd_dat_o => Rem_Data_Fifo_Out
);
Rem_Last <= Rem_Data_Fifo_Out(BytesWidth_c + IntDataWidth_g + 1);
Rem_Trigger <= Rem_Data_Fifo_Out(BytesWidth_c + IntDataWidth_g);
Rem_RdBytes <= Rem_Data_Fifo_Out(BytesWidth_c + IntDataWidth_g - 1 downto IntDataWidth_g);
Rem_Data <= Rem_Data_Fifo_Out(IntDataWidth_g - 1 downto 0);
end;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,157 +8,153 @@
-- Libraries
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_math_pkg.all;
------------------------------------------------------------------------------
-- Package Header
------------------------------------------------------------------------------
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);
constant MaxStreamWidth_c : integer := 64;
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));
constant RecMode_TriggerMask_c : RecMode_t := std_logic_vector(to_unsigned(1, RecMode_t'length));
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);
Bytes : std_logic_vector(3 downto 0);
IsTo : std_logic;
IsTrig : std_logic;
end record;
type Input2Daq_Data_a is array (natural range <>) of Input2Daq_Data_t;
type DaqSm2DaqDma_Cmd_t is record
Address : std_logic_vector(31 downto 0);
MaxSize : std_logic_vector(15 downto 0);
Stream : integer range 0 to MaxStreams_c-1;
end record;
constant DaqSm2DaqDma_Cmd_Size_c : integer := 32+16+MaxStreamsBits_c;
function DaqSm2DaqDma_Cmd_ToStdlv( rec : DaqSm2DaqDma_Cmd_t) return std_logic_vector;
function DaqSm2DaqDma_Cmd_FromStdlv( stdlv : std_logic_vector) return DaqSm2DaqDma_Cmd_t;
type DaqDma2DaqSm_Resp_t is record
Size : std_logic_vector(15 downto 0);
Trigger : std_logic;
Stream : integer range 0 to MaxStreams_c-1;
end record;
constant DaqDma2DaqSm_Resp_Size_c : integer := 16+1+MaxStreamsBits_c;
function DaqDma2DaqSm_Resp_ToStdlv( rec : DaqDma2DaqSm_Resp_t) return std_logic_vector;
function DaqDme2DaqSm_Resp_FromStdlv( stdlv : std_logic_vector) return DaqDma2DaqSm_Resp_t;
type ToCtxStr_t is record
Stream : integer range 0 to MaxStreams_c-1;
Sel : std_logic_vector(1 downto 0);
Rd : std_logic;
WenLo : std_logic;
WenHi : std_logic;
WdatLo : std_logic_vector(31 downto 0);
WdatHi : std_logic_vector(31 downto 0);
end record;
constant CtxStr_Sel_ScfgBufstart_c : std_logic_vector(1 downto 0) := "00";
constant CtxStr_Sel_WinsizePtr_c : std_logic_vector(1 downto 0) := "01";
constant CtxStr_Sel_Winend_c : std_logic_vector(1 downto 0) := "10";
constant CtxStr_Sft_SCFG_RINGBUF_c : integer := 0;
constant CtxStr_Sft_SCFG_OVERWRITE_c : integer := 8;
constant CtxStr_Sft_SCFG_WINCNT_c : integer := 16;
constant CtxStr_Sft_SCFG_WINCUR_c : integer := 24;
type ToCtxWin_t is record
Stream : integer range 0 to MaxStreams_c-1;
Window : integer range 0 to MaxWindows_c-1;
Sel : std_logic_vector(0 downto 0);
Rd : std_logic;
WenLo : std_logic;
WenHi : std_logic;
WdatLo : std_logic_vector(31 downto 0);
WdatHi : std_logic_vector(31 downto 0);
end record;
constant CtxWin_Sel_WincntWinlast_c : std_logic_vector(0 downto 0) := "0";
constant CtxWin_Sel_WinTs_c : std_logic_vector(0 downto 0) := "1";
type FromCtx_t is record
RdatLo : std_logic_vector(31 downto 0);
RdatHi : std_logic_vector(31 downto 0);
end record;
type TmemRqst_t is record
ADD : std_logic_vector(23 downto 0);
DATW : std_logic_vector(63 downto 0);
ENA : std_logic;
WE : std_logic_vector(7 downto 0);
CS : std_logic_vector(1 downto 0);
end record;
constant TmemRqst_init_c : TmemRqst_t := ((others => '0'), (others => '0'), '0', (others => '0'), (others => '0'));
type TmemResp_t is record
DATR : std_logic_vector(63 downto 0);
BUSY : std_logic;
PIPE : std_logic_vector(1 downto 0);
end record;
end psi_ms_daq_pkg;
constant MaxStreams_c : integer := 32;
constant MaxWindows_c : integer := 32;
constant MaxStreamsBits_c : integer := log2ceil(MaxStreams_c);
constant MaxWindowsBits_c : integer := log2ceil(MaxWindows_c);
constant MaxStreamWidth_c : integer := 64;
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));
constant RecMode_TriggerMask_c : RecMode_t := std_logic_vector(to_unsigned(1, RecMode_t'length));
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;
Bytes : std_logic_vector;
IsTo : std_logic;
IsTrig : std_logic;
end record;
type Input2Daq_Data_a is array (natural range <>) of Input2Daq_Data_t;
type DaqSm2DaqDma_Cmd_t is record
Address : std_logic_vector(31 downto 0);
MaxSize : std_logic_vector(15 downto 0);
Stream : integer range 0 to MaxStreams_c - 1;
end record;
constant DaqSm2DaqDma_Cmd_Size_c : integer := 32 + 16 + MaxStreamsBits_c;
function DaqSm2DaqDma_Cmd_ToStdlv(rec : DaqSm2DaqDma_Cmd_t) return std_logic_vector;
function DaqSm2DaqDma_Cmd_FromStdlv(stdlv : std_logic_vector) return DaqSm2DaqDma_Cmd_t;
type DaqDma2DaqSm_Resp_t is record
Size : std_logic_vector(15 downto 0);
Trigger : std_logic;
Stream : integer range 0 to MaxStreams_c - 1;
end record;
constant DaqDma2DaqSm_Resp_Size_c : integer := 16 + 1 + MaxStreamsBits_c;
function DaqDma2DaqSm_Resp_ToStdlv(rec : DaqDma2DaqSm_Resp_t) return std_logic_vector;
function DaqDme2DaqSm_Resp_FromStdlv(stdlv : std_logic_vector) return DaqDma2DaqSm_Resp_t;
type ToCtxStr_t is record
Stream : integer range 0 to MaxStreams_c - 1;
Sel : std_logic_vector(1 downto 0);
Rd : std_logic;
WenLo : std_logic;
WenHi : std_logic;
WdatLo : std_logic_vector(31 downto 0);
WdatHi : std_logic_vector(31 downto 0);
end record;
constant CtxStr_Sel_ScfgBufstart_c : std_logic_vector(1 downto 0) := "00";
constant CtxStr_Sel_WinsizePtr_c : std_logic_vector(1 downto 0) := "01";
constant CtxStr_Sel_Winend_c : std_logic_vector(1 downto 0) := "10";
constant CtxStr_Sft_SCFG_RINGBUF_c : integer := 0;
constant CtxStr_Sft_SCFG_OVERWRITE_c : integer := 8;
constant CtxStr_Sft_SCFG_WINCNT_c : integer := 16;
constant CtxStr_Sft_SCFG_WINCUR_c : integer := 24;
type ToCtxWin_t is record
Stream : integer range 0 to MaxStreams_c - 1;
Window : integer range 0 to MaxWindows_c - 1;
Sel : std_logic_vector(0 downto 0);
Rd : std_logic;
WenLo : std_logic;
WenHi : std_logic;
WdatLo : std_logic_vector(31 downto 0);
WdatHi : std_logic_vector(31 downto 0);
end record;
constant CtxWin_Sel_WincntWinlast_c : std_logic_vector(0 downto 0) := "0";
constant CtxWin_Sel_WinTs_c : std_logic_vector(0 downto 0) := "1";
type FromCtx_t is record
RdatLo : std_logic_vector(31 downto 0);
RdatHi : std_logic_vector(31 downto 0);
end record;
type TmemRqst_t is record
ADD : std_logic_vector(23 downto 0);
DATW : std_logic_vector(63 downto 0);
ENA : std_logic;
WE : std_logic_vector(7 downto 0);
CS : std_logic_vector(1 downto 0);
end record;
constant TmemRqst_init_c : TmemRqst_t := ((others => '0'), (others => '0'), '0', (others => '0'), (others => '0'));
type TmemResp_t is record
DATR : std_logic_vector(63 downto 0);
BUSY : std_logic;
PIPE : std_logic_vector(1 downto 0);
end record;
end psi_ms_daq_pkg;
------------------------------------------------------------------------------
-- Package Body
------------------------------------------------------------------------------
package body psi_ms_daq_pkg is
-- *** DaqSm2DaqDma_Cmd ***
function DaqSm2DaqDma_Cmd_ToStdlv( rec : DaqSm2DaqDma_Cmd_t) return std_logic_vector is
variable stdlv : std_logic_vector(DaqSm2DaqDma_Cmd_Size_c-1 downto 0);
begin
stdlv(31 downto 0) := rec.Address;
stdlv(47 downto 32) := rec.MaxSize;
stdlv(stdlv'left downto 48) := std_logic_vector(to_unsigned(rec.Stream, MaxStreamsBits_c));
return stdlv;
end function;
function DaqSm2DaqDma_Cmd_FromStdlv( stdlv : std_logic_vector) return DaqSm2DaqDma_Cmd_t is
variable rec : DaqSm2DaqDma_Cmd_t;
begin
rec.Address := stdlv(31 downto 0);
rec.MaxSize := stdlv(47 downto 32);
rec.Stream := to_integer(unsigned(stdlv(stdlv'left downto 48)));
return rec;
end function;
-- *** DaqDma2DaqSm_Resp ***
function DaqDma2DaqSm_Resp_ToStdlv( rec : DaqDma2DaqSm_Resp_t) return std_logic_vector is
variable stdlv : std_logic_vector(DaqDma2DaqSm_Resp_Size_c-1 downto 0);
begin
stdlv(15 downto 0) := rec.Size;
stdlv(16) := rec.Trigger;
stdlv(stdlv'left downto 17) := std_logic_vector(to_unsigned(rec.Stream, MaxStreamsBits_c));
return stdlv;
end function;
function DaqDme2DaqSm_Resp_FromStdlv( stdlv : std_logic_vector) return DaqDma2DaqSm_Resp_t is
variable rec : DaqDma2DaqSm_Resp_t;
begin
rec.Size := stdlv(15 downto 0);
rec.Trigger := stdlv(16);
rec.Stream := to_integer(unsigned(stdlv(stdlv'left downto 17)));
return rec;
end function;
package body psi_ms_daq_pkg is
-- *** DaqSm2DaqDma_Cmd ***
function DaqSm2DaqDma_Cmd_ToStdlv(rec : DaqSm2DaqDma_Cmd_t) return std_logic_vector is
variable stdlv : std_logic_vector(DaqSm2DaqDma_Cmd_Size_c - 1 downto 0);
begin
stdlv(31 downto 0) := rec.Address;
stdlv(47 downto 32) := rec.MaxSize;
stdlv(stdlv'left downto 48) := std_logic_vector(to_unsigned(rec.Stream, MaxStreamsBits_c));
return stdlv;
end function;
function DaqSm2DaqDma_Cmd_FromStdlv(stdlv : std_logic_vector) return DaqSm2DaqDma_Cmd_t is
variable rec : DaqSm2DaqDma_Cmd_t;
begin
rec.Address := stdlv(31 downto 0);
rec.MaxSize := stdlv(47 downto 32);
rec.Stream := to_integer(unsigned(stdlv(stdlv'left downto 48)));
return rec;
end function;
-- *** DaqDma2DaqSm_Resp ***
function DaqDma2DaqSm_Resp_ToStdlv(rec : DaqDma2DaqSm_Resp_t) return std_logic_vector is
variable stdlv : std_logic_vector(DaqDma2DaqSm_Resp_Size_c - 1 downto 0);
begin
stdlv(15 downto 0) := rec.Size;
stdlv(16) := rec.Trigger;
stdlv(stdlv'left downto 17) := std_logic_vector(to_unsigned(rec.Stream, MaxStreamsBits_c));
return stdlv;
end function;
function DaqDme2DaqSm_Resp_FromStdlv(stdlv : std_logic_vector) return DaqDma2DaqSm_Resp_t is
variable rec : DaqDma2DaqSm_Resp_t;
begin
rec.Size := stdlv(15 downto 0);
rec.Trigger := stdlv(16);
rec.Stream := to_integer(unsigned(stdlv(stdlv'left downto 17)));
return rec;
end function;
end psi_ms_daq_pkg;

File diff suppressed because it is too large Load Diff

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

@@ -55,9 +55,11 @@ architecture sim of psi_ms_daq_axi_tb is
constant ID_WIDTH : integer := 1;
constant ADDR_WIDTH : integer := 32;
constant USER_WIDTH : integer := 1;
constant DATA_WIDTH : integer := 64;
constant DATA_WIDTH : integer := 128;
constant BYTE_WIDTH : integer := DATA_WIDTH/8;
constant IntDataWidth_g : integer := 128;
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;
@@ -163,9 +165,11 @@ 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),
IntDataWidth_g => IntDataWidth_g,
MaxWindows_g => work.psi_ms_daq_axi_tb_pkg.MaxWindows_c,
MinBurstSize_g => 16,
MaxBurstSize_g => 128,
AxiDataWidth_g => DATA_WIDTH,
AxiFifoDepth_g => 512,
AxiSlaveIdWidth_g => 1
)
@@ -378,7 +382,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;

View File

@@ -52,6 +52,7 @@ end entity;
architecture sim of psi_ms_daq_daq_dma_tb is
-- *** Fixed Generics ***
constant Streams_g : positive := 4;
constant IntDataWidth_g : positive := 64;
-- *** Not Assigned Generics (default values) ***
@@ -80,7 +81,7 @@ architecture sim of psi_ms_daq_daq_dma_tb is
signal DaqSm_HasLast : std_logic_vector(Streams_g-1 downto 0) := (others => '0');
signal Inp_Vld : std_logic_vector(Streams_g-1 downto 0) := (others => '0');
signal Inp_Rdy : std_logic_vector(Streams_g-1 downto 0) := (others => '0');
signal Inp_Data : Input2Daq_Data_a(Streams_g-1 downto 0);
signal Inp_Data : Input2Daq_Data_a(Streams_g - 1 downto 0)(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Mem_CmdAddr : std_logic_vector(31 downto 0) := (others => '0');
signal Mem_CmdSize : std_logic_vector(31 downto 0) := (others => '0');
signal Mem_CmdVld : std_logic := '0';

View File

@@ -87,9 +87,12 @@ architecture sim of psi_ms_daq_input_tb is
signal Mode : RecMode_t := (others => '0');
signal Arm : std_logic := '0';
signal IsArmed : std_logic := '0';
signal IsRecording : std_logic := '0';
signal ToDisable : std_logic := '0';
signal FrameTo : std_logic := '0';
signal Daq_Vld : std_logic := '0';
signal Daq_Rdy : std_logic := '0';
signal Daq_Data : Input2Daq_Data_t;
signal Daq_Data : Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : std_logic_vector(15 downto 0) := (others => '0');
signal Daq_HasLast : std_logic := '0';
signal Ts_Vld : std_logic := '0';
@@ -122,6 +125,9 @@ begin
Mode => Mode,
Arm => Arm,
IsArmed => IsArmed,
IsRecording => IsRecording,
ToDisable => ToDisable,
FrameTo => FrameTo,
ClkMem => ClkMem,
RstMem => RstMem,
Daq_Vld => Daq_Vld,

View File

@@ -44,7 +44,7 @@ package psi_ms_daq_input_tb_case_always_trig is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;
@@ -106,7 +106,7 @@ package body psi_ms_daq_input_tb_case_always_trig is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;

View File

@@ -44,7 +44,7 @@ package psi_ms_daq_input_tb_case_backpressure is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;
@@ -145,7 +145,7 @@ package body psi_ms_daq_input_tb_case_backpressure is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;

View File

@@ -46,7 +46,7 @@ package psi_ms_daq_input_tb_case_modes is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;
@@ -131,7 +131,7 @@ package body psi_ms_daq_input_tb_case_modes is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;

View File

@@ -44,7 +44,7 @@ package psi_ms_daq_input_tb_case_multi_frame is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;
@@ -92,7 +92,7 @@ package body psi_ms_daq_input_tb_case_multi_frame is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;

View File

@@ -44,7 +44,7 @@ package psi_ms_daq_input_tb_case_single_frame is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;
@@ -134,7 +134,7 @@ package body psi_ms_daq_input_tb_case_single_frame is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;

View File

@@ -45,7 +45,7 @@ package psi_ms_daq_input_tb_case_timeout is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;
@@ -104,7 +104,7 @@ package body psi_ms_daq_input_tb_case_timeout is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;

View File

@@ -45,7 +45,7 @@ package psi_ms_daq_input_tb_case_trig_in_posttrig is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;
@@ -100,7 +100,7 @@ package body psi_ms_daq_input_tb_case_trig_in_posttrig is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;

View File

@@ -44,7 +44,7 @@ package psi_ms_daq_input_tb_case_ts_overflow is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;
@@ -110,7 +110,7 @@ package body psi_ms_daq_input_tb_case_ts_overflow is
signal Mode : inout RecMode_t;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Daq_Level : in std_logic_vector;
signal Daq_HasLast : in std_logic;
signal Ts_Vld : in std_logic;

View File

@@ -34,6 +34,7 @@ package psi_ms_daq_input_tb_pkg is
------------------------------------------------------------
-- Not exported Generics
------------------------------------------------------------
constant IntDataWidth_g : positive := 64;
constant StreamBuffer_g : positive := 32;
constant StreamClkFreq_g : real := 125.0e6;
constant StreamTsFifoDepth_g : positive := 8;
@@ -63,7 +64,7 @@ package psi_ms_daq_input_tb_pkg is
signal Clk : in std_logic;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Ts_Vld : in std_logic;
signal Ts_Rdy : inout std_logic;
signal Ts_Data : in std_logic_vector;
@@ -124,7 +125,7 @@ package body psi_ms_daq_input_tb_pkg is
signal Clk : in std_logic;
signal Daq_Vld : in std_logic;
signal Daq_Rdy : inout std_logic;
signal Daq_Data : in Input2Daq_Data_t;
signal Daq_Data : in Input2Daq_Data_t(Data(IntDataWidth_g-1 downto 0), Bytes(log2ceil(IntDataWidth_g/8) downto 0));
signal Ts_Vld : in std_logic;
signal Ts_Rdy : inout std_logic;
signal Ts_Data : in std_logic_vector;