DEVEL: Implemented handling for first access after enable (not tested yet)

This commit is contained in:
Oliver Bruendler
2018-07-10 10:03:06 +02:00
parent fd2790c6e6
commit cac231412b
3 changed files with 125 additions and 32 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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#,