DEVEL: Simplified daq_dma
This commit is contained in:
@ -78,37 +78,32 @@ 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, Start_s, Transfer_s, Done_s, Cmd_s);
|
||||
type State_t is (Idle_s, RemRd1_s, RemRd2_s, Transfer_s, Done_s, Cmd_s);
|
||||
|
||||
-- Two process method
|
||||
type two_process_r is record
|
||||
CmdFifo_Rdy : std_logic;
|
||||
RspFifo_Vld : std_logic;
|
||||
RspFifo_Data : DaqDma2DaqSm_Resp_t;
|
||||
Mem_Data : std_logic_vector(63 downto 0);
|
||||
Mem_DataVld : std_logic;
|
||||
StreamStdlv : std_logic_vector(log2ceil(Streams_g)-1 downto 0);
|
||||
RemAddr : std_logic_vector(log2ceil(Streams_g)-1 downto 0);
|
||||
RemWen : std_logic_vector(0 to 3);
|
||||
RemWen : std_logic;
|
||||
RemWrBytes : std_logic_vector(2 downto 0);
|
||||
RemSft : integer range 0 to 7;
|
||||
RemData : std_logic_vector(63 downto 0);
|
||||
State : State_t;
|
||||
HndlMaxSize : unsigned(15 downto 0);
|
||||
HndlSize : unsigned(15 downto 0);
|
||||
HndlBytes : unsigned(15 downto 0);
|
||||
RdBytes : unsigned(15 downto 0);
|
||||
WrBytes : unsigned(15 downto 0);
|
||||
HndlStream : integer range 0 to MaxStreams_c-1;
|
||||
HndlAddress : std_logic_vector(31 downto 0);
|
||||
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);
|
||||
DataMuxVld : std_logic;
|
||||
Mem_CmdVld : std_logic;
|
||||
Trigger : std_logic;
|
||||
DataSft : std_logic_vector(127 downto 0);
|
||||
NextDone : std_logic;
|
||||
end record;
|
||||
signal r, r_next : two_process_r;
|
||||
|
||||
@ -121,7 +116,7 @@ begin
|
||||
CmdFifo_Cmd, CmdFifo_Vld, DatFifo_AlmFull, Rem_RdBytes, Rem_Data)
|
||||
variable v : two_process_r;
|
||||
variable ThisByte_v : std_logic_vector(7 downto 0);
|
||||
variable MuxInVld_v : std_logic;
|
||||
variable RemSft_v : integer range 0 to 7;
|
||||
begin
|
||||
-- *** Hold variables stable ***
|
||||
v := r;
|
||||
@ -131,8 +126,7 @@ begin
|
||||
Inp_Rdy <= (others => '0');
|
||||
v.Mem_DataVld := '0';
|
||||
v.RspFifo_Vld := '0';
|
||||
MuxInVld_v := '0';
|
||||
v.RemWen(0) := '0';
|
||||
v.RemWen := '0';
|
||||
v.UpdateLast := '0';
|
||||
|
||||
-- *** State Machine ***
|
||||
@ -145,68 +139,73 @@ begin
|
||||
v.HndlAddress := CmdFifo_Cmd.Address;
|
||||
v.Trigger := '0';
|
||||
if CmdFifo_Vld = '1' then
|
||||
-- For back to back commands on the same stream, wait until remaining bytes are written (will never occur in real-life but in TBs)
|
||||
if (std_logic_vector(to_unsigned(CmdFifo_Cmd.Stream, v.StreamStdlv'length)) /= r.RemAddr) or (unsigned(r.RemWen) = 0) then
|
||||
v.CmdFifo_Rdy := '1';
|
||||
v.State := RemRd1_s;
|
||||
end if;
|
||||
v.CmdFifo_Rdy := '1';
|
||||
v.State := RemRd1_s;
|
||||
end if;
|
||||
|
||||
when RemRd1_s =>
|
||||
v.State := RemRd2_s;
|
||||
|
||||
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
|
||||
|
||||
when RemRd2_s =>
|
||||
-- Prevent RAM data from before reset to have an influence
|
||||
v.WrBytes := (others => '0');
|
||||
if r.FirstDma(r.HndlStream) = '1' then
|
||||
v.HndlSft := (others => '0');
|
||||
v.HndlSize := (others => '0');
|
||||
v.HndlBytes := (others => '0');
|
||||
v.HndlSft := (others => '0');
|
||||
v.RdBytes := (others => '0');
|
||||
v.DataSft := (others => '0');
|
||||
else
|
||||
v.HndlSft := unsigned(Rem_RdBytes);
|
||||
v.DataLast := Rem_Data;
|
||||
v.HndlSize := (others => '0');
|
||||
v.HndlBytes := resize(unsigned(Rem_RdBytes), v.HndlBytes'length);
|
||||
v.HndlSft := unsigned(Rem_RdBytes);
|
||||
v.DataSft(127 downto 64) := Rem_Data;
|
||||
v.RdBytes := resize(unsigned(Rem_RdBytes), v.RdBytes'length);
|
||||
end if;
|
||||
v.FirstDma(r.HndlStream) := '0';
|
||||
v.State := Start_s;
|
||||
|
||||
when Start_s =>
|
||||
v.State := Transfer_s;
|
||||
v.UpdateLast := '1';
|
||||
v.State := Transfer_s;
|
||||
v.NextDone := '0';
|
||||
|
||||
when Transfer_s =>
|
||||
-- TF done because of maximum size reached
|
||||
if r.HndlSize >= r.HndlMaxSize then
|
||||
if r.WrBytes >= r.HndlMaxSize then
|
||||
v.State := Done_s;
|
||||
elsif DatFifo_AlmFull = '0' then
|
||||
v.HndlSize := r.HndlSize + 8;
|
||||
v.HndlBytes := r.HndlBytes + unsigned(Inp_Data(r.HndlStream).Bytes);
|
||||
if r.NextDone = '0' then
|
||||
v.RdBytes := r.RdBytes + unsigned(Inp_Data(r.HndlStream).Bytes);
|
||||
end if;
|
||||
v.WrBytes := r.WrBytes + 8;
|
||||
-- Combinatorial handling because of fall-through interface at input
|
||||
Inp_Rdy(r.HndlStream) <= '1';
|
||||
MuxInVld_v := '1';
|
||||
if r.RdBytes < r.HndlMaxSize and r.NextDone = '0' then
|
||||
Inp_Rdy(r.HndlStream) <= '1';
|
||||
end if;
|
||||
-- Handling of last frame
|
||||
if Inp_Data(r.HndlStream).Last = '1' then
|
||||
v.State := Done_s;
|
||||
-- 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 then
|
||||
v.State := Done_s;
|
||||
else
|
||||
v.NextDone := '1';
|
||||
end if;
|
||||
v.Trigger := Inp_Data(r.HndlStream).IsTrig;
|
||||
end if;
|
||||
if r.NextDone = '1' then
|
||||
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.Mem_DataVld := '1';
|
||||
end if;
|
||||
|
||||
when Done_s =>
|
||||
if r.HndlMaxSize < r.HndlSize then
|
||||
v.RemWrBytes := std_logic_vector(resize(r.HndlBytes - r.HndlMaxSize, v.RemWrBytes'length));
|
||||
v.HndlSize := r.HndlMaxSize;
|
||||
v.RemSft := to_integer(resize(r.HndlMaxSize, 3));
|
||||
RemSft_v := to_integer(resize(r.HndlMaxSize, 3));
|
||||
if r.HndlMaxSize < r.RdBytes then
|
||||
v.RemWrBytes := std_logic_vector(resize(r.RdBytes - r.HndlMaxSize, v.RemWrBytes'length));
|
||||
v.RdBytes := r.HndlMaxSize;
|
||||
else
|
||||
v.RemWrBytes := (others => '0');
|
||||
v.RemSft := 0;
|
||||
end if;
|
||||
v.RemData := v.DataSft(8*RemSft_v+63 downto 8*RemSft_v);
|
||||
v.State := Cmd_s;
|
||||
v.Mem_CmdVld := '1';
|
||||
v.RemWen(0) := '1';
|
||||
v.RemWen := '1';
|
||||
v.RemAddr := r.StreamStdlv;
|
||||
|
||||
when Cmd_s =>
|
||||
@ -214,51 +213,12 @@ begin
|
||||
v.State := Idle_s;
|
||||
v.Mem_CmdVld := '0';
|
||||
v.RspFifo_Vld := '1';
|
||||
v.RspFifo_Data.Size := std_logic_vector(r.HndlSize);
|
||||
v.RspFifo_Data.Size := std_logic_vector(r.RdBytes);
|
||||
v.RspFifo_Data.Trigger := r.Trigger;
|
||||
v.RspFifo_Data.Stream := r.HndlStream;
|
||||
end if;
|
||||
-- do shift
|
||||
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
|
||||
-- *** Data Multiplexer ***
|
||||
if r.State = RemRd2_s then
|
||||
v.DataMux := Rem_Data;
|
||||
else
|
||||
v.DataMux := Inp_Data(r.HndlStream).Data;
|
||||
end if;
|
||||
v.DataMuxVld := MuxInVld_v;
|
||||
v.RemWen(1) := r.RemWen(0);
|
||||
|
||||
-- *** Data Alignment ***
|
||||
v.DataCurVld := r.DataMuxVld;
|
||||
v.RemWen(2) := r.RemWen(1);
|
||||
if r.State = Start_s then
|
||||
v.DataCur := r.DataMux;
|
||||
elsif r.DataMuxVld = '1' then
|
||||
v.DataCur(63 downto 8*to_integer(r.HndlSft)) := r.DataMux(63-8*to_integer(r.HndlSft) downto 0);
|
||||
v.DataCur(8*to_integer(r.HndlSft)-1 downto 0) := r.DataMux(63 downto 64-8*to_integer(r.HndlSft));
|
||||
end if;
|
||||
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
|
||||
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.DataLast := r.DataCur;
|
||||
end if;
|
||||
|
||||
-- *** Alignment of remiaining data for next transfer ***
|
||||
v.RemWen(3) := r.RemWen(2);
|
||||
v.RemData(63-8*r.RemSft downto 0) := r.DataCur(63 downto 8*r.RemSft);
|
||||
v.RemData(63 downto 64-8*r.RemSft) := r.DataCur(8*r.RemSft-1 downto 0);
|
||||
|
||||
end case;
|
||||
|
||||
-- *** Assign to signal ***
|
||||
r_next <= v;
|
||||
@ -267,8 +227,8 @@ begin
|
||||
|
||||
-- *** Registered Outputs ***
|
||||
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');
|
||||
Mem_CmdSize(r.RdBytes'range) <= std_logic_vector(r.RdBytes);
|
||||
Mem_CmdSize(Mem_CmdSize'high downto r.RdBytes'high+1) <= (others => '0');
|
||||
Mem_CmdVld <= r.Mem_CmdVld;
|
||||
|
||||
--------------------------------------------
|
||||
@ -282,11 +242,9 @@ begin
|
||||
r.CmdFifo_Rdy <= '0';
|
||||
r.RspFifo_Vld <= '0';
|
||||
r.Mem_DataVld <= '0';
|
||||
r.RemWen <= (others => '0');
|
||||
r.RemWen <= '0';
|
||||
r.State <= Idle_s;
|
||||
r.FirstDma <= (others => '1');
|
||||
r.DataMuxVld <= '0';
|
||||
r.DataCurVld <= '0';
|
||||
r.Mem_CmdVld <= '0';
|
||||
end if;
|
||||
end if;
|
||||
@ -351,7 +309,7 @@ begin
|
||||
port map (
|
||||
Clk => Clk,
|
||||
Rst => Rst,
|
||||
InData => r.Mem_Data,
|
||||
InData => r.DataSft(63 downto 0),
|
||||
InVld => r.Mem_DataVld,
|
||||
OutData => Mem_DatData,
|
||||
OutVld => Mem_DatVld,
|
||||
@ -372,7 +330,7 @@ begin
|
||||
Clk => Clk,
|
||||
RdClk => Rst,
|
||||
WrAddr => r.RemAddr,
|
||||
Wr => r.RemWen(3),
|
||||
Wr => r.RemWen,
|
||||
WrData(66 downto 64) => r.RemWrBytes,
|
||||
WrData(63 downto 0) => r.RemData,
|
||||
RdAddr => r.StreamStdlv,
|
||||
|
Reference in New Issue
Block a user