DEVEL: support for 1024bit bus

This commit is contained in:
2021-04-28 13:03:56 +02:00
parent 28b79e93a9
commit 5249ac7223
7 changed files with 306 additions and 256 deletions

View File

@ -37,16 +37,16 @@ entity psi_ms_daq_axi is
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;
AxiMaxBurstBeats_g : integer range 1 to 256 := 64;
AxiMaxOpenTrasactions_g : natural range 1 to 8 := 8;
AxiFifoDepth_g : natural := 1024;
-- Axi Slave
AxiSlaveIdWidth_g : integer := 0
);
port (
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_Data : in t_aslv512(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);
@ -170,25 +170,25 @@ architecture rtl of psi_ms_daq_axi is
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_DatData : std_logic_vector(MemoryBusWidth_c-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);
-- 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);
-- 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_PreTrigDisable : std_logic_vector(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;
@ -259,7 +259,8 @@ begin
IsArmed => Stat_IsArmed,
IsRecording => Stat_IsRecording,
RecMode => Cfg_RecMode,
ClkMem => M_Axi_Aclk,
PreTrigDisable => Cfg_PreTrigDisable,
ClkMem => M_Axi_Aclk,
RstMem => M_Axi_Areset,
CtxStr_Cmd => CtxStr_Cmd,
CtxStr_Resp => CtxStr_Resp,
@ -304,6 +305,7 @@ begin
RstReg => S_Axi_Areset,
PostTrigSpls => Cfg_PostTrig(str),
Mode => Cfg_RecMode(str),
PreTrigDisable => Cfg_PreTrigDisable(str),
Arm => Cfg_Arm(str),
IsArmed => Stat_IsArmed(str),
IsRecording => Stat_IsRecording(str),
@ -399,8 +401,8 @@ begin
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,
DataFifoDepth_g => 4096,
-- AxiFifoDepth_g => AxiFifoDepth_g,
RamBehavior_g => "RBW" -- Okay for Xilinx chips
)
port map (

View File

@ -10,10 +10,13 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_ms_daq_pkg.all;
------------------------------------------------------------------------------
-- Entity Declaration
------------------------------------------------------------------------------
@ -24,7 +27,6 @@ entity psi_ms_daq_axi_if is
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 (
@ -39,7 +41,7 @@ entity psi_ms_daq_axi_if is
Cmd_Rdy : out std_logic;
-- Write Data
Dat_Data : in std_logic_vector(63 downto 0);
Dat_Data : in std_logic_vector(MemoryBusWidth_c-1 downto 0);
Dat_Vld : in std_logic;
Dat_Rdy : out std_logic;
@ -106,17 +108,18 @@ architecture rtl of psi_ms_daq_axi_if is
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;
InfoFifoIn(CommandSizeRng_c) <= Cmd_Size;
i_wrinfo_fifo : entity work.psi_common_sync_fifo
generic map (
Width_g => WrCmdWidth_c,
Depth_g => MaxOpenCommands_g,
Depth_g => MaxOpenCommands_g*16,
RamStyle_g => "distributed"
)
port map (
@ -141,7 +144,7 @@ begin
AxiMaxOpenTrasactions_g => AxiMaxOpenTrasactions_g,
UserTransactionSizeBits_g => 32,
DataFifoDepth_g => DataFifoDepth_g,
DataWidth_g => 64,
DataWidth_g => MemoryBusWidth_c,
ImplRead_g => false,
ImplWrite_g => true,
RamBehavior_g => RamBehavior_g
@ -212,7 +215,7 @@ begin
M_Axi_RValid => M_Axi_RValid,
M_Axi_RReady => M_Axi_RReady
);
Done <= DoneI or ErrorI;

View File

@ -55,7 +55,7 @@ entity psi_ms_daq_daq_dma is
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_DatData : out std_logic_vector(MemoryBusWidth_c-1 downto 0); -- $$ proc=mem_dat $$
Mem_DatVld : out std_logic; -- $$ proc=mem_dat $$
Mem_DatRdy : in std_logic -- $$ proc=mem_dat $$
);
@ -66,9 +66,11 @@ end entity;
------------------------------------------------------------------------------
architecture rtl of psi_ms_daq_daq_dma is
-- Constants
constant BufferFifoDepth_c : integer := 32;
-- Constants
constant BufferFifoDepth_c : integer := 32;
constant RemShifts_c : natural := log2(MemoryBusBytes_c);
constant RemRamWidth_c : natural := 1+1+RemShifts_c+MemoryBusWidth_c;
-- 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);
@ -85,11 +87,14 @@ architecture rtl of psi_ms_daq_daq_dma is
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_RdBytes : std_logic_vector(RemShifts_c-1 downto 0);
signal Rem_Data : std_logic_vector(MemoryBusWidth_c-1 downto 0);
signal Rem_Trigger : std_logic;
signal Rem_Last : std_logic;
signal RemRam_WrData : std_logic_vector(RemRamWidth_c-1 downto 0);
signal RemRam_RdData : std_logic_vector(RemRamWidth_c-1 downto 0);
-- Types
type State_t is (Idle_s, RemRd1_s, RemRd2_s, Transfer_s, Done_s, Cmd_s);
@ -101,8 +106,8 @@ architecture rtl of psi_ms_daq_daq_dma is
Mem_DataVld : std_logic;
StreamStdlv : std_logic_vector(StreamBits_c-1 downto 0);
RemWen : std_logic;
RemWrBytes : std_logic_vector(2 downto 0);
RemData : std_logic_vector(63 downto 0);
RemWrBytes : std_logic_vector(RemShifts_c-1 downto 0);
RemData : std_logic_vector(MemoryBusWidth_c-1 downto 0);
RemTrigger : std_logic;
RemLast : std_logic;
RemWrTrigger : std_logic;
@ -114,12 +119,12 @@ architecture rtl of psi_ms_daq_daq_dma is
HndlStream : integer range 0 to MaxStreams_c-1;
HndlAddress : std_logic_vector(31 downto 0);
UpdateLast : std_logic;
HndlSft : unsigned(2 downto 0);
HndlSft : unsigned(log2(MemoryBusBytes_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(127 downto 0);
DataSft : std_logic_vector(2*MemoryBusWidth_c-1 downto 0);
NextDone : std_logic;
DataWritten : std_logic;
HasLast : std_logic_vector(Streams_g-1 downto 0);
@ -134,8 +139,7 @@ begin
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;
variable RemSft_v : integer range 0 to MemoryBusBytes_c-1;
begin
-- *** Hold variables stable ***
v := r;
@ -177,7 +181,7 @@ begin
v.RemLast := '0';
else
v.HndlSft := unsigned(Rem_RdBytes);
v.DataSft(127 downto 64) := Rem_Data;
v.DataSft(2*MemoryBusWidth_c-1 downto MemoryBusWidth_c) := Rem_Data;
v.RdBytes := resize(unsigned(Rem_RdBytes), v.RdBytes'length);
v.RemTrigger := Rem_Trigger;
v.RemLast := Rem_Last;
@ -195,7 +199,7 @@ begin
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;
v.WrBytes := r.WrBytes + MemoryBusBytes_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';
@ -203,7 +207,7 @@ begin
-- 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
if (r.HndlSft + unsigned(Inp_Data(r.HndlStream).Bytes) <= MemoryBusBytes_c) or (r.RemLast = '1') then
v.State := Done_s;
else
v.NextDone := '1';
@ -217,8 +221,8 @@ begin
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;
v.DataSft(MemoryBusWidth_c-1 downto 0) := r.DataSft(2*MemoryBusWidth_c-1 downto MemoryBusWidth_c);
v.DataSft(8*to_integer(r.HndlSft)+(MemoryBusWidth_c-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';
@ -226,7 +230,7 @@ begin
end if;
when Done_s =>
RemSft_v := to_integer(resize(r.HndlMaxSize, 3));
RemSft_v := to_integer(resize(r.HndlMaxSize, RemShifts_c));
v.RemWrTrigger := '0';
v.RemWrLast := '0';
if r.HndlMaxSize < r.RdBytes then
@ -239,7 +243,7 @@ begin
v.RemWrBytes := (others => '0');
v.HasLast(r.HndlStream) := '0';
end if;
v.RemData := v.DataSft(8*RemSft_v+63 downto 8*RemSft_v);
v.RemData := v.DataSft(8*RemSft_v+(MemoryBusWidth_c-1) downto 8*RemSft_v);
v.State := Cmd_s;
if r.DataWritten = '1' then
v.Mem_CmdVld := '1';
@ -348,7 +352,7 @@ begin
-- 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,
Width_g => MemoryBusWidth_c,
Depth_g => BufferFifoDepth_c,
AlmFullOn_g => true,
AlmFullLevel_g => BufferFifoDepth_c/2,
@ -358,7 +362,7 @@ begin
port map (
Clk => Clk,
Rst => Rst,
InData => r.DataSft(63 downto 0),
InData => r.DataSft(MemoryBusWidth_c-1 downto 0),
InVld => r.Mem_DataVld,
OutData => Mem_DatData,
OutVld => Mem_DatVld,
@ -366,31 +370,38 @@ begin
OutLevel => DatFifo_Level_Dbg,
AlmFull => DatFifo_AlmFull
);
-- *** Remaining Data RAM ***
i_remram : entity work.psi_common_sdp_ram
generic map (
Depth_g => 2**StreamBits_c,
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
);
Rem_Last <= RemRam_RdData(0);
Rem_Trigger <= RemRam_RdData(1);
Rem_RdBytes <= RemRam_RdData(RemShifts_c-1+2 downto 2);
Rem_Data <= RemRam_RdData(RemRamWidth_c-1 downto RemShifts_c+2);
RemRam_WrData(0) <= r.RemWrLast;
RemRam_WrData(1) <= r.RemWrTrigger;
RemRam_WrData(RemShifts_c-1+2 downto 2) <= r.RemWrBytes;
RemRam_WrData(RemRamWidth_c-1 downto RemShifts_c+2) <= r.RemData;
-- *** Remaining Data RAM ***
i_remram : entity work.psi_common_sdp_ram
generic map (
Depth_g => 2**StreamBits_c,
Width_g => RemRamWidth_c,
IsAsync_g => false,
RamStyle_g => "distributed",
Behavior_g => "RBW"
)
port map (
Clk => Clk,
RdClk => Rst,
WrAddr => r.StreamStdlv,
Wr => r.RemWen,
WrData => RemRam_WrData,
RdAddr => r.StreamStdlv,
RdData => RemRam_RdData
);
end;

View File

@ -433,7 +433,7 @@ begin
-- Calculate Command
v.Dma_Cmd.Address := r.HndlPtr0;
v.Dma_Cmd.Stream := r.HndlStream;
v.Dma_Cmd.MaxSize := std_logic_vector(to_unsigned(MaxBurstSize_g*8, v.Dma_Cmd.MaxSize'length)); -- 8 bytes per 64-bit QWORD
v.Dma_Cmd.MaxSize := std_logic_vector(to_unsigned(MaxBurstSize_g*MemoryBusBytes_c, v.Dma_Cmd.MaxSize'length)); -- 8 bytes per 64-bit QWORD
-- State update (abort if window is not free)
if (r.HndlOverwrite = '0') and (unsigned(r.HndlWinBytes) /= 0) and (r.NewBuffer(r.HndlStream) = '1') then
v.State := Idle_s;

View File

@ -28,7 +28,7 @@ library work;
-- $$ tbpkg=work.psi_tb_txt_util $$
entity psi_ms_daq_input is
generic (
StreamWidth_g : positive range 8 to 64 := 16; -- Must be 8, 16, 32 or 64 $$ export=true $$
StreamWidth_g : positive range 8 to MemoryBusWidth_c := 16; -- Must be 8 bits increments and modulo MemoryBusWidth_c $$ export=true $$
StreamBuffer_g : positive range 1 to 65535 := 1024; -- Buffer depth in QWORDs $$ constant=32 $$
StreamTimeout_g : real := 1.0e-3; -- Timeout in seconds $$ constant=10.0e-6 $$
StreamClkFreq_g : real := 125.0e6; -- Input clock frequency in Hz $$ constant=125.0e6 $$
@ -49,6 +49,7 @@ entity psi_ms_daq_input is
RstReg : in std_logic;
PostTrigSpls : in std_logic_vector(31 downto 0); -- $$ proc=daq $$
Mode : in RecMode_t; -- $$ proc=daq $$
PreTrigDisable : in std_logic; -- $$ proc=daq $$
Arm : in std_logic; -- $$ proc=stream $$
IsArmed : out std_logic; -- $$ proc=stream $$
IsRecording : out std_logic; -- $$ proc=stream $$
@ -81,16 +82,19 @@ architecture rtl of psi_ms_daq_input is
-- Constants
constant TimeoutLimit_c : integer := integer(StreamClkFreq_g*StreamTimeout_g)-1;
constant WconvFactor_c : positive := 64/StreamWidth_g;
constant WconvFactor_c : positive := MemoryBusWidth_c/StreamWidth_g;
constant TlastCntWidth_c : positive := log2ceil(StreamBuffer_g) + 1;
constant BytesIncr_c : unsigned(log2(MemoryBusBytes_c)-1 downto 0)
:= to_unsigned(StreamWidth_g/8, log2(MemoryBusBytes_c));
-- Two process method
type two_process_r is record
ModeReg : RecMode_t;
ArmReg : std_logic;
DataSftReg : std_logic_vector(63 downto 0);
DataSftReg : std_logic_vector(MemoryBusWidth_c-1 downto 0);
WordCnt : unsigned(log2ceil(WconvFactor_c) downto 0);
DataFifoBytes : unsigned(3 downto 0);
BytesCnt : unsigned(Input2Daq_Data_Bytes_Len-1 downto 0);
DataFifoBytes : unsigned(Input2Daq_Data_Bytes_Len-1 downto 0);
TrigLatch : std_logic;
DataFifoVld : std_logic;
DataFifoIsTo : std_logic;
@ -104,17 +108,21 @@ architecture rtl of psi_ms_daq_input is
HasTlastSync : std_logic_vector(0 to 1);
IsArmed : std_logic;
RecEna : std_logic;
PreRecEna : std_logic;
StrData : std_logic_vector(StreamWidth_g-1 downto 0); -- 1 clk delayed stream data
end record;
signal r, r_next : two_process_r;
-- General Instantiation signals
signal Str_Rst : std_logic;
-- DataFifo contains Data, Number of Bytes and Timeout and Trig signals
constant DataFifo_Width_c : natural := MemoryBusWidth_c+Input2Daq_Data_Bytes_Len+2;
-- Data FIFO signals
signal DataFifo_InRdy : std_logic;
signal DataFifo_InData : std_logic_vector(69 downto 0);
signal DataFifo_OutData : std_logic_vector(69 downto 0);
signal DataFifo_PlData : std_logic_vector(69 downto 0);
signal DataFifo_InData : std_logic_vector(DataFifo_Width_c-1 downto 0);
signal DataFifo_OutData : std_logic_vector(DataFifo_Width_c-1 downto 0);
signal DataFifo_PlData : std_logic_vector(DataFifo_Width_c-1 downto 0);
signal DataFifo_PlVld : std_logic;
signal DataFifo_PlRdy : std_logic;
signal DataFifo_Level : std_logic_vector(log2ceil(StreamBuffer_g) downto 0);
@ -140,26 +148,27 @@ architecture rtl of psi_ms_daq_input is
-- Clock Crossing Signals
signal PostTrigSpls_Sync : std_logic_vector(PostTrigSpls'range);
signal Mode_Sync : RecMode_t;
signal PreTrigDisable_Sync : std_logic;
signal Arm_Sync : std_logic;
signal RstReg_Sync : std_logic;
signal RstAcq_Sync : std_logic;
begin
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process( r,
Str_Vld, Str_Data, Str_Trig, Str_Ts, PostTrigSpls_Sync, Daq_Rdy, Ts_Rdy, Mode_Sync, Arm_Sync,
DataFifo_InRdy, DataFifo_InData, DataFifo_OutData, Daq_Vld_I, Daq_Data_I, Daq_HasLast_I, Ts_Vld_I, OutTlastCnt, TsFifo_AlmFull, TsFifo_Empty,
InTlastCnt, TsFifo_InRdy, TsFifo_RdData)
variable v : two_process_r;
variable ProcessSample_v : boolean;
variable TriggerSample_v : boolean;
variable AddSamples_v : integer range 0 to 1;
variable TrigMasked_v : std_logic;
begin
-- *** Hold variables stable ***
v := r;
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process(r,
Str_Vld, Str_Data, Str_Trig, Str_Ts, PostTrigSpls_Sync, Daq_Rdy, Ts_Rdy, Mode_Sync,
Arm_Sync,DataFifo_InRdy, DataFifo_InData, DataFifo_OutData, Daq_Vld_I, Daq_Data_I,
Daq_HasLast_I, Ts_Vld_I, OutTlastCnt, TsFifo_AlmFull, TsFifo_Empty,
InTlastCnt, TsFifo_InRdy, TsFifo_RdData, PreTrigDisable_Sync)
variable v : two_process_r;
variable ProcessSample_v : boolean;
variable TriggerSample_v : boolean;
variable TrigMasked_v : std_logic;
begin
-- *** Hold variables stable ***
v := r;
-- *** Simplification Variables ***
ProcessSample_v := (DataFifo_InRdy = '1') and (Str_Vld = '1');
@ -170,7 +179,11 @@ begin
v.DataFifoIsTrig := '0';
v.ModeReg := Mode_Sync;
v.ArmReg := Arm_Sync;
if ProcessSample_v then
v.StrData := Str_Data;
end if;
-- Masking trigger according to recording mode
case r.ModeReg is
when RecMode_Continuous_c =>
@ -182,8 +195,7 @@ begin
TrigMasked_v := r.ArmReg;
when others => null;
end case;
-- Keep FifoVld high until data is written
v.DataFifoVld := r.DataFifoVld and not DataFifo_InRdy;
@ -191,7 +203,7 @@ begin
if ProcessSample_v then
v.TrigLatch := '0';
else
v.TrigLatch := r.TrigLatch or TrigMasked_v;
v.TrigLatch := r.TrigLatch or TrigMasked_v;
end if;
-- Detect timestamp FIFO overflows
@ -217,28 +229,31 @@ begin
end if;
-- Trigger handling and post trigger counter
if ProcessSample_v and r.RecEna = '1' then
if ProcessSample_v then
if r.PostTrigCnt /= 0 then
v.PostTrigCnt := r.PostTrigCnt - 1;
if r.PostTrigCnt = 1 then
v.DataFifoIsTrig := '1';
v.DataFifoVld := r.DataFifoVld or r.RecEna;
v.DataFifoVld := r.DataFifoVld or r.RecEna or r.PreRecEna;
v.RecEna := '0'; -- stop recording after frame
v.PreRecEna := '0';
end if;
elsif (r.TrigLatch = '1') or (TrigMasked_v = '1') then
-- Handle incoming trigger sample
if unsigned(PostTrigSpls_Sync) = 0 then
v.DataFifoIsTrig := '1';
v.DataFifoVld := r.DataFifoVld or r.RecEna;
v.DataFifoVld := r.DataFifoVld or r.RecEna or r.PreRecEna;
v.RecEna := '0'; -- stop recording after frame
v.PreRecEna := '0';
else
v.PostTrigCnt := unsigned(PostTrigSpls_Sync);
v.RecEna := '1';
v.PostTrigCnt := unsigned(PostTrigSpls_Sync);
end if;
end if;
end if;
-- Detect Timeout
if Str_Vld = '1' then
-- Detect Timeout (only if data is stuck in conversion)
if Str_Vld = '1' or r.WordCnt = 0 then
v.TimeoutCnt := 0;
else
if r.TimeoutCnt = TimeoutLimit_c then
@ -254,40 +269,41 @@ begin
v.TLastCnt := std_logic_vector(unsigned(r.TLastCnt) + 1);
end if;
-- Write because timeout occured (only if data is stuck in conversion)
if r.Timeout = '1' then
v.DataFifoVld := r.DataFifoVld or r.RecEna;
v.DataFifoIsTo := '1';
v.Timeout := '0'; -- reser timeout after data was flushed to the FIFO
end if;
-- Process input data
if ProcessSample_v and r.RecEna = '1' then
v.WordCnt := r.WordCnt + 1;
-- Write because 64-bits are ready
if r.WordCnt = WconvFactor_c-1 then
v.DataFifoVld := r.DataFifoVld or r.RecEna;
end if;
v.DataSftReg((to_integer(r.WordCnt)+1)*StreamWidth_g-1 downto to_integer(r.WordCnt)*StreamWidth_g) := Str_Data;
end if;
-- Reset counter if data is being written to FIFO
if v.DataFifoVld = '1' then
v.WordCnt := (others => '0');
end if;
-- Write because timeout occured
if r.Timeout = '1' then
v.DataFifoVld := r.DataFifoVld or r.RecEna or r.PreRecEna;
v.DataFifoIsTo := '1';
v.Timeout := '0'; -- reser timeout after data was flushed to the FIFO
end if;
-- Process input data
if ProcessSample_v and (r.RecEna = '1' or r.PreRecEna = '1') then
v.WordCnt := r.WordCnt + 1;
v.BytesCnt := r.BytesCnt + BytesIncr_c;
-- Write because 64-bits are ready
if r.WordCnt = WconvFactor_c-1 then
v.DataFifoVld := r.DataFifoVld or r.RecEna or r.PreRecEna;
end if;
-- If the pretrigger is disabled, use delayed data to compensate for trigger detection time
if PreTrigDisable_Sync = '1' then
v.DataSftReg((to_integer(r.WordCnt)+1)*StreamWidth_g-1 downto to_integer(r.WordCnt)*StreamWidth_g) := r.StrData;
else
v.DataSftReg((to_integer(r.WordCnt)+1)*StreamWidth_g-1 downto to_integer(r.WordCnt)*StreamWidth_g) := Str_Data;
end if;
end if;
-- Reset counter if data is being written to FIFO
if v.DataFifoVld = '1' then
v.WordCnt := (others => '0');
v.BytesCnt := (others => '0');
end if;
-- Convert word counter to byte counter
v.DataFifoBytes := (others => '0');
if r.Timeout = '1' then
AddSamples_v := 0;
v.DataFifoBytes := r.BytesCnt;
else
AddSamples_v := 1;
v.DataFifoBytes := r.BytesCnt + BytesIncr_c;
end if;
case StreamWidth_g is
when 8 => v.DataFifoBytes := r.WordCnt + AddSamples_v;
when 16 => v.DataFifoBytes := (r.WordCnt + AddSamples_v) & "0";
when 32 => v.DataFifoBytes := (r.WordCnt + AddSamples_v) & "00";
when 64 => v.DataFifoBytes := (r.WordCnt + AddSamples_v) & "000";
when others => null;
end case;
-- Handle Arming Logic
if (r.ModeReg /= Mode_Sync) or (r.ModeReg = RecMode_Continuous_c) or (r.ModeReg = RecMode_ManuelMode_c) then -- reset on mode change!
@ -303,17 +319,21 @@ begin
when RecMode_Continuous_c |
RecMode_TriggerMask_c =>
-- always enabled
v.RecEna := '1';
when RecMode_SingleShot_c |
RecMode_ManuelMode_c =>
v.PreRecEna := not PreTrigDisable_Sync;
when RecMode_SingleShot_c =>
if v.ArmReg = '1' then
v.PreRecEna := not PreTrigDisable_Sync;
end if;
when RecMode_ManuelMode_c =>
-- enable on arming (disable happens after recording)
if v.ArmReg = '1' then
v.RecEna := '1';
v.PreRecEna := '1';
end if;
when others => null;
end case;
if r.ModeReg /= Mode_Sync then
v.RecEna := '0';
v.RecEna := '0';
v.PreRecEna := '0';
end if;
-- *** Assign to signal ***
@ -321,28 +341,30 @@ begin
end process;
--------------------------------------------
-- Sequential Process
--------------------------------------------
p_seq : process(Str_Clk)
begin
if rising_edge(Str_Clk) then
r <= r_next;
if Str_Rst = '1' then
r.WordCnt <= (others => '0');
r.TrigLatch <= '0';
r.TimeoutCnt <= 0;
r.Timeout <= '0';
r.PostTrigCnt <= (others => '0');
r.TLastCnt <= (others => '0');
r.TsOverflow <= '0';
r.HasTlastSync <= (others => '0');
r.IsArmed <= '0';
r.RecEna <= '0';
r.ArmReg <= '0';
end if;
end if;
end process;
--------------------------------------------
-- Sequential Process
--------------------------------------------
p_seq : process(Str_Clk)
begin
if rising_edge(Str_Clk) then
r <= r_next;
if Str_Rst = '1' then
r.WordCnt <= (others => '0');
r.BytesCnt <= (others => '0');
r.TrigLatch <= '0';
r.TimeoutCnt <= 0;
r.Timeout <= '0';
r.PostTrigCnt <= (others => '0');
r.TLastCnt <= (others => '0');
r.TsOverflow <= '0';
r.HasTlastSync <= (others => '0');
r.IsArmed <= '0';
r.RecEna <= '0';
r.PreRecEna <= '0';
r.ArmReg <= '0';
end if;
end if;
end process;
--------------------------------------------
-- Output Side TLAST handling
@ -387,24 +409,26 @@ begin
end process;
Daq_HasLast <= Daq_HasLast_I;
--------------------------------------------
-- Component Instantiation
--------------------------------------------
-- *** Register Interface clock crossings ***
i_cc_reg_status : entity work.psi_common_status_cc
generic map (
DataWidth_g => 34
)
port map (
ClkA => ClkReg,
RstInA => '0',
DataA(31 downto 0) => PostTrigSpls,
DataA(33 downto 32) => Mode,
ClkB => Str_Clk,
RstInB => Str_Rst,
DataB(31 downto 0) => PostTrigSpls_Sync,
DataB(33 downto 32) => Mode_Sync
);
--------------------------------------------
-- Component Instantiation
--------------------------------------------
-- *** Register Interface clock crossings ***
i_cc_reg_status : entity work.psi_common_status_cc
generic map (
DataWidth_g => 35
)
port map (
ClkA => ClkReg,
RstInA => '0',
DataA(31 downto 0) => PostTrigSpls,
DataA(33 downto 32) => Mode,
DataA(34) => PreTrigDisable,
ClkB => Str_Clk,
RstInB => Str_Rst,
DataB(31 downto 0) => PostTrigSpls_Sync,
DataB(33 downto 32) => Mode_Sync,
DataB(34) => PreTrigDisable_Sync
);
i_cc_status : entity work.psi_common_bit_cc
generic map (
@ -412,7 +436,7 @@ begin
)
port map (
BitsA(0) => r.IsArmed,
BitsA(1) => r.RecEna,
BitsA(1) => r.RecEna or r.PreRecEna,
ClkB => ClkReg,
BitsB(0) => IsArmed,
BitsB(1) => IsRecording
@ -473,16 +497,17 @@ begin
);
-- Data FIFO
DataFifo_InData(63 downto 0) <= r.DataSftReg;
DataFifo_InData(67 downto 64) <= std_logic_vector(r.DataFifoBytes);
DataFifo_InData(68) <= r.DataFifoIsTo;
DataFifo_InData(69) <= r.DataFifoIsTrig;
-- Data FIFO
DataFifo_InData(MemoryBusWidth_c-1+2 downto 2) <= r.DataSftReg;
DataFifo_InData(MemoryBusWidth_c+Input2Daq_Data_Bytes_Len+2-1
downto MemoryBusWidth_c+2) <= std_logic_vector(r.DataFifoBytes);
DataFifo_InData(0) <= r.DataFifoIsTo;
DataFifo_InData(1) <= r.DataFifoIsTrig;
i_dfifo : entity work.psi_common_async_fifo
generic map (
Width_g => 70,
Width_g => DataFifo_Width_c,
Depth_g => StreamBuffer_g,
AlmFullOn_g => false,
AlmEmptyOn_g => false
@ -504,7 +529,7 @@ begin
-- An additional pipeline stage after the FIFO is required for timing reasons
i_dplstage : entity work.psi_common_pl_stage
generic map (
Width_g => 70,
Width_g => DataFifo_Width_c,
UseRdy_g => true
)
port map (
@ -519,13 +544,13 @@ begin
);
Str_Rdy <= DataFifo_InRdy;
Daq_Data_I.Data <= DataFifo_OutData(63 downto 0);
Daq_Data_I.Bytes <= DataFifo_OutData(67 downto 64);
Daq_Data_I.IsTo <= DataFifo_OutData(68);
Daq_Data_I.IsTrig <= DataFifo_OutData(69);
Daq_Data_I.Last <= Daq_Data_I.IsTo or Daq_Data_I.IsTrig;
Daq_Data <= Daq_Data_I;
Daq_Vld <= Daq_Vld_I;
Daq_Data_I.Data <= DataFifo_OutData(MemoryBusWidth_c-1+2 downto 2);
Daq_Data_I.Bytes <= DataFifo_OutData(MemoryBusWidth_c+Input2Daq_Data_Bytes_Len+2-1 downto MemoryBusWidth_c+2);
Daq_Data_I.IsTo <= DataFifo_OutData(0);
Daq_Data_I.IsTrig <= DataFifo_OutData(1);
Daq_Data_I.Last <= Daq_Data_I.IsTo or Daq_Data_I.IsTrig;
Daq_Data <= Daq_Data_I;
Daq_Vld <= Daq_Vld_I;
-- Timestamp FIFO
@ -572,7 +597,7 @@ begin
p_assert : process(ClkMem)
begin
if rising_edge(ClkMem) then
assert StreamWidth_g = 8 or StreamWidth_g = 16 or StreamWidth_g = 32 or StreamWidth_g = 64 report "###ERROR###: psi_ms_daq_input: StreamWidth_g must be 8, 16, 32 or 64" severity error;
assert MemoryBusWidth_c mod StreamWidth_g = 0 report "###ERROR###: psi_ms_daq_input: StreamWidth_g must be modulo division of MemoryBusWidth_c" severity error;
end if;
end process;

View File

@ -19,11 +19,13 @@ library work;
------------------------------------------------------------------------------
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;
constant MemoryBusWidth_c : integer := 512;
constant MemoryBusBytes_c : integer := MemoryBusWidth_c/8;
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 := MemoryBusWidth_c;
subtype RecMode_t is std_logic_vector(1 downto 0);
constant RecMode_Continuous_c : RecMode_t := std_logic_vector(to_unsigned(0, RecMode_t'length));
@ -33,11 +35,12 @@ package psi_ms_daq_pkg is
subtype WinType_t is std_logic_vector(MaxWindowsBits_c-1 downto 0);
type WinType_a is array (natural range <>) of WinType_t;
constant Input2Daq_Data_Bytes_Len : natural := log2(MemoryBusBytes_c)+1;
type Input2Daq_Data_t is record
Last : std_logic;
Data : std_logic_vector(63 downto 0);
Bytes : std_logic_vector(3 downto 0);
Data : std_logic_vector(MemoryBusWidth_c-1 downto 0);
Bytes : std_logic_vector(Input2Daq_Data_Bytes_Len-1 downto 0);
IsTo : std_logic;
IsTrig : std_logic;
end record;

View File

@ -77,6 +77,7 @@ entity psi_ms_daq_reg_axi is
IsRecording : in std_logic_vector(Streams_g-1 downto 0);
PostTrig : out t_aslv32(Streams_g-1 downto 0);
RecMode : out t_aslv2(Streams_g-1 downto 0);
PreTrigDisable : out std_logic_vector(Streams_g-1 downto 0);
IrqOut : out std_logic;
-- Memory Interfae Clock domain control singals
@ -99,22 +100,23 @@ entity psi_ms_daq_reg_axi is
end entity;
architecture rtl of psi_ms_daq_reg_axi is
-- Two process method
type two_process_r is record
Reg_Gcfg_Ena : std_logic;
Reg_Gcfg_IrqEna : std_logic;
Reg_IrqVec : std_logic_vector(Streams_g-1 downto 0);
Reg_IrqEna : std_logic_vector(Streams_g-1 downto 0);
Reg_StrEna : std_logic_vector(Streams_g-1 downto 0);
Reg_PostTrig : t_aslv32(Streams_g-1 downto 0);
Reg_Mode_Recm : t_aslv2(Streams_g-1 downto 0);
Reg_Mode_Arm : std_logic_vector(Streams_g-1 downto 0);
Irq : std_logic;
RegRdval : std_logic_vector(31 downto 0);
AddrReg : std_logic_vector(15 downto 0);
MaxLvlClr : std_logic_vector(Streams_g-1 downto 0);
end record;
signal r, r_next : two_process_r;
-- Two process method
type two_process_r is record
Reg_Gcfg_Ena : std_logic;
Reg_Gcfg_IrqEna : std_logic;
Reg_IrqVec : std_logic_vector(Streams_g-1 downto 0);
Reg_IrqEna : std_logic_vector(Streams_g-1 downto 0);
Reg_StrEna : std_logic_vector(Streams_g-1 downto 0);
Reg_PostTrig : t_aslv32(Streams_g-1 downto 0);
Reg_Mode_Recm : t_aslv2(Streams_g-1 downto 0);
Reg_Mode_Arm : std_logic_vector(Streams_g-1 downto 0);
Reg_Mode_PreTrigDisable : std_logic_vector(Streams_g-1 downto 0);
Irq : std_logic;
RegRdval : std_logic_vector(31 downto 0);
AddrReg : std_logic_vector(15 downto 0);
MaxLvlClr : std_logic_vector(Streams_g-1 downto 0);
end record;
signal r, r_next : two_process_r;
constant DwWrite_c : std_logic_vector(3 downto 0) := "1111";
@ -224,18 +226,20 @@ begin
v.RegRdval := r.Reg_PostTrig(Stream_v);
end if;
-- MODEn / LASTWINn
if AccAddr(3 downto 0) = X"8" then
if AccWr(0) = '1' then
v.Reg_Mode_Recm(Stream_v) := AccWrData(1 downto 0);
end if;
if AccWr(1) = '1' then
v.Reg_Mode_Arm(Stream_v) := AccWrData(8);
end if;
v.RegRdval(1 downto 0) := r.Reg_Mode_Recm(Stream_v);
v.RegRdval(8) := IsArmed(Stream_v);
v.RegRdval(16) := IsRecording(Stream_v);
end if;
-- MODEn / LASTWINn
if AccAddr(3 downto 0) = X"8" then
if AccWr(0) = '1' then
v.Reg_Mode_Recm(Stream_v) := AccWrData(1 downto 0);
v.Reg_Mode_PreTrigDisable(Stream_v) := AccWrData(2);
end if;
if AccWr(1) = '1' then
v.Reg_Mode_Arm(Stream_v) := AccWrData(8);
end if;
v.RegRdval(1 downto 0) := r.Reg_Mode_Recm(Stream_v);
v.RegRdval(2) := r.Reg_Mode_PreTrigDisable(Stream_v);
v.RegRdval(8) := IsArmed(Stream_v);
v.RegRdval(16) := IsRecording(Stream_v);
end if;
-- LASTWINn
if AccAddr(3 downto 0) = X"C" then
@ -291,27 +295,29 @@ begin
PostTrig <= r.Reg_PostTrig;
Arm <= r.Reg_Mode_Arm;
RecMode <= r.Reg_Mode_Recm;
PreTrigDisable <= r.Reg_Mode_PreTrigDisable;
--------------------------------------------
-- Sequential Process
--------------------------------------------
p_seq : process(S_Axi_Aclk)
begin
if rising_edge(S_Axi_Aclk) then
r <= r_next;
if A_Axi_Areset = '1' then
r.Reg_Gcfg_Ena <= '0';
r.Reg_Gcfg_IrqEna <= '0';
r.Reg_IrqVec <= (others => '0');
r.Reg_IrqEna <= (others => '0');
r.Reg_StrEna <= (others => '0');
r.Irq <= '0';
r.Reg_PostTrig <= (others => (others => '0'));
r.Reg_Mode_Recm <= (others => (others => '0'));
r.Reg_Mode_Arm <= (others => '0');
end if;
end if;
end process;
--------------------------------------------
-- Sequential Process
--------------------------------------------
p_seq : process(S_Axi_Aclk)
begin
if rising_edge(S_Axi_Aclk) then
r <= r_next;
if A_Axi_Areset = '1' then
r.Reg_Gcfg_Ena <= '0';
r.Reg_Gcfg_IrqEna <= '0';
r.Reg_IrqVec <= (others => '0');
r.Reg_IrqEna <= (others => '0');
r.Reg_StrEna <= (others => '0');
r.Irq <= '0';
r.Reg_PostTrig <= (others => (others => '0'));
r.Reg_Mode_Recm <= (others => (others => '0'));
r.Reg_Mode_Arm <= (others => '0');
r.Reg_Mode_PreTrigDisable <= (others => '0');
end if;
end if;
end process;
--------------------------------------------
-- Maximum Level Latching (MemClk)