DEVEL: Allow different clocks for TMEM and SMEM

This commit is contained in:
Oliver Bruendler
2018-09-11 07:49:33 +02:00
parent ddf28d6596
commit 59716bf3bc
7 changed files with 343 additions and 185 deletions

View File

@ -38,21 +38,20 @@ entity psi_ms_daq is
Str_Rdy : out std_logic_vector(Streams_g-1 downto 0);
Str_Trig : in std_logic_vector(Streams_g-1 downto 0);
-- Tosca Control Signals
Tosca_Clk : in std_logic; -- 200 MHz tosca clock
Tmem_Rst : in std_logic;
Smem_Rst : in std_logic;
-- TMEM Interface
Tmem_Clk : in std_logic;
Tmem_Rst : in std_logic;
TmemAcq : in TmemRqst_t;
AcqTmem : out TmemResp_t;
-- SMEM Interface
Smem_Clk : in std_logic;
Smem_Rst : in std_logic;
AcqSmem : out ToSmemWr_t;
SmemAcq : in FromSmemWr_t;
-- Miscellaneous
Irq : out std_logic
Irq : out std_logic -- TMEM clock domain
);
end entity;
@ -119,16 +118,6 @@ architecture rtl of psi_ms_daq is
begin
--------------------------------------------
-- Reset
--------------------------------------------
p_rst : process(Tosca_Clk)
begin
if rising_edge(Tosca_Clk) then
Rst <= Tmem_Rst or Smem_Rst;
end if;
end process;
--------------------------------------------
-- TMEM Interface
--------------------------------------------
@ -138,24 +127,26 @@ begin
MaxWindows_g => MaxWindows_g
)
port map (
ToscaClk => Tosca_Clk,
Rst => Rst,
ClkTmem => Tmem_Clk,
RstTmem => Tmem_Rst,
TmemRqst => TmemAcq,
TmemResp => AcqTmem,
CtxStr_Cmd => CtxStr_Cmd,
CtxStr_Resp => CtxStr_Resp,
CtxWin_Cmd => CtxWin_Cmd,
CtxWin_Resp => CtxWin_Resp,
StrIrq => Stat_StrIrq,
StrEna => Cfg_StrEna,
GlbEna => Cfg_GlbEna,
IrqOut => Irq,
InLevel => InpSm_Level,
IrqOut => Irq,
PostTrig => Cfg_PostTrig,
Arm => Cfg_Arm,
IsArmed => Stat_IsArmed,
IsRecording => Stat_IsRecording,
RecMode => Cfg_RecMode
RecMode => Cfg_RecMode,
ClkSmem => Smem_Clk,
RstSmem => Smem_Rst,
CtxStr_Cmd => CtxStr_Cmd,
CtxStr_Resp => CtxStr_Resp,
CtxWin_Cmd => CtxWin_Cmd,
CtxWin_Resp => CtxWin_Resp,
InLevel => InpSm_Level,
StrIrq => Stat_StrIrq,
StrEna => Cfg_StrEna,
GlbEna => Cfg_GlbEna
);
--------------------------------------------
@ -166,7 +157,7 @@ begin
signal StrInput : std_logic_vector(StreamWidth_g(str)-1 downto 0);
begin
-- Reset if stream is disabled
InRst <= Rst or not Cfg_StrEna(str) or not Cfg_GlbEna;
InRst <= Smem_Rst or not Cfg_StrEna(str) or not Cfg_GlbEna;
StrInput <= Str_Data(str)(StrInput'range);
-- Instantiation
@ -186,13 +177,15 @@ begin
Str_Data => StrInput,
Str_Trig => Str_Trig(str),
Str_Ts => Str_Ts(str),
Clk => Tosca_Clk,
Rst => InRst,
ClkTmem => Tmem_Clk,
RstTmem => Tmem_Rst,
PostTrigSpls => Cfg_PostTrig(str),
Mode => Cfg_RecMode(str),
Arm => Cfg_Arm(str),
IsArmed => Stat_IsArmed(str),
IsRecording => Stat_IsRecording(str),
ClkSmem => Smem_Clk,
RstSmem => InRst,
Daq_Vld => InpDma_Vld(str),
Daq_Rdy => InpDma_Rdy(str),
Daq_Data => InpDma_Data(str),
@ -221,8 +214,8 @@ begin
MaxBurstSize_g => MaxBurstSize_g
)
port map (
Clk => Tosca_Clk,
Rst => Rst,
Clk => Smem_Clk,
Rst => Smem_Rst,
GlbEna => Cfg_GlbEna,
StrEna => Cfg_StrEna,
StrIrq => Stat_StrIrq,
@ -253,8 +246,8 @@ begin
Streams_g => Streams_g
)
port map (
Clk => Tosca_Clk,
Rst => Rst,
Clk => Smem_Clk,
Rst => Smem_Rst,
DaqSm_Cmd => SmDma_Cmd,
DaqSm_Cmd_Vld => SmDma_CmdVld,
DaqSm_Resp => DmaSm_Resp,
@ -284,8 +277,8 @@ begin
MaxOpenTransactions_g => Streams_g
)
port map (
Clk => Tosca_Clk,
Rst => Rst,
Clk => Smem_Clk,
Rst => Smem_Rst,
Cmd_Addr => DmaMem_CmdAddr,
Cmd_Size => DmaMem_CmdSize,
Cmd_Vld => DmaMem_CmdVld,

View File

@ -38,14 +38,18 @@ entity psi_ms_daq_input is
Str_Trig : in std_logic; -- $$ proc=stream $$
Str_Ts : in std_logic_vector(63 downto 0); -- $$ proc=stream $$
-- DAQ control signals
Clk : in std_logic; -- $$ type=clk; freq=200e6; proc=daq,stream $$
Rst : in std_logic; -- $$ type=rst; clk=Clk $$
-- Configuration Signals
ClkTmem : in std_logic;
RstTmem : in std_logic;
PostTrigSpls : in std_logic_vector(31 downto 0); -- $$ proc=daq $$
Mode : in RecMode_t; -- $$ proc=daq $$
Arm : in std_logic; -- $$ proc=stream $$
IsArmed : out std_logic; -- $$ proc=stream $$
IsRecording : out std_logic; -- $$ proc=stream $$
IsRecording : out std_logic; -- $$ proc=stream $$
-- DAQ control signals
ClkSmem : in std_logic; -- $$ type=clk; freq=200e6; proc=daq,stream $$
RstSmem : in std_logic; -- $$ type=rst; clk=Clk $$
-- DAQ logic Connections
Daq_Vld : out std_logic; -- $$ proc=daq $$
@ -99,11 +103,6 @@ architecture rtl of psi_ms_daq_input is
-- General Instantiation signals
signal Str_Rst : std_logic;
-- clock Crossing Signals
signal Str_Arm : std_logic;
signal StatusCcIn : std_logic_vector(TlastCntWidth_c+1 downto 0);
signal StatusCcOut : std_logic_vector(TlastCntWidth_c+1 downto 0);
-- Data FIFO signals
signal DataFifo_InRdy : std_logic;
@ -127,12 +126,19 @@ architecture rtl of psi_ms_daq_input is
signal TsFifo_AlmFull : std_logic;
signal TsFifo_Empty : std_logic;
-- Clock Crossing Signals
signal PostTrigSpls_Sync : std_logic_vector(PostTrigSpls'range);
signal Mode_Sync : RecMode_t;
signal Arm_Sync : std_logic;
signal RstTmem_Sync : std_logic;
signal RstAcq_Sync : std_logic;
begin
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process( r,
Str_Vld, Str_Data, Str_Trig, Str_Ts, PostTrigSpls, Daq_Rdy, Ts_Rdy, Mode, Str_Arm,
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;
@ -151,8 +157,8 @@ begin
-- Default values
v.DataFifoIsTo := '0';
v.DataFifoIsTrig := '0';
v.ModeReg := Mode;
v.ArmReg := Str_Arm;
v.ModeReg := Mode_Sync;
v.ArmReg := Arm_Sync;
-- Masking trigger according to recording mode
case r.ModeReg is
@ -210,12 +216,12 @@ begin
end if;
elsif (r.TrigLatch = '1') or (TrigMasked_v = '1') then
-- Handle incoming trigger sample
if unsigned(PostTrigSpls) = 0 then
if unsigned(PostTrigSpls_Sync) = 0 then
v.DataFifoIsTrig := '1';
v.DataFifoVld := r.DataFifoVld or r.RecEna;
v.RecEna := '0'; -- stop recording after frame
else
v.PostTrigCnt := unsigned(PostTrigSpls);
v.PostTrigCnt := unsigned(PostTrigSpls_Sync);
end if;
end if;
end if;
@ -273,7 +279,7 @@ begin
end case;
-- Handle Arming Logic
if (r.ModeReg /= Mode) or (r.ModeReg = RecMode_Continuous_c) or (r.ModeReg = RecMode_ManuelMode_c) then -- reset on mode change!
if (r.ModeReg /= Mode_Sync) or (r.ModeReg = RecMode_Continuous_c) or (r.ModeReg = RecMode_ManuelMode_c) then -- reset on mode change!
v.IsArmed := '0';
elsif r.ArmReg = '1' then
v.IsArmed := '1';
@ -295,7 +301,7 @@ begin
end if;
when others => null;
end case;
if r.ModeReg /= Mode then
if r.ModeReg /= Mode_Sync then
v.RecEna := '0';
end if;
@ -330,9 +336,9 @@ begin
--------------------------------------------
-- Output Side TLAST handling
--------------------------------------------
p_outlast : process(Clk)
p_outlast : process(ClkSmem)
begin
if rising_edge(Clk) then
if rising_edge(ClkSmem) then
-- Default Value
Daq_HasLast_I <= '0';
@ -347,7 +353,7 @@ begin
end if;
-- Reset
if Rst = '1' then
if RstSmem = '1' then
OutTlastCnt <= (others => '0');
end if;
end if;
@ -357,41 +363,88 @@ begin
--------------------------------------------
-- Component Instantiation
--------------------------------------------
-- Clock crossing for reset and TLAST counter
-- Only the reset from Tosca is used since resetting the FIFO during a burst could lead to deadlocks.
StatusCcIn(TlastCntWidth_c-1 downto 0) <= r.TLastCnt;
StatusCcIn(TlastCntWidth_c) <= r.IsArmed;
StatusCcIn(TlastCntWidth_c+1) <= r.RecEna;
i_cc : entity work.psi_common_status_cc
-- *** TMEM clock crossings ***
i_cc_tmem_status : entity work.psi_common_status_cc
generic map (
DataWidth_g => TlastCntWidth_c+2
DataWidth_g => 34
)
port map (
ClkA => Str_Clk,
RstInA => '0',
RstOutA => Str_Rst,
DataA => StatusCcIn,
ClkB => Clk,
RstInB => Rst,
DataB => StatusCcOut
ClkA => ClkTmem,
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
);
InTlastCnt <= StatusCcOut(TlastCntWidth_c-1 downto 0);
IsArmed <= StatusCcOut(TlastCntWidth_c);
IsRecording <= StatusCcOut(TlastCntWidth_c+1);
-- Clock crossing for ARM pulse
i_cc_arm : entity work.psi_common_pulse_cc
i_cc_status : entity work.psi_common_bit_cc
generic map (
NumBits_g => 2
)
port map (
BitsA(0) => r.IsArmed,
BitsA(1) => r.RecEna,
ClkB => ClkTmem,
BitsB(0) => IsArmed,
BitsB(1) => IsRecording
);
i_cc_tmem_pulse : entity work.psi_common_pulse_cc
generic map (
NumPulses_g => 1
)
port map (
ClkA => Clk,
RstInA => Rst,
ClkA => ClkTmem,
RstInA => '0',
PulseA(0) => Arm,
ClkB => Str_Clk,
RstInB => Str_Rst,
PulseB(0) => Str_Arm
RstOutB => open,
PulseB(0) => Arm_Sync
);
-- *** Reset Handling ***
icc_tmem_rst : entity work.psi_common_bit_cc
generic map (
NumBits_g => 1
)
port map (
BitsA(0) => RstTmem,
ClkB => Str_Clk,
BitsB(0) => RstTmem_Sync
);
icc_smem_rst : entity work.psi_common_bit_cc
generic map (
NumBits_g => 1
)
port map (
BitsA(0) => RstSmem,
ClkB => Str_Clk,
BitsB(0) => RstAcq_Sync
);
Str_Rst <= RstTmem_Sync or RstAcq_Sync;
-- *** Acquisition Clock Crossing ***
-- Clock crossing for reset and TLAST counter
i_cc : entity work.psi_common_status_cc
generic map (
DataWidth_g => TlastCntWidth_c
)
port map (
ClkA => Str_Clk,
RstInA => Str_Rst,
RstOutA => open,
DataA => r.TLastCnt,
ClkB => ClkSmem,
RstInB => '0',
DataB => InTlastCnt
);
-- Data FIFO
DataFifo_InData(63 downto 0) <= r.DataSftReg;
@ -409,9 +462,9 @@ begin
)
port map (
InClk => Str_Clk,
InRst => '0',
OutClk => Clk,
OutRst => Rst,
InRst => Str_Rst,
OutClk => ClkSmem,
OutRst => '0',
InData => DataFifo_InData,
InVld => r.DataFifoVld,
InRdy => DataFifo_InRdy,
@ -447,9 +500,9 @@ begin
)
port map (
InClk => Str_Clk,
InRst => '0',
OutClk => Clk,
OutRst => Rst,
InRst => Str_Rst,
OutClk => ClkSmem,
OutRst => '0',
InData => r.TsLatch,
InVld => TsFifo_InVld,
InRdy => TsFifo_InRdy,
@ -473,9 +526,9 @@ begin
--------------------------------------------
-- Assertions
--------------------------------------------
p_assert : process(Clk)
p_assert : process(ClkSmem)
begin
if rising_edge(Clk) then
if rising_edge(ClkSmem) then
assert StreamWidth_g = 8 or StreamWidth_g = 16 or StreamWidth_g = 32 or StreamWidth_g = 64 report "###ERROR###: psi_ms_daq_input: StreamWidth_g must be 8, 16, 32 or 64" severity error;
end if;
end process;

View File

@ -20,31 +20,35 @@ entity psi_ms_daq_reg_tmem is
MaxWindows_g : in integer range 1 to 32
);
port (
-- control Ports
ToscaClk : in std_logic;
Rst : in std_logic;
-- TMEM Interface
ClkTmem : in std_logic;
RstTmem : in std_logic;
TmemRqst : in TmemRqst_t;
TmemResp : out TmemResp_t;
-- Context Memory Interface
-- Control Signals (TMEM Clk)
Arm : out std_logic_vector(Streams_g-1 downto 0);
IsArmed : in std_logic_vector(Streams_g-1 downto 0);
IsRecording : in std_logic_vector(Streams_g-1 downto 0);
PostTrig : out t_aslv32(Streams_g-1 downto 0);
RecMode : out t_aslv2(Streams_g-1 downto 0);
IrqOut : out std_logic;
-- SMEM Clock domain control singals
ClkSmem : in std_logic;
RstSmem : in std_logic;
-- Context Memory Interface (SMEM Clk)
CtxStr_Cmd : in ToCtxStr_t;
CtxStr_Resp : out FromCtx_t;
CtxWin_Cmd : in ToCtxWin_t;
CtxWin_Resp : out FromCtx_t;
-- Logic Interface
-- Logic Interface (SMEM Clk)
StrIrq : in std_logic_vector(Streams_g-1 downto 0);
StrEna : out std_logic_vector(Streams_g-1 downto 0);
GlbEna : out std_logic;
IrqOut : out std_logic;
InLevel : in t_aslv16(Streams_g-1 downto 0);
PostTrig : out t_aslv32(Streams_g-1 downto 0);
Arm : out std_logic_vector(Streams_g-1 downto 0);
IsArmed : in std_logic_vector(Streams_g-1 downto 0);
IsRecording : in std_logic_vector(Streams_g-1 downto 0);
RecMode : out t_aslv2(Streams_g-1 downto 0)
StrEna : out std_logic_vector(Streams_g-1 downto 0);
GlbEna : out std_logic;
InLevel : in t_aslv16(Streams_g-1 downto 0)
);
end entity;
@ -55,8 +59,7 @@ architecture rtl of psi_ms_daq_reg_tmem is
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_MaxLvl : t_aslv16(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);
@ -64,6 +67,7 @@ architecture rtl of psi_ms_daq_reg_tmem is
RegRdval : std_logic_vector(63 downto 0);
RdVal : std_logic_vector(63 downto 0);
AddrReg : std_logic_vector(23 downto 0);
MaxLvlClr : std_logic_vector(Streams_g-1 downto 0);
end record;
signal r, r_next : two_process_r;
@ -86,25 +90,25 @@ architecture rtl of psi_ms_daq_reg_tmem is
signal CtxWin_Rdval : std_logic_vector(63 downto 0);
signal CtxWin_AddrB : std_logic_vector(log2ceil(DepthCtxWin_c)-1 downto 0);
signal AddrCtxWin : boolean;
-- Maximum Level Latching
signal MaxLevel : t_aslv16(Streams_g-1 downto 0);
-- Clock Crossing Signals
signal StrIrq_Sync : std_logic_vector(Streams_g-1 downto 0);
signal MaxLevel_Sync : t_aslv16(Streams_g-1 downto 0);
signal MaxLevelClr_Sync : std_logic_vector(Streams_g-1 downto 0);
begin
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process( r, TmemRqst, StrIrq, InLevel, IsArmed, IsRecording, CtxStr_Rdval, CtxWin_Rdval)
p_comb : process( r, TmemRqst, StrIrq_Sync, IsArmed, IsRecording, CtxStr_Rdval, CtxWin_Rdval, MaxLevel)
variable v : two_process_r;
variable Stream_v : integer range 0 to Streams_g-1;
begin
-- *** Hold variables stable ***
v := r;
-- *** Update Maximum Level
for i in 0 to Streams_g-1 loop
if unsigned(InLevel(i)) > unsigned(r.Reg_MaxLvl(i)) then
v.Reg_MaxLvl(i) := InLevel(i);
end if;
end loop;
-- *** General Register Accesses ***
v.RegRdval := (others => '0');
if TmemRqst.ENA = '1' then
@ -150,6 +154,7 @@ begin
-- *** Stream Register Accesses ***
v.Reg_Mode_Arm := (others => '0');
v.MaxLvlClr := (others => '0');
if TmemRqst.ENA = '1' then
if TmemRqst.ADD(23 downto 9) = X"000" & "001" then
Stream_v := to_integer(unsigned(TmemRqst.ADD(8 downto 4)));
@ -158,9 +163,9 @@ begin
if TmemRqst.ADD(3 downto 0) = X"0" then
-- MAXLVLn
if TmemRqst.WE(WeLow_c) = DwWrite_c then
v.Reg_MaxLvl(Stream_v) := (others => '0');
v.MaxLvlClr(Stream_v) := '1';
end if;
v.RegRdval(15 downto 0) := r.Reg_MaxLvl(Stream_v);
v.RegRdval(15 downto 0) := MaxLevel(Stream_v);
-- POSTTRIGn
if TmemRqst.WE(WeHigh_c) = DwWrite_c then
v.Reg_PostTrig(Stream_v) := TmemRqst.DATW(63 downto 32);
@ -198,7 +203,7 @@ begin
-- *** IRQ Handling ***
for i in 0 to Streams_g-1 loop
if (StrIrq(i) = '1') and (r.Reg_StrEna(i) = '1') then
if (StrIrq_Sync(i) = '1') and (r.Reg_StrEna(i) = '1') then
v.Reg_IrqVec(i) := '1';
end if;
end loop;
@ -220,8 +225,6 @@ begin
TmemResp.BUSY <= '0';
TmemResp.DATR <= r.RdVal;
IrqOut <= r.Irq;
StrEna <= r.Reg_StrEna;
GlbEna <= r.Reg_Gcfg_Ena;
PostTrig <= r.Reg_PostTrig;
Arm <= r.Reg_Mode_Arm;
RecMode <= r.Reg_Mode_Recm;
@ -229,29 +232,100 @@ begin
--------------------------------------------
-- Sequential Process
--------------------------------------------
p_seq : process(ToscaClk)
p_seq : process(ClkTmem)
begin
if rising_edge(ToscaClk) then
if rising_edge(ClkTmem) then
r <= r_next;
if Rst = '1' then
if RstTmem = '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_MaxLvl <= (others => (others => '0'));
r.Reg_PostTrig <= (others => (others => '0'));
r.Reg_Mode_Recm <= (others => (others => '0'));
r.Reg_Mode_Arm <= (others => '0');
end if;
end if;
end process;
--------------------------------------------
-- Maximum Level Latching (SmemClk)
--------------------------------------------
p_maxlvl : process(ClkSmem)
begin
if rising_edge(ClkSmem) then
if RstSmem = '1' then
MaxLevel <= (others => (others => '0'));
else
-- Latch maximum level
for i in 0 to Streams_g-1 loop
if MaxLevelClr_Sync(i) = '1' then
MaxLevel(i) <= (others => '0');
elsif unsigned(InLevel(i)) > unsigned(MaxLevel(i)) then
MaxLevel(i) <= InLevel(i);
end if;
end loop;
end if;
end if;
end process;
--------------------------------------------
-- Component Instantiations
--------------------------------------------
-- *** Clock Crossings ***
i_cc_smem_in : entity work.psi_common_pulse_cc
generic map (
NumPulses_g => Streams_g
)
port map (
ClkA => ClkSmem,
RstInA => RstSmem,
PulseA => StrIrq,
ClkB => ClkTmem,
RstInB => RstTmem,
PulseB => StrIrq_Sync
);
blk_cc_smem_out : block
signal ccIn, ccOut : std_logic_vector(Streams_g downto 0);
begin
-- Input Assembly
ccIn(Streams_g-1 downto 0) <= r.Reg_StrEna;
ccIn(Streams_g) <= r.Reg_Gcfg_Ena;
-- Instantiation
i_cc_smem_out : entity work.psi_common_bit_cc
generic map (
NumBits_g => Streams_g+1
)
port map (
BitsA => ccIn,
ClkB => ClkSmem,
BitsB => ccOut
);
-- Output assembly
StrEna <= ccOut(Streams_g-1 downto 0);
GlbEna <= ccOut(Streams_g);
end block;
i_cc_smem_out_pulse : entity work.psi_common_pulse_cc
generic map (
NumPulses_g => Streams_g
)
port map (
ClkA => ClkTmem,
RstInA => RstTmem,
PulseA => r.MaxLvlClr,
ClkB => ClkSmem,
RstInB => RstSmem,
PulseB => MaxLevelClr_Sync
);
-- *** Stream Context Memory ***
-- Signal Assembly
AddrCtxStr <= TmemRqst.ADD(23 downto 12) = X"001";
@ -266,12 +340,12 @@ begin
Width_g => 32
)
port map (
ClkA => ToscaClk,
ClkA => ClkTmem,
AddrA => TmemRqst.ADD(CtxStrAddrHigh_c downto 3),
WrA => CtxStr_WeLo,
DinA => TmemRqst.DATW(31 downto 0),
DoutA => CtxStr_Rdval(31 downto 0),
ClkB => ToscaClk,
ClkB => ClkSmem,
AddrB => CtxStr_AddrB,
WrB => CtxStr_Cmd.WenLo,
DinB => CtxStr_Cmd.WdatLo,
@ -285,12 +359,12 @@ begin
Width_g => 32
)
port map (
ClkA => ToscaClk,
ClkA => ClkTmem,
AddrA => TmemRqst.ADD(CtxStrAddrHigh_c downto 3),
WrA => CtxStr_WeHi,
DinA => TmemRqst.DATW(63 downto 32),
DoutA => CtxStr_Rdval(63 downto 32),
ClkB => ToscaClk,
ClkB => ClkSmem,
AddrB => CtxStr_AddrB,
WrB => CtxStr_Cmd.WenHi,
DinB => CtxStr_Cmd.WdatHi,
@ -313,12 +387,12 @@ begin
Width_g => 32
)
port map (
ClkA => ToscaClk,
ClkA => ClkTmem,
AddrA => TmemRqst.ADD(CtxWinAddrHigh_c downto 3),
WrA => CtxWin_WeLo,
DinA => TmemRqst.DATW(31 downto 0),
DoutA => CtxWin_Rdval(31 downto 0),
ClkB => ToscaClk,
ClkB => ClkSmem,
AddrB => CtxWin_AddrB,
WrB => CtxWin_Cmd.WenLo,
DinB => CtxWin_Cmd.WdatLo,
@ -332,12 +406,12 @@ begin
Width_g => 32
)
port map (
ClkA => ToscaClk,
ClkA => ClkTmem,
AddrA => TmemRqst.ADD(CtxWinAddrHigh_c downto 3),
WrA => CtxWin_WeHi,
DinA => TmemRqst.DATW(63 downto 32),
DoutA => CtxWin_Rdval(63 downto 32),
ClkB => ToscaClk,
ClkB => ClkSmem,
AddrB => CtxWin_AddrB,
WrB => CtxWin_Cmd.WenHi,
DinB => CtxWin_Cmd.WdatHi,

View File

@ -21,6 +21,7 @@ add_sources $LibPath {
psi_common/hdl/psi_common_logic_pkg.vhd \
psi_common/hdl/psi_common_sdp_ram_rbw.vhd \
psi_common/hdl/psi_common_pulse_cc.vhd \
psi_common/hdl/psi_common_bit_cc.vhd \
psi_common/hdl/psi_common_simple_cc.vhd \
psi_common/hdl/psi_common_status_cc.vhd \
psi_common/hdl/psi_common_async_fifo.vhd \

View File

@ -56,7 +56,8 @@ architecture sim of psi_ms_daq_tb is
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 Tosca_Clk : std_logic := '0';
signal Tmem_Clk : std_logic := '0';
signal Smem_Clk : std_logic := '0';
signal Tmem_Rst : std_logic := '1';
signal Smem_Rst : std_logic := '1';
signal TmemAcq : TmemRqst_t := TmemRqst_init_c;
@ -88,7 +89,10 @@ architecture sim of psi_ms_daq_tb is
end case;
end if;
end loop;
wait until rising_edge(clk);
-- Delay to ensure IRQ is cleared
for i in 0 to 5 loop
wait until rising_edge(clk);
end loop;
end procedure;
@ -124,8 +128,9 @@ begin
Str_Vld => Str_Vld,
Str_Rdy => Str_Rdy,
Str_Trig => Str_Trig,
Tosca_Clk => Tosca_Clk,
Tmem_Clk => Tmem_Clk,
Tmem_Rst => Tmem_Rst,
Smem_Clk => Smem_Clk,
Smem_Rst => Smem_Rst,
TmemAcq => TmemAcq,
AcqTmem => AcqTmem,
@ -142,22 +147,22 @@ begin
variable Size_v : integer;
begin
while TbRunning loop
wait until (rising_edge(Tosca_Clk) and AcqSmem.WREQ = SMEM_REQ_Request_c) or (not TbRunning);
wait until (rising_edge(Smem_Clk) and AcqSmem.WREQ = SMEM_REQ_Request_c) or (not TbRunning);
if TbRunning then
wait until rising_edge(Tosca_Clk);
wait until rising_edge(Smem_Clk);
Address_v := to_integer(unsigned(AcqSmem.WADD));
Size_v := to_integer(unsigned(AcqSmem.WSIZ));
SmemAcq.WACK <= SMEM_ACK_Grant_c;
wait until rising_edge(Tosca_Clk);
wait until rising_edge(Smem_Clk);
SmemAcq.WACK <= SMEM_ACK_Burst_c;
wait until rising_edge(Tosca_Clk);
wait until rising_edge(Tosca_Clk);
wait until rising_edge(Tosca_Clk);
wait until rising_edge(Smem_Clk);
wait until rising_edge(Smem_Clk);
wait until rising_edge(Smem_Clk);
for qw in 0 to Size_v-1 loop
if qw = Size_v-1 then
SmemAcq.WACK <= SMEM_ACK_Done_c;
end if;
wait until rising_edge(Tosca_Clk);
wait until rising_edge(Smem_Clk);
for byte in 0 to 7 loop
if AcqSmem.WBE(byte) = '1' then
Memory(Address_v+qw*8+byte) <= AcqSmem.WDAT(byte*8+7 downto byte*8);
@ -165,7 +170,7 @@ begin
end loop;
end loop;
SmemAcq.WACK <= SMEM_ACK_Idle_c;
wait until rising_edge(Tosca_Clk);
wait until rising_edge(Smem_Clk);
end if;
end loop;
wait;
@ -175,16 +180,26 @@ begin
-- Clocks
------------------------------------------------------------
p_clk_tosca : process
p_clk_smem : process
constant Frequency_c : real := real(200e6);
begin
while TbRunning loop
wait for 0.5*(1 sec)/Frequency_c;
Tosca_Clk <= not Tosca_Clk;
Smem_Clk <= not Smem_Clk;
end loop;
wait;
end process;
p_clk_tmem : process
constant Frequency_c : real := real(166e6);
begin
while TbRunning loop
wait for 0.5*(1 sec)/Frequency_c;
Tmem_Clk <= not Tmem_Clk;
end loop;
wait;
end process;
g_clk_str : for i in 0 to StrCount_c-1 generate
p_clk_str : process
begin
@ -213,32 +228,32 @@ begin
Smem_Rst <= '0';
-- *** Initial Configuration ***
TmemExpect32(16#0010#, 0, Tosca_Clk, TmemAcq, AcqTmem);
TmemWriteAndRead32(16#0014#, 16#000F#, Tosca_Clk, TmemAcq, AcqTmem);
TmemWriteAndRead32(16#0020#, 16#000F#, Tosca_Clk, TmemAcq, AcqTmem);
TmemExpect32(16#0010#, 0, Tmem_Clk, TmemAcq, AcqTmem);
TmemWriteAndRead32(16#0014#, 16#000F#, Tmem_Clk, TmemAcq, AcqTmem);
TmemWriteAndRead32(16#0020#, 16#000F#, Tmem_Clk, TmemAcq, AcqTmem);
-- Stream Setup
Str0Setup(Tosca_Clk, TmemAcq, AcqTmem);
Str1Setup(Tosca_Clk, TmemAcq, AcqTmem);
Str2Setup(Tosca_Clk, TmemAcq, AcqTmem);
Str3Setup(Tosca_Clk, TmemAcq, AcqTmem);
Str0Setup(Tmem_Clk, TmemAcq, AcqTmem);
Str1Setup(Tmem_Clk, TmemAcq, AcqTmem);
Str2Setup(Tmem_Clk, TmemAcq, AcqTmem);
Str3Setup(Tmem_Clk, TmemAcq, AcqTmem);
-- Enable
TmemWriteAndRead32(16#0000#, 16#0101#, Tosca_Clk, TmemAcq, AcqTmem);
TmemWriteAndRead32(16#0000#, 16#0101#, Tmem_Clk, TmemAcq, AcqTmem);
-- *** Run Test ***
StartTime_v := now;
while now < StartTime_v+100 us loop
wait until rising_edge(Tosca_Clk);
wait until rising_edge(Tmem_Clk);
-- IRQ Handling
if Irq = '1' then
IrqHandler(Tosca_Clk, TmemAcq, AcqTmem);
IrqHandler(Tmem_Clk, TmemAcq, AcqTmem);
end if;
-- Regular actions
Str0Update(Tosca_Clk, TmemAcq, AcqTmem);
Str1Update(Tosca_Clk, TmemAcq, AcqTmem);
Str2Update(Tosca_Clk, TmemAcq, AcqTmem);
Str3Update(Tosca_Clk, TmemAcq, AcqTmem);
Str0Update(Tmem_Clk, TmemAcq, AcqTmem);
Str1Update(Tmem_Clk, TmemAcq, AcqTmem);
Str2Update(Tmem_Clk, TmemAcq, AcqTmem);
Str3Update(Tmem_Clk, TmemAcq, AcqTmem);
end loop;
TbRunning <= false;

View File

@ -123,6 +123,8 @@ package body psi_ms_daq_tb_str0_pkg is
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);
@ -134,7 +136,10 @@ package body psi_ms_daq_tb_str0_pkg is
print("Skipped, stream disabled", PrintStr0_c);
print("", PrintStr0_c);
else
while Str0NextWin /= curwin loop
HlIsTrigWin(0, Str0NextWin, clk, rqst, rsp, HasTrigger);
-- curwin = nextwin can occur if al lwindows are filled. In all cases we only interpret windows containing triggers.
while ((Str0NextWin /= curwin) or firstLoop) and HasTrigger loop
firstLoop := false;
print("*** Window " & to_string(Str0NextWin) & " / Number: " & to_string(Str0WinCheck) & " ***", PrintStr0_c);
HlGetWinCnt(0, Str0NextWin, clk, rqst, rsp, wincnt);
print("WINCNT: " & to_string(wincnt), PrintStr0_c);

View File

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