DEVEL: Worked on DMA (unaligned transfers)
This commit is contained in:
@ -78,7 +78,7 @@ architecture rtl of psi_ms_daq_daq_dma is
|
||||
signal Rem_Data : std_logic_vector(63 downto 0);
|
||||
|
||||
-- Types
|
||||
type State_t is (Idle_s, RemRd1_s, RemRd2_s, Transfer_s, Done_s, Cmd_s);
|
||||
type State_t is (Idle_s, RemRd1_s, RemRd2_s, Start_s, Transfer_s, Done_s, Cmd_s);
|
||||
|
||||
-- Two process method
|
||||
type two_process_r is record
|
||||
@ -99,14 +99,14 @@ architecture rtl of psi_ms_daq_daq_dma is
|
||||
DataLast : std_logic_vector(63 downto 0);
|
||||
DataCur : std_logic_vector(63 downto 0);
|
||||
DataCurVld : std_logic;
|
||||
UpdateLast : std_logic;
|
||||
HndlSft : unsigned(2 downto 0);
|
||||
FirstDma : std_logic_vector(Streams_g-1 downto 0);
|
||||
DataMux : std_logic_vector(63 downto 0);
|
||||
MuxInVld : std_logic;
|
||||
DataMuxVld : std_logic;
|
||||
Inp_Rdy : std_logic_vector(Streams_g-1 downto 0);
|
||||
Mem_CmdVld : std_logic;
|
||||
Trigger : std_logic;
|
||||
DataRaw : std_logic_vector(63 downto 0);
|
||||
end record;
|
||||
signal r, r_next : two_process_r;
|
||||
|
||||
@ -120,16 +120,19 @@ begin
|
||||
variable v : two_process_r;
|
||||
variable ThisByte_v : std_logic_vector(7 downto 0);
|
||||
variable ByteIdx_v : integer range 0 to 7;
|
||||
variable MuxInVld_v : std_logic;
|
||||
begin
|
||||
-- *** Hold variables stable ***
|
||||
v := r;
|
||||
|
||||
-- *** Default Values ***
|
||||
v.CmdFifo_Rdy := '0';
|
||||
v.Inp_Rdy := (others => '0');
|
||||
Inp_Rdy <= (others => '0');
|
||||
v.Mem_DataVld := '0';
|
||||
v.RspFifo_Vld := '0';
|
||||
v.MuxInVld := '0';
|
||||
MuxInVld_v := '0';
|
||||
v.RemWen := '0';
|
||||
v.UpdateLast := '0';
|
||||
|
||||
-- *** State Machine ***
|
||||
case r.State is
|
||||
@ -150,18 +153,23 @@ begin
|
||||
when RemRd2_s =>
|
||||
-- TODO: Handle empty timeout sample
|
||||
-- TODO: Very short TFs (no read from FIFO)
|
||||
-- TODO: Handle end of transfer because no more data
|
||||
|
||||
-- Prevent RAM data from before reset to have an influence
|
||||
if r.FirstDma(r.HndlStream) = '1' then
|
||||
v.HndlSft := (others => '0');
|
||||
v.HndlSize := (others => '0');
|
||||
else
|
||||
v.HndlSft := unsigned(Rem_RdBytes);
|
||||
v.HndlSft := to_unsigned(0, 3) - unsigned(Rem_RdBytes);
|
||||
v.DataLast := Rem_Data;
|
||||
v.HndlSize := resize(unsigned(Rem_RdBytes), v.HndlMaxSize'length);
|
||||
end if;
|
||||
v.FirstDma(r.HndlStream) := '0';
|
||||
v.State := Transfer_s;
|
||||
v.State := Start_s;
|
||||
|
||||
when Start_s =>
|
||||
v.State := Transfer_s;
|
||||
v.UpdateLast := '1';
|
||||
|
||||
when Transfer_s =>
|
||||
-- TF done because of maximum size reached
|
||||
@ -172,8 +180,9 @@ begin
|
||||
v.Trigger := Inp_Data(r.HndlStream).IsTrig;
|
||||
elsif DatFifo_AlmFull = '0' then
|
||||
v.HndlSize := r.HndlSize + unsigned(Inp_Data(r.HndlStream).Bytes);
|
||||
v.Inp_Rdy(r.HndlStream) := '1';
|
||||
v.MuxInVld := '1';
|
||||
-- Combinatorial handling because of fall-through interface at input
|
||||
Inp_Rdy(r.HndlStream) <= '1';
|
||||
MuxInVld_v := '1';
|
||||
end if;
|
||||
|
||||
when Done_s =>
|
||||
@ -189,6 +198,7 @@ begin
|
||||
when Cmd_s =>
|
||||
if Mem_CmdRdy = '1' then
|
||||
v.State := Idle_s;
|
||||
v.RemWen := '1';
|
||||
v.Mem_CmdVld := '0';
|
||||
v.RspFifo_Vld := '1';
|
||||
v.RspFifo_Data.Size := std_logic_vector(r.HndlSize);
|
||||
@ -200,31 +210,38 @@ begin
|
||||
end case;
|
||||
|
||||
-- *** Data Multiplexer ***
|
||||
v.DataMux := Inp_Data(r.HndlStream).Data;
|
||||
v.DataMuxVld := r.MuxInVld;
|
||||
if r.State = RemRd2_s then
|
||||
v.DataMux := Rem_Data;
|
||||
else
|
||||
v.DataMux := Inp_Data(r.HndlStream).Data;
|
||||
end if;
|
||||
v.DataMuxVld := MuxInVld_v;
|
||||
if r.DataMuxVld = '1' then
|
||||
v.DataRaw := r.DataMux;
|
||||
end if;
|
||||
|
||||
-- *** Data Alignment ***
|
||||
v.DataCurVld := '0';
|
||||
if r.DataMuxVld = '1' then
|
||||
v.DataCurVld := '1';
|
||||
v.DataCurVld := r.DataMuxVld;
|
||||
if r.DataMuxVld = '1' or r.State = Start_s then
|
||||
for i in 0 to 7 loop
|
||||
ByteIdx_v := (i-to_integer(r.HndlSft)+8) mod 8;
|
||||
ByteIdx_v := (i+to_integer(r.HndlSft)) mod 8;
|
||||
v.DataCur(8*(i+1)-1 downto 8*i) := r.DataMux(8*(ByteIdx_v+1)-1 downto 8*ByteIdx_v);
|
||||
end loop;
|
||||
end if;
|
||||
if r.DataCurVld = '1' then
|
||||
v.Mem_DataVld := r.DataCurVld;
|
||||
if (r.DataCurVld = '1') or (r.UpdateLast = '1') then
|
||||
for i in 0 to 7 loop
|
||||
if i < r.HndlSft then
|
||||
if i < 8-r.HndlSft then
|
||||
ThisByte_v := r.DataLast(8*(i+1)-1 downto 8*i);
|
||||
else
|
||||
ThisByte_v := r.DataCur(8*(i+1)-1 downto 8*i);
|
||||
end if;
|
||||
v.Mem_Data(8*(i+1)-1 downto 8*i) := ThisByte_v;
|
||||
end loop;
|
||||
v.Mem_DataVld := '1';
|
||||
v.DataLast := r.DataCur;
|
||||
end if;
|
||||
|
||||
|
||||
-- *** Assign to signal ***
|
||||
r_next <= v;
|
||||
|
||||
@ -234,7 +251,6 @@ begin
|
||||
Mem_CmdAddr <= r.HndlAddress;
|
||||
Mem_CmdSize(r.HndlSize'range) <= std_logic_vector(r.HndlSize);
|
||||
Mem_CmdSize(Mem_CmdSize'high downto r.HndlSize'high+1) <= (others => '0');
|
||||
Inp_Rdy <= r.Inp_Rdy;
|
||||
Mem_CmdVld <= r.Mem_CmdVld;
|
||||
|
||||
--------------------------------------------
|
||||
@ -251,11 +267,9 @@ begin
|
||||
r.RemWen <= '0';
|
||||
r.State <= Idle_s;
|
||||
r.FirstDma <= (others => '1');
|
||||
r.Inp_Rdy <= (others => '0');
|
||||
r.DataMuxVld <= '0';
|
||||
r.DataCurVld <= '0';
|
||||
r.Mem_CmdVld <= '0';
|
||||
r.MuxInVld <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
@ -342,7 +356,7 @@ begin
|
||||
WrAddr => r.RemWrAddr,
|
||||
Wr => r.RemWen,
|
||||
WrData(66 downto 64) => r.RemWrBytes,
|
||||
WrData(63 downto 0) => r.DataLast,
|
||||
WrData(63 downto 0) => r.DataRaw,
|
||||
RdAddr => r.RemRdAddr,
|
||||
RdData(66 downto 64) => Rem_RdBytes,
|
||||
RdData(63 downto 0) => Rem_Data
|
||||
|
@ -72,7 +72,53 @@ package body psi_ms_daq_daq_dma_tb_case_unaligned is
|
||||
signal DaqSm_Resp_Rdy : inout std_logic;
|
||||
constant Generics_c : Generics_t) is
|
||||
begin
|
||||
assert false report "Case UNALIGNED Procedure CONTROL: No Content added yet!" severity warning;
|
||||
InitCase(Clk, Rst);
|
||||
print(">> -- Unaligned --");
|
||||
|
||||
-- End Unaligned
|
||||
print(">> End Unaligned");
|
||||
InitCase(Clk, Rst);
|
||||
InitSubCase(0);
|
||||
ApplyCmd(2, 16#01230000#, 30, DaqSm_Cmd, DaqSm_Cmd_Vld, Clk);
|
||||
CheckResp(2, 16#01230000#, 30, NoEnd_s, DaqSm_Resp, DaqSm_Resp_Vld, DaqSm_Resp_Rdy, Clk);
|
||||
ApplyCmd(2, 16#01231000#, 29, DaqSm_Cmd, DaqSm_Cmd_Vld, Clk);
|
||||
CheckResp(2, 16#01231000#, 29, NoEnd_s, DaqSm_Resp, DaqSm_Resp_Vld, DaqSm_Resp_Rdy, Clk);
|
||||
ApplyCmd(2, 16#01232000#, 30, DaqSm_Cmd, DaqSm_Cmd_Vld, Clk);
|
||||
CheckResp(2, 16#01232000#, 30, NoEnd_s, DaqSm_Resp, DaqSm_Resp_Vld, DaqSm_Resp_Rdy, Clk);
|
||||
WaitAllProc(Clk);
|
||||
|
||||
-- QWord Split
|
||||
print(">> QWord Split");
|
||||
InitCase(Clk, Rst);
|
||||
InitSubCase(1);
|
||||
ApplyCmd(2, 16#01230000#, 30, DaqSm_Cmd, DaqSm_Cmd_Vld, Clk);
|
||||
CheckResp(2, 16#01230000#, 30, NoEnd_s, DaqSm_Resp, DaqSm_Resp_Vld, DaqSm_Resp_Rdy, Clk);
|
||||
ApplyCmd(2, 16#01231000#, 29, DaqSm_Cmd, DaqSm_Cmd_Vld, Clk);
|
||||
CheckResp(2, 16#01231000#, 29, NoEnd_s, DaqSm_Resp, DaqSm_Resp_Vld, DaqSm_Resp_Rdy, Clk);
|
||||
ApplyCmd(2, 16#01232000#, 30, DaqSm_Cmd, DaqSm_Cmd_Vld, Clk);
|
||||
CheckResp(2, 16#01232000#, 30, NoEnd_s, DaqSm_Resp, DaqSm_Resp_Vld, DaqSm_Resp_Rdy, Clk);
|
||||
WaitAllProc(Clk);
|
||||
|
||||
-- QWord Split, Rdy Toggling
|
||||
print(">> QWord Split, Rdy Toggling");
|
||||
InitCase(Clk, Rst);
|
||||
InitSubCase(2);
|
||||
ApplyCmd(2, 16#01230000#, 30, DaqSm_Cmd, DaqSm_Cmd_Vld, Clk);
|
||||
CheckResp(2, 16#01230000#, 30, NoEnd_s, DaqSm_Resp, DaqSm_Resp_Vld, DaqSm_Resp_Rdy, Clk);
|
||||
ApplyCmd(2, 16#01231000#, 29, DaqSm_Cmd, DaqSm_Cmd_Vld, Clk);
|
||||
CheckResp(2, 16#01231000#, 29, NoEnd_s, DaqSm_Resp, DaqSm_Resp_Vld, DaqSm_Resp_Rdy, Clk);
|
||||
ApplyCmd(2, 16#01232000#, 30, DaqSm_Cmd, DaqSm_Cmd_Vld, Clk);
|
||||
CheckResp(2, 16#01232000#, 30, NoEnd_s, DaqSm_Resp, DaqSm_Resp_Vld, DaqSm_Resp_Rdy, Clk);
|
||||
WaitAllProc(Clk);
|
||||
|
||||
-- mixed streams
|
||||
|
||||
-- End Aligned
|
||||
|
||||
-- Unaligned end by trigger (leads to flush)
|
||||
|
||||
-- Unaligned end by timeout (leads to flush)
|
||||
|
||||
end procedure;
|
||||
|
||||
procedure input (
|
||||
@ -82,7 +128,22 @@ package body psi_ms_daq_daq_dma_tb_case_unaligned is
|
||||
signal Inp_Data : inout Input2Daq_Data_a;
|
||||
constant Generics_c : Generics_t) is
|
||||
begin
|
||||
assert false report "Case UNALIGNED Procedure INPUT: No Content added yet!" severity warning;
|
||||
-- End Unaligned
|
||||
WaitForCase(0, Clk);
|
||||
ApplyData(2, 30, NoEnd_s, Inp_Vld, Inp_Rdy, Inp_Data, Clk);
|
||||
ApplyData(2, 29, NoEnd_s, Inp_Vld, Inp_Rdy, Inp_Data, Clk, 30);
|
||||
ApplyData(2, 30, NoEnd_s, Inp_Vld, Inp_Rdy, Inp_Data, Clk, 30+29);
|
||||
ProcDone_V(0) := '1';
|
||||
|
||||
-- QWord Split
|
||||
WaitForCase(1, Clk);
|
||||
ApplyData(2, 30+29+30, NoEnd_s, Inp_Vld, Inp_Rdy, Inp_Data, Clk);
|
||||
ProcDone_V(0) := '1';
|
||||
|
||||
-- QWord Split, Rdy Toggling
|
||||
WaitForCase(2, Clk);
|
||||
ApplyData(2, 30+29+30, NoEnd_s, Inp_Vld, Inp_Rdy, Inp_Data, Clk);
|
||||
ProcDone_V(0) := '1';
|
||||
end procedure;
|
||||
|
||||
procedure mem_cmd (
|
||||
@ -93,7 +154,26 @@ package body psi_ms_daq_daq_dma_tb_case_unaligned is
|
||||
signal Mem_CmdRdy : inout std_logic;
|
||||
constant Generics_c : Generics_t) is
|
||||
begin
|
||||
assert false report "Case UNALIGNED Procedure MEM_CMD: No Content added yet!" severity warning;
|
||||
-- End Unaligned
|
||||
WaitForCase(0, Clk);
|
||||
CheckMemCmd( 16#01230000#, 30, 0, Mem_CmdAddr, Mem_CmdSize, Mem_CmdVld, Mem_CmdRdy, Clk);
|
||||
CheckMemCmd( 16#01231000#, 29, 0, Mem_CmdAddr, Mem_CmdSize, Mem_CmdVld, Mem_CmdRdy, Clk);
|
||||
CheckMemCmd( 16#01232000#, 30, 0, Mem_CmdAddr, Mem_CmdSize, Mem_CmdVld, Mem_CmdRdy, Clk);
|
||||
ProcDone_V(1) := '1';
|
||||
|
||||
-- QWord Split
|
||||
WaitForCase(1, Clk);
|
||||
CheckMemCmd( 16#01230000#, 30, 0, Mem_CmdAddr, Mem_CmdSize, Mem_CmdVld, Mem_CmdRdy, Clk);
|
||||
CheckMemCmd( 16#01231000#, 29, 0, Mem_CmdAddr, Mem_CmdSize, Mem_CmdVld, Mem_CmdRdy, Clk);
|
||||
CheckMemCmd( 16#01232000#, 30, 0, Mem_CmdAddr, Mem_CmdSize, Mem_CmdVld, Mem_CmdRdy, Clk);
|
||||
ProcDone_V(1) := '1';
|
||||
|
||||
-- QWord Split, Rdy Toggling
|
||||
WaitForCase(2, Clk);
|
||||
CheckMemCmd( 16#01230000#, 30, 0, Mem_CmdAddr, Mem_CmdSize, Mem_CmdVld, Mem_CmdRdy, Clk);
|
||||
CheckMemCmd( 16#01231000#, 29, 0, Mem_CmdAddr, Mem_CmdSize, Mem_CmdVld, Mem_CmdRdy, Clk);
|
||||
CheckMemCmd( 16#01232000#, 30, 0, Mem_CmdAddr, Mem_CmdSize, Mem_CmdVld, Mem_CmdRdy, Clk);
|
||||
ProcDone_V(1) := '1';
|
||||
end procedure;
|
||||
|
||||
procedure mem_dat (
|
||||
@ -103,7 +183,26 @@ package body psi_ms_daq_daq_dma_tb_case_unaligned is
|
||||
signal Mem_DatRdy : inout std_logic;
|
||||
constant Generics_c : Generics_t) is
|
||||
begin
|
||||
assert false report "Case UNALIGNED Procedure MEM_DAT: No Content added yet!" severity warning;
|
||||
-- End Unaligned
|
||||
WaitForCase(0, Clk);
|
||||
CheckMemData(30, 0, Mem_DatData, Mem_DatVld, Mem_DatRdy, Clk);
|
||||
CheckMemData(29, 0, Mem_DatData, Mem_DatVld, Mem_DatRdy, Clk, 30);
|
||||
CheckMemData(30, 0, Mem_DatData, Mem_DatVld, Mem_DatRdy, Clk, 30+29);
|
||||
ProcDone_V(2) := '1';
|
||||
|
||||
-- QWord Split
|
||||
WaitForCase(1, Clk);
|
||||
CheckMemData(30, 0, Mem_DatData, Mem_DatVld, Mem_DatRdy, Clk);
|
||||
CheckMemData(29, 0, Mem_DatData, Mem_DatVld, Mem_DatRdy, Clk, 30);
|
||||
CheckMemData(30, 0, Mem_DatData, Mem_DatVld, Mem_DatRdy, Clk, 30+29);
|
||||
ProcDone_V(2) := '1';
|
||||
|
||||
-- QWord Split, Rdy Toggling
|
||||
WaitForCase(2, Clk);
|
||||
CheckMemData(30, 5, Mem_DatData, Mem_DatVld, Mem_DatRdy, Clk);
|
||||
CheckMemData(29, 5, Mem_DatData, Mem_DatVld, Mem_DatRdy, Clk, 30);
|
||||
CheckMemData(30, 5, Mem_DatData, Mem_DatVld, Mem_DatRdy, Clk, 30+29);
|
||||
ProcDone_V(2) := '1';
|
||||
end procedure;
|
||||
|
||||
end;
|
||||
|
@ -57,14 +57,16 @@ package psi_ms_daq_daq_dma_tb_pkg is
|
||||
signal Inp_Vld : out std_logic_vector;
|
||||
signal Inp_Rdy : in std_logic_vector;
|
||||
signal Inp_Data : out Input2Daq_Data_a;
|
||||
signal Clk : in std_logic);
|
||||
signal Clk : in std_logic;
|
||||
Offset : in integer := 0);
|
||||
|
||||
procedure CheckMemData( Bytes : in integer;
|
||||
RdyDelay : in integer := 0;
|
||||
signal Mem_DatData : in std_logic_vector;
|
||||
signal Mem_DatVld : in std_logic;
|
||||
signal Mem_DatRdy : out std_logic;
|
||||
signal Clk : in std_logic);
|
||||
signal Clk : in std_logic;
|
||||
Offset : in integer := 0);
|
||||
|
||||
procedure CheckMemCmd( Address : in integer;
|
||||
Bytes : in integer;
|
||||
@ -139,8 +141,9 @@ package body psi_ms_daq_daq_dma_tb_pkg is
|
||||
signal Inp_Vld : out std_logic_vector;
|
||||
signal Inp_Rdy : in std_logic_vector;
|
||||
signal Inp_Data : out Input2Daq_Data_a;
|
||||
signal Clk : in std_logic) is
|
||||
variable DataCnt_v : unsigned(7 downto 0) := (others => '0');
|
||||
signal Clk : in std_logic;
|
||||
Offset : in integer := 0) is
|
||||
variable DataCnt_v : unsigned(7 downto 0) := to_unsigned(Offset, 8);
|
||||
begin
|
||||
assert EndType = NoEnd_s report "###ERROR###: EndType not yet implemented" severity error;
|
||||
Inp_Vld(Stream) <= '1';
|
||||
@ -171,8 +174,9 @@ package body psi_ms_daq_daq_dma_tb_pkg is
|
||||
signal Mem_DatData : in std_logic_vector;
|
||||
signal Mem_DatVld : in std_logic;
|
||||
signal Mem_DatRdy : out std_logic;
|
||||
signal Clk : in std_logic) is
|
||||
variable DataCnt_v : integer := 0;
|
||||
signal Clk : in std_logic;
|
||||
Offset : in integer := 0) is
|
||||
variable DataCnt_v : integer := Offset;
|
||||
begin
|
||||
for dw in 0 to (Bytes+7)/8-1 loop
|
||||
if RdyDelay > 0 then
|
||||
@ -183,6 +187,7 @@ package body psi_ms_daq_daq_dma_tb_pkg is
|
||||
end if;
|
||||
Mem_DatRdy <= '1';
|
||||
wait until rising_edge(Clk) and Mem_DatVld = '1';
|
||||
Mem_DatRdy <= '0';
|
||||
for byte in 0 to 7 loop
|
||||
if dw*8+byte >= Bytes then
|
||||
-- nothing to compare
|
||||
@ -192,8 +197,6 @@ package body psi_ms_daq_daq_dma_tb_pkg is
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
wait until rising_edge(Clk);
|
||||
StdlCompare(0, Mem_DatVld, "Mem_DatVld did not go low");
|
||||
end procedure;
|
||||
|
||||
procedure CheckMemCmd( Address : in integer;
|
||||
|
Reference in New Issue
Block a user