DEVEL: Added skeleton for DMA engine

This commit is contained in:
Oliver Bruendler
2018-07-13 11:40:33 +02:00
parent 13871baefb
commit b6b6094f0f
2 changed files with 248 additions and 3 deletions

198
hdl/psi_ms_daq_daq_dma.vhd Normal file
View File

@ -0,0 +1,198 @@
------------------------------------------------------------------------------
-- Description
------------------------------------------------------------------------------
-- This component calculates a binary division of two fixed point values.
------------------------------------------------------------------------------
-- Libraries
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
use work.psi_common_logic_pkg.all;
use work.psi_common_array_pkg.all;
use work.psi_ms_daq_pkg.all;
------------------------------------------------------------------------------
-- Entity Declaration
------------------------------------------------------------------------------
entity psi_ms_daq_daq_dma is
generic (
Streams_g : positive range 1 to 32 := 4;
StreamWidth_g : t_ainteger := (8, 16, 32, 64)
);
port (
-- Control signals
Clk : in std_logic;
Rst : in std_logic;
-- DAQ Statemachione Connections
DaqSm_Cmd : in DaqSm2DaqDma_Cmd_t;
DaqSm_Cmd_Vld : in std_logic;
DaqSm_Resp : out DaqDma2DaqSm_Resp_t;
DaqSm_Resp_Vld : out std_logic;
DaqSm_Resp_Rdy : in std_logic;
-- Input handling connections
Inp_Vld : in std_logic_vector(Streams_g-1 downto 0);
Inp_Rdy : out std_logic_vector(Streams_g-1 downto 0);
Inp_Data : in Input2Daq_Data_a(Streams_g-1 downto 0);
-- Memory interface connections
Mem_CmdAddr : out std_logic_vector(31 downto 0);
Mem_CmdSize : out std_logic_vector(31 downto 0);
Mem_CmdVld : out std_logic;
Mem_CmdRdy : in std_logic;
Mem_DatData : out std_logic_vector(63 downto 0);
Mem_DatVld : out std_logic;
Mem_DatRdy : in std_logic
);
end entity;
------------------------------------------------------------------------------
-- Architecture Declaration
------------------------------------------------------------------------------
architecture rtl of psi_ms_daq_daq_dma is
-- Constants
signal BufferFifoDepth_g : integer := 32;
-- Component Connection Signals
signal CmdFifo_Level_Dbg : std_logic_vector(log2ceil(Streams_g) downto 0);
signal CmdFifo_InData : std_logic_vector(DaqSm2DaqDma_Cmd_Size_c-1 downto 0);
signal CmdFifo_OutData : std_logic_vector(DaqSm2DaqDma_Cmd_Size_c-1 downto 0);
signal CmdFifo_Cmd : DaqSm2DaqDma_Cmd_t;
signal CmdFifo_Vld : std_logic;
signal RspFifo_Level_Dbg : std_logic_vector(log2ceil(Streams_g) downto 0);
signal RspFifo_InData : std_logic_vector(DaqSm2DaqDma_Resp_Size_c-1 downto 0);
signal RspFifo_OutData : std_logic_vector(DaqSm2DaqDma_Resp_Size_c-1 downto 0);
signal DatFifo_Level_Dbg : std_logic_vector(log2ceil(BufferFifoDepth_g) downto 0);
signal DatFifo_AlmFull : std_logic;
-- Types
--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
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;
end record;
signal r, r_next : two_process_r;
begin
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process( r, DaqSm_Cmd, DaqSm_Cmd_Vld, DaqSm_Resp_Rdy, Inp_Vld, Inp_Data, Mem_CmdRdy, Mem_DatRdy,
CmdFifo_Cmd, CmdFifo_Vld, DatFifo_AlmFull)
variable v : two_process_r;
begin
-- *** Hold variables stable ***
v := r;
-- *** Assign to signal ***
r_next <= v;
end process;
-- *** Registered Outputs ***
--------------------------------------------
-- Sequential Process
--------------------------------------------
p_seq : process(Clk)
begin
if rising_edge(Clk) then
r <= r_next;
if Rst = '1' then
r.CmdFifo_Rdy <= '0';
r.RspFifo_Vld <= '0';
r.Mem_DataVld <= '0';
end if;
end if;
end process;
--------------------------------------------
-- Component Instantiation
--------------------------------------------
-- *** Command FIFO ***
CmdFifo_InData <= DaqSm2DaqDma_Cmd_ToStdlv(DaqSm_Cmd);
i_fifocmd : entity work.psi_common_sync_fifo
generic map (
Width_g => DaqSm2DaqDma_Cmd_Size_c,
Depth_g => Streams_g,
RamStyle_g => "distributed"
)
port map (
Clk => Clk,
Rst => Rst,
InData => CmdFifo_InData,
InVld => DaqSm_Cmd_Vld,
OutData => CmdFifo_OutData,
OutVld => CmdFifo_Vld,
OutRdy => r.CmdFifo_Rdy,
OutLevel => CmdFifo_Level_Dbg
);
CmdFifo_Cmd <= DaqSm2DaqDma_Cmd_FromStdlv(CmdFifo_OutData);
-- *** Response FIFO ***
-- Ready not required for system reasons: There is never more commands open than streams.
RspFifo_InData <= DaqSm2DaqDma_Cmd_ToStdlv(r.RspFifo_Data);
i_fiforsp : entity work.psi_common_sync_fifo
generic map (
Width_g => DaqSm2DaqDma_Resp_Size_c,
Depth_g => Streams_g,
RamStyle_g => "distributed"
)
port map (
Clk => Clk,
Rst => Rst,
InData => RspFifo_InData,
InVld => r.RspFifo_Vld,
OutData => OutData,
OutVld => DaqSm_Resp_Vld,
OutRdy => DaqSm_Resp_Rdy,
OutLevel => RspFifo_Level_Dbg
);
DaqSm_Resp <= DaqSm2DaqDma_Cmd_FromStdlv(OutData);
-- *** Buffer FIFO ***
-- This FIFO allows buffering data for the time the state machine requires to react on a "memory interface not ready for more data" situation.
-- As a result, the backpressure must not handled in the complete pipeline of this block.
-- Rdy is not required since the data pipeline is stopped based on the almost full flag
i_fifodata : entity work.psi_common_sync_fifo
generic map (
Width_g => 64,
Depth_g => BufferFifoDepth_g,
AlmFullOn_g => true,
AlmFullLevel_g => BufferFifoDepth_g/2,
RamStyle_g => "distributed"
)
port map (
Clk => Clk,
Rst => Rst,
InData => r.Mem_Data,
InVld => r.Mem_DataVld,
OutData => Mem_DatData,
OutVld => Mem_DatVld,
OutRdy => Mem_DatRdy,
OutLevel => DatFifo_Level_Dbg,
AlmFull => DatFifo_AlmFull
);
end;

View File

@ -4,14 +4,18 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.psi_common_math_pkg.all;
------------------------------------------------------------------------------
-- Package Header
------------------------------------------------------------------------------
package psi_ms_daq_pkg is
constant MaxStreams_c : integer := 32;
constant MaxWindows_c : integer := 32;
constant MaxStreams_c : integer := 32;
constant MaxWindows_c : integer := 32;
constant MaxStreamsBits_c : integer := log2ceil(MaxStreams_c);
subtype RecMode_t is std_logic_vector(1 downto 0);
constant RecMode_Continuous_c : RecMode_t := std_logic_vector(to_unsigned(0, RecMode_t'length));
@ -26,18 +30,25 @@ package psi_ms_daq_pkg is
IsTo : std_logic;
IsTrig : std_logic;
end record;
type Input2Daq_Data_a is array (natural range <>) of Input2Daq_Data_t;
type DaqSm2DaqDma_Cmd_t is record
Address : std_logic_vector(31 downto 0);
MaxSize : std_logic_vector(15 downto 0);
Stream : integer range 0 to MaxStreams_c-1;
end record;
constant DaqSm2DaqDma_Cmd_Size_c : integer := 32+16+MaxStreamsBits_c;
function DaqSm2DaqDma_Cmd_ToStdlv( rec : DaqSm2DaqDma_Cmd_t) return std_logic_vector;
function DaqSm2DaqDma_Cmd_FromStdlv( stdlv : std_logic_vector) return DaqSm2DaqDma_Cmd_t;
type DaqDma2DaqSm_Resp_t is record
Size : std_logic_vector(15 downto 0);
Trigger : std_logic;
Stream : integer range 0 to MaxStreams_c-1;
end record;
constant DaqDma2DaqSm_Resp_Size_c : integer := 15+1+MaxStreamsBits_c;
function DaqSm2DaqDma_Resp_ToStdlv( rec : DaqDma2DaqSm_Resp_t) return std_logic_vector;
function DaqSm2DaqDma_Resp_FromStdlv( stdlv : std_logic_vector) return DaqDma2DaqSm_Resp_t;
type ToCtxStr_t is record
Stream : integer range 0 to MaxStreams_c-1;
@ -82,7 +93,43 @@ end psi_ms_daq_pkg;
------------------------------------------------------------------------------
package body psi_ms_daq_pkg is
--
-- *** DaqSm2DaqDma_Cmd ***
function DaqSm2DaqDma_Cmd_ToStdlv( rec : DaqSm2DaqDma_Cmd_t) return std_logic_vector is
variable stdlv : std_logic_vector(DaqSm2DaqDma_Cmd_Size_c-1 downto 0);
begin
stdlv(31 downto 0) := rec.Address;
stdlv(47 downto 32) := rec.MaxSize;
stdlv(stdlv'left downto 48) := std_logic_vector(to_unsigned(rec.Stream, MaxStreamsBits_c));
return stdlv;
end function;
function DaqSm2DaqDma_Cmd_FromStdlv( stdlv : std_logic_vector) return DaqSm2DaqDma_Cmd_t is
variable rec : DaqSm2DaqDma_Cmd_t;
begin
rec.Address := stdlv(31 downto 0);
rec.MaxSize := stdlv(47 downto 32);
rec.Stream := to_integer(unsigned(stdlv(stdlv'left downto 48)));
return rec;
end function;
-- *** DaqDma2DaqSm_Resp ***
function DaqSm2DaqDma_Resp_ToStdlv( rec : DaqDma2DaqSm_Resp_t) return std_logic_vector is
variable stdlv : std_logic_vector(DaqDma2DaqSm_Resp_Size_c-1 downto 0);
begin
stdlv(15 downto 0) := rec.Size;
stdlv(16) := rec.Trigger;
stdlv(stdlv'left downto 17) := std_logic_vector(to_unsigned(rec.Stream, MaxStreamsBits_c));
return stdlv;
end function;
function DaqSm2DaqDma_Resp_FromStdlv( stdlv : std_logic_vector) return DaqDma2DaqSm_Resp_t is
variable rec : DaqDma2DaqSm_Resp_t;
begin
rec.Size := stdlv(15 downto 0);
rec.Trigger := stdlv(16);
rec.Stream := to_integer(unsigned(stdlv(stdlv'left downto 17)));
return rec;
end function;
end psi_ms_daq_pkg;