DEVEL: Implemented handling for first access after enable (not tested yet)
This commit is contained in:
@ -41,6 +41,8 @@ entity psi_ms_daq_daq_sm is
|
||||
-- Control signals
|
||||
Clk : in std_logic; -- $$ type=clk; freq=200e6; proc=control,dma_cmd,dma_resp,ctx $$
|
||||
Rst : in std_logic; -- $$ proc=control $$
|
||||
GlbEna : in std_logic; -- $$ proc=control $$
|
||||
StrEna : in std_logic_vector(Streams_g-1 downto 0); -- $$ proc=control $$
|
||||
|
||||
-- Input logic Connections
|
||||
Inp_HasLast : in std_logic_vector(Streams_g-1 downto 0); -- $$ proc=control $$
|
||||
@ -111,16 +113,19 @@ architecture rtl of psi_ms_daq_daq_sm is
|
||||
signal GrantVld : std_logic_vector(3 downto 1);
|
||||
|
||||
-- Types
|
||||
type State_t is (Idle_s, CheckPrio1_s, CheckPrio2_s, CheckPrio3_s, CheckResp_s, TlastCheck_s, ReadCtxStr_s, ReadCtxWin_s, CalcAccess0_s, CalcAccess1_s, ProcResp0_s, NextWin_s, WriteCtx_s);
|
||||
type State_t is (Idle_s, CheckPrio1_s, CheckPrio2_s, CheckPrio3_s, CheckResp_s, TlastCheck_s, ReadCtxStr_s, First_s, ReadCtxWin_s, CalcAccess0_s, CalcAccess1_s, ProcResp0_s, NextWin_s, WriteCtx_s);
|
||||
|
||||
-- Two process method
|
||||
type two_process_r is record
|
||||
GlbEnaReg : std_logic;
|
||||
StrEnaReg : std_logic_vector(Streams_g-1 downto 0);
|
||||
InpDataAvail : std_logic_vector(Streams_g-1 downto 0);
|
||||
DataAvailArbIn : std_logic_vector(Streams_g-1 downto 0);
|
||||
DataPending : std_logic_vector(Streams_g-1 downto 0);
|
||||
OpenCommand : std_logic_vector(Streams_g-1 downto 0);
|
||||
WinProtected : std_logic_vector(Streams_g-1 downto 0); -- Set if the current window is not yet available
|
||||
NewBuffer : std_logic_vector(Streams_g-1 downto 0);
|
||||
FirstAfterEna : std_logic_vector(Streams_g-1 downto 0);
|
||||
GrantRdy : std_logic_vector(3 downto 1);
|
||||
GrantVldReg : std_logic_vector(3 downto 1);
|
||||
State : State_t;
|
||||
@ -162,7 +167,7 @@ begin
|
||||
--------------------------------------------
|
||||
-- Combinatorial Process
|
||||
--------------------------------------------
|
||||
p_comb : process( r, Inp_HasLast, Inp_Level, Ts_Vld, Ts_Data, Dma_Resp, Dma_Resp_Vld, CtxStr_Resp, CtxWin_Resp,
|
||||
p_comb : process( r, Inp_HasLast, Inp_Level, Ts_Vld, Ts_Data, Dma_Resp, Dma_Resp_Vld, CtxStr_Resp, CtxWin_Resp, GlbEna, StrEna,
|
||||
GrantVld, GrantPrio1, GrantPrio2, GrantPrio3)
|
||||
variable v : two_process_r;
|
||||
begin
|
||||
@ -192,6 +197,8 @@ begin
|
||||
v.GrantPrio2Reg := GrantPrio2;
|
||||
v.GrantPrio3Reg := GrantPrio3;
|
||||
v.HasLastReg := Inp_HasLast;
|
||||
v.StrEnaReg := StrEna;
|
||||
v.GlbEnaReg := GlbEna;
|
||||
|
||||
-- *** Check Availability of a full burst ***
|
||||
for str in 0 to Streams_g-1 loop
|
||||
@ -292,7 +299,7 @@ begin
|
||||
when ReadCtxStr_s =>
|
||||
-- State handling
|
||||
if r.HndlCtxCnt = 4 then
|
||||
v.State := ReadCtxWin_s;
|
||||
v.State := First_s;
|
||||
v.HndlCtxCnt := 0;
|
||||
else
|
||||
v.HndlCtxCnt := r.HndlCtxCnt + 1;
|
||||
@ -325,6 +332,22 @@ begin
|
||||
when others => null;
|
||||
end case;
|
||||
|
||||
-- Handle first access after enable
|
||||
when First_s =>
|
||||
-- State handling
|
||||
v.State := ReadCtxWin_s;
|
||||
|
||||
-- Update values for first access
|
||||
if r.FirstAfterEna(r.HndlStream) = '1' then
|
||||
v.FirstAfterEna(r.HndlStream) := '0';
|
||||
v.HndlWinEnd := std_logic_vector(unsigned(r.HndlBufstart) + unsigned(r.HndlWinSize));
|
||||
v.HndlPtr := r.HndlBufstart;
|
||||
v.HndlWincur := (others => '0');
|
||||
v.Hndl4kMax := std_logic_vector(to_unsigned(4096, 13) - unsigned(r.HndlBufstart(11 downto 0)));
|
||||
v.HndlWinMax := r.HndlWinSize;
|
||||
end if;
|
||||
|
||||
|
||||
-- Read information from window memory
|
||||
when ReadCtxWin_s =>
|
||||
-- State handling
|
||||
@ -479,6 +502,14 @@ begin
|
||||
when others => null;
|
||||
end case;
|
||||
end case;
|
||||
|
||||
-- *** Handle Disabled Streams ***
|
||||
for str in 0 to Streams_g-1 loop
|
||||
if (r.GlbEnaReg = '0') or (r.StrEnaReg(str) = '0') then
|
||||
v.FirstAfterEna(str) := '1';
|
||||
v.NewBuffer(str) := '1';
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
|
||||
-- *** Assign to signal ***
|
||||
@ -519,7 +550,7 @@ begin
|
||||
r.WinProtected <= (others => '0');
|
||||
r.Dma_Resp_Rdy <= '0';
|
||||
r.Ts_Rdy <= (others => '0');
|
||||
r.NewBuffer <= (others => '1'); -- Remember for enable!
|
||||
r.GlbEnaReg <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
@ -97,6 +97,8 @@ begin
|
||||
port map (
|
||||
Clk => Clk,
|
||||
Rst => Rst,
|
||||
GlbEna => '1',
|
||||
StrEna => (others => '1'),
|
||||
Inp_HasLast => Inp_HasLast,
|
||||
Inp_Level => Inp_Level,
|
||||
Ts_Vld => Ts_Vld,
|
||||
|
@ -96,10 +96,22 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
wait until rising_edge(Clk);
|
||||
end loop;
|
||||
ControlWaitCompl(Clk);
|
||||
|
||||
|
||||
-- First transfer after startup, 4k Aligned
|
||||
-- .. This is required to bypass all special handling for the first transfer after enabling a stream.
|
||||
print(">> First transfer after startup, 4k Aligned");
|
||||
TestCase := 2;
|
||||
for str in 0 to 3 loop
|
||||
Inp_Level(str) <= std_logic_vector(to_unsigned(Size4k_c/DataWidthBytes_c, Inp_Level(str)'length));
|
||||
wait until rising_edge(Clk) and Dma_Cmd_Vld = '1';
|
||||
Inp_Level(str) <= (others => '0');
|
||||
wait for 1 us;
|
||||
end loop;
|
||||
ControlWaitCompl(Clk);
|
||||
|
||||
-- Check a single 4k aligned burst on stream 1
|
||||
print(">> most simple 4k Aligned transfer");
|
||||
TestCase := 2;
|
||||
TestCase := 3;
|
||||
Inp_Level(1) <= std_logic_vector(to_unsigned(Size4k_c/DataWidthBytes_c, Inp_Level(0)'length));
|
||||
wait until rising_edge(Clk) and Dma_Cmd_Vld = '1';
|
||||
Inp_Level(1) <= (others => '0');
|
||||
@ -107,7 +119,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
|
||||
-- Check two 4k Transfers in a row on stream 0
|
||||
print(">> two 4k Aligned transfers");
|
||||
TestCase := 3;
|
||||
TestCase := 4;
|
||||
Inp_Level(0) <= std_logic_vector(to_unsigned(Size4k_c/DataWidthBytes_c, Inp_Level(0)'length));
|
||||
wait until rising_edge(Clk) and Dma_Cmd_Vld = '1';
|
||||
wait until rising_edge(Clk) and Dma_Cmd_Vld = '1';
|
||||
@ -116,7 +128,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
|
||||
-- Check maximum Transfer size limitation
|
||||
print(">> Transfer size limitation to 4k");
|
||||
TestCase := 4;
|
||||
TestCase := 5;
|
||||
Inp_Level(0) <= std_logic_vector(to_unsigned(Size4k_c*2/DataWidthBytes_c, Inp_Level(0)'length));
|
||||
wait until rising_edge(Clk) and Dma_Cmd_Vld = '1';
|
||||
Inp_Level(0) <= (others => '0');
|
||||
@ -124,7 +136,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
|
||||
-- Check 4k boundary limitation
|
||||
print(">> Check 4k boundary limitation");
|
||||
TestCase := 5;
|
||||
TestCase := 6;
|
||||
Inp_Level(0) <= std_logic_vector(to_unsigned(Size4k_c/DataWidthBytes_c, Inp_Level(0)'length));
|
||||
wait until rising_edge(Clk) and Dma_Cmd_Vld = '1';
|
||||
Inp_Level(0) <= (others => '0');
|
||||
@ -132,7 +144,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
|
||||
-- Check window size limitation
|
||||
print(">> Check window size limitation");
|
||||
TestCase := 6;
|
||||
TestCase := 7;
|
||||
Inp_Level(1) <= std_logic_vector(to_unsigned(Size4k_c/DataWidthBytes_c, Inp_Level(0)'length));
|
||||
wait until rising_edge(Clk) and Dma_Cmd_Vld = '1';
|
||||
Inp_Level(1) <= (others => '0');
|
||||
@ -140,7 +152,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
|
||||
-- check response smaller than request
|
||||
print(">> check response smaller than request");
|
||||
TestCase := 7;
|
||||
TestCase := 8;
|
||||
Inp_Level(1) <= std_logic_vector(to_unsigned(Size4k_c/DataWidthBytes_c, Inp_Level(0)'length));
|
||||
wait until rising_edge(Clk) and Dma_Cmd_Vld = '1';
|
||||
Inp_Level(1) <= (others => '0');
|
||||
@ -175,8 +187,20 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
end loop;
|
||||
ProcDone(2) := '1';
|
||||
|
||||
-- Check a single 4k aligned burst on stream 1
|
||||
-- First transfer after startup, 4k Aligned
|
||||
WaitForCase(2, Clk);
|
||||
for str in 0 to 3 loop
|
||||
ExpectDmaCmd( Stream => str,
|
||||
Address => 16#01230000#,
|
||||
MaxSize => Size4k_c,
|
||||
Clk => Clk,
|
||||
Dma_Cmd => Dma_Cmd,
|
||||
Dma_Vld => Dma_Cmd_Vld);
|
||||
end loop;
|
||||
ProcDone(2) := '1';
|
||||
|
||||
-- Check a single 4k aligned burst on stream 1
|
||||
WaitForCase(3, Clk);
|
||||
ExpectDmaCmd( Stream => 1,
|
||||
Address => 16#01238000#,
|
||||
MaxSize => Size4k_c,
|
||||
@ -186,19 +210,20 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(2) := '1';
|
||||
|
||||
-- Check two 4k Transfers in a row on stream 0
|
||||
WaitForCase(3, Clk);
|
||||
WaitForCase(4, Clk);
|
||||
for i in 0 to 1 loop
|
||||
ExpectDmaCmd( Stream => 0,
|
||||
Address => 16#01238000# + i*16#1000#,
|
||||
MaxSize => Size4k_c,
|
||||
Clk => Clk,
|
||||
Dma_Cmd => Dma_Cmd,
|
||||
Dma_Vld => Dma_Cmd_Vld);
|
||||
Dma_Vld => Dma_Cmd_Vld,
|
||||
Msg => "Tf" & to_string(i));
|
||||
end loop;
|
||||
ProcDone(2) := '1';
|
||||
|
||||
-- Check maximum Transfer size limitation
|
||||
WaitForCase(4, Clk);
|
||||
WaitForCase(5, Clk);
|
||||
ExpectDmaCmd( Stream => 0,
|
||||
Address => 16#01238000#,
|
||||
MaxSize => Size4k_c,
|
||||
@ -208,7 +233,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(2) := '1';
|
||||
|
||||
-- Check 4k boundary limitation
|
||||
WaitForCase(5, Clk);
|
||||
WaitForCase(6, Clk);
|
||||
ExpectDmaCmd( Stream => 0,
|
||||
Address => 16#01238000#+384,
|
||||
MaxSize => Size4k_c-384,
|
||||
@ -218,7 +243,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(2) := '1';
|
||||
|
||||
-- Check window size limitation
|
||||
WaitForCase(6, Clk);
|
||||
WaitForCase(7, Clk);
|
||||
ExpectDmaCmd( Stream => 1,
|
||||
Address => 16#01230000#,
|
||||
MaxSize => 502,
|
||||
@ -228,7 +253,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(2) := '1';
|
||||
|
||||
-- check response smaller than request
|
||||
WaitForCase(7, Clk);
|
||||
WaitForCase(8, Clk);
|
||||
ExpectDmaCmd( Stream => 1,
|
||||
Address => 16#01230000#,
|
||||
MaxSize => Size4k_c,
|
||||
@ -265,8 +290,23 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
end loop;
|
||||
ProcDone(1) := '1';
|
||||
|
||||
-- Check a single 4k aligned burst on stream 1
|
||||
-- First transfer after startup, 4k Aligned
|
||||
WaitForCase(2, Clk);
|
||||
for str in 0 to 3 loop
|
||||
ApplyDmaResp( Stream => str,
|
||||
Size => Size4k_c,
|
||||
Trigger => '0',
|
||||
Delay => 200 ns,
|
||||
Clk => Clk,
|
||||
Dma_Resp => Dma_Resp,
|
||||
Dma_Resp_Vld => Dma_Resp_Vld,
|
||||
Dma_Resp_Rdy => Dma_Resp_Rdy);
|
||||
end loop;
|
||||
ProcDone(1) := '1';
|
||||
|
||||
|
||||
-- Check a single 4k aligned burst on stream 1
|
||||
WaitForCase(3, Clk);
|
||||
ApplyDmaResp( Stream => 1,
|
||||
Size => Size4k_c,
|
||||
Trigger => '0',
|
||||
@ -278,7 +318,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(1) := '1';
|
||||
|
||||
-- Check two 4k Transfers in a row on stream 0
|
||||
WaitForCase(3, Clk);
|
||||
WaitForCase(4, Clk);
|
||||
for i in 0 to 1 loop
|
||||
ApplyDmaResp( Stream => 0,
|
||||
Size => Size4k_c,
|
||||
@ -287,12 +327,13 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
Clk => Clk,
|
||||
Dma_Resp => Dma_Resp,
|
||||
Dma_Resp_Vld => Dma_Resp_Vld,
|
||||
Dma_Resp_Rdy => Dma_Resp_Rdy);
|
||||
Dma_Resp_Rdy => Dma_Resp_Rdy,
|
||||
Msg => "Tf" & to_string(i));
|
||||
end loop;
|
||||
ProcDone(1) := '1';
|
||||
|
||||
-- Check maximum Transfer size limitation
|
||||
WaitForCase(4, Clk);
|
||||
WaitForCase(5, Clk);
|
||||
ApplyDmaResp( Stream => 0,
|
||||
Size => Size4k_c,
|
||||
Trigger => '0',
|
||||
@ -303,7 +344,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(1) := '1';
|
||||
|
||||
-- Check 4k boundary limitation
|
||||
WaitForCase(5, Clk);
|
||||
WaitForCase(6, Clk);
|
||||
ApplyDmaResp( Stream => 0,
|
||||
Size => Size4k_c-384,
|
||||
Trigger => '0',
|
||||
@ -314,7 +355,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(1) := '1';
|
||||
|
||||
-- Check window size limitation
|
||||
WaitForCase(6, Clk);
|
||||
WaitForCase(7, Clk);
|
||||
ApplyDmaResp( Stream => 1,
|
||||
Size => 502,
|
||||
Trigger => '0',
|
||||
@ -325,7 +366,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(1) := '1';
|
||||
|
||||
-- check response smaller than request
|
||||
WaitForCase(7, Clk);
|
||||
WaitForCase(8, Clk);
|
||||
ApplyDmaResp( Stream => 1,
|
||||
Size => 500,
|
||||
Trigger => '0',
|
||||
@ -345,7 +386,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
signal CtxWin_Resp : inout FromCtx_t;
|
||||
constant Generics_c : Generics_t) is
|
||||
variable StartTime_v : time;
|
||||
variable PtrStr1_v : integer := 16#01238000#;
|
||||
variable PtrStr1_v : integer;
|
||||
begin
|
||||
-- Check Steady behavior
|
||||
WaitForCase(0, Clk);
|
||||
@ -371,8 +412,27 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
end loop;
|
||||
ProcDone(0) := '1';
|
||||
|
||||
-- Check a single 4k aligned burst on stream 1
|
||||
-- First transfer after startup, 4k Aligned
|
||||
WaitForCase(2, Clk);
|
||||
for str in 0 to 3 loop
|
||||
PtrStr1_v := 16#01230000#;
|
||||
ExpCtxFullBurst( Stream => str,
|
||||
TfSize => Size4k_c,
|
||||
PtrBefore => PtrStr1_v,
|
||||
SamplesWinBefore => 0,
|
||||
PtrAfter => PtrStr1_v,
|
||||
Clk => Clk,
|
||||
CtxStr_Cmd => CtxStr_Cmd,
|
||||
CtxStr_Resp => CtxStr_Resp,
|
||||
CtxWin_Cmd => CtxWin_Cmd,
|
||||
CtxWin_Resp => CtxWin_Resp,
|
||||
Msg => "Str" & to_string(str));
|
||||
end loop;
|
||||
ProcDone(0) := '1';
|
||||
|
||||
-- Check a single 4k aligned burst on stream 1
|
||||
WaitForCase(3, Clk);
|
||||
PtrStr1_v := 16#01238000#;
|
||||
ExpCtxFullBurst( Stream => 1,
|
||||
TfSize => Size4k_c,
|
||||
PtrBefore => PtrStr1_v,
|
||||
@ -386,7 +446,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(0) := '1';
|
||||
|
||||
-- Check two 4k Transfers in a row on stream 0
|
||||
WaitForCase(3, Clk);
|
||||
WaitForCase(4, Clk);
|
||||
PtrStr1_v := 16#01238000#;
|
||||
for i in 0 to 1 loop
|
||||
ExpCtxFullBurst( Stream => 0,
|
||||
@ -403,7 +463,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(0) := '1';
|
||||
|
||||
-- Check maximum Transfer size limitation
|
||||
WaitForCase(4, Clk);
|
||||
WaitForCase(5, Clk);
|
||||
PtrStr1_v := 16#01238000#;
|
||||
ExpCtxFullBurst( Stream => 0,
|
||||
TfSize => Size4k_c,
|
||||
@ -418,7 +478,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(0) := '1';
|
||||
|
||||
-- Check 4k boundary limitation
|
||||
WaitForCase(5, Clk);
|
||||
WaitForCase(6, Clk);
|
||||
PtrStr1_v := 16#01238000#+384;
|
||||
ExpCtxFullBurst( Stream => 0,
|
||||
TfSize => Size4k_c-384,
|
||||
@ -434,7 +494,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(0) := '1';
|
||||
|
||||
-- Check window size limitation
|
||||
WaitForCase(6, Clk);
|
||||
WaitForCase(7, Clk);
|
||||
PtrStr1_v := 16#01230000#;
|
||||
ExpCtxFullBurst( Stream => 1,
|
||||
BufStart => 16#01230000#,
|
||||
@ -452,7 +512,7 @@ package body psi_ms_daq_daq_sm_tb_case_single_simple is
|
||||
ProcDone(0) := '1';
|
||||
|
||||
-- check response smaller than request
|
||||
WaitForCase(7, Clk);
|
||||
WaitForCase(8, Clk);
|
||||
PtrStr1_v := 16#01230000#;
|
||||
ExpCtxFullBurst( Stream => 1,
|
||||
BufStart => 16#01230000#,
|
||||
|
Reference in New Issue
Block a user