DEVEL: Implemented TMEM Interface (not yet tested)

This commit is contained in:
Oliver Bruendler
2018-08-31 10:42:50 +02:00
parent 2c987611ab
commit 46bc02e36f
3 changed files with 415 additions and 20 deletions

View File

@ -1,8 +1,3 @@
------------------------------------------------------------------------------
-- Description
------------------------------------------------------------------------------
-- This component calculates a binary division of two fixed point values.
------------------------------------------------------------------------------
-- Libraries
------------------------------------------------------------------------------
@ -49,8 +44,8 @@ entity psi_ms_daq is
Smem_Rst : in std_logic;
-- TMEM Interface
AcqTmem : TBD
TmemAcq : TBD
TmemAcq : in TmemRqst_t;
AcqTmem : out TmemResp_t;
-- SMEM Interface
AcqSmem : out ToSmemWr_t;
@ -100,6 +95,23 @@ architecture rtl of psi_ms_daq is
-- Mem/Statemachine
signal MemSm_Done : std_logic;
-- Configuration
signal Cfg_StrEna : std_logic_vector(Streams_g-1 downto 0);
signal Cfg_GlbEna : std_logic;
signal Cfg_PostTrig : t_aslv32(Streams_g-1 downto 0);
signal Cfg_Arm : std_logic_vector(Streams_g-1 downto 0);
signal Cfg_RecMode : t_aslv2(Streams_g-1 downto 0);
-- Status
signal Stat_StrIrq : std_logic_vector(Streams_g-1 downto 0);
signal Stat_IsArmed : std_logic_vector(Streams_g-1 downto 0);
-- Context Memory Connections
signal CtxStr_Cmd : ToCtxStr_t;
signal CtxStr_Resp : FromCtx_t;
signal CtxWin_Cmd : ToCtxWin_t;
signal CtxWin_Resp : FromCtx_t;
begin
--------------------------------------------
@ -112,10 +124,43 @@ begin
end if;
end process;
--------------------------------------------
-- TMEM Interface
--------------------------------------------
i_reg : entity work.psi_ms_daq_reg_tmem
generic map (
Streams_g => Streams_g
)
port map (
ToscaClk => Tosca_Clk,
Rst => Rst,
TmemRqst => TmemAcq,
TmemResp => AcqTmem,
CtxStr_Cmd => CtxStr_Cmd,
CtxStr_Resp => CtxStr_Resp,
CtxWin_Cmd => CtxWin_Cmd,
CtxWin_Resp => CtxWin_Resp,
StrIrq => Stat_StrIrq,
StrEna => Cfg_StrEna,
GlbEna => Cfg_GlbEna,
IrqOut => Irq,
InLevel => InpSm_Level,
PostTrig => Cfg_PostTrig,
Arm => Cfg_Arm,
IsArmed => Stat_IsArmed,
RecMode => Cfg_RecMode
);
--------------------------------------------
-- Input Logic Instantiation
--------------------------------------------
g_input : for str in 0 to Streams_g-1 generate
signal InRst : std_logic;
begin
-- Reset if stream is disabled
InRst <= Rst or not Cfg_StrEna(str) or not Cfg_GlbEna;
-- Instantiation
i_input : entity work.psi_ms_daq_input
generic map (
StreamWidth_g => StreamWidth_g(str),
@ -133,11 +178,11 @@ begin
Str_Trig => Str_Trig(str),
Str_Ts => Str_Ts(str),
Clk => Tosca_Clk,
Rst => Rst,
PostTrigSpls =>
Mode =>
Arm =>
IsArmed =>
Rst => InRst,
PostTrigSpls => Cfg_PostTrig(str),
Mode => Cfg_RecMode(str),
Arm => Cfg_Arm(str),
IsArmed => Stat_IsArmed(str),
Daq_Vld => InpDma_Vld(str),
Daq_Rdy => InpDma_Rdy(str),
Daq_Data => InpDma_Data(str),
@ -165,9 +210,9 @@ begin
port map (
Clk => Tosca_Clk,
Rst => Rst,
GlbEna =>
StrEna =>
StrIrq =>
GlbEna => Cfg_GlbEna,
StrEna => Cfg_StrEna,
StrIrq => Stat_StrIrq,
Inp_HasLast => InpSm_HasTlast,
Inp_Level => InpSm_Level,
Ts_Vld => InpSm_TsVld,
@ -181,10 +226,10 @@ begin
TfDone => MemSm_Done,
-- Context RAM connections
CtxStr_Cmd : out ToCtxStr_t; -- $$ proc=ctx $$
CtxStr_Resp : in FromCtx_t; -- $$ proc=ctx $$
CtxWin_Cmd : out ToCtxWin_t; -- $$ proc=ctx $$
CtxWin_Resp : in FromCtx_t -- $$ proc=ctx $$
CtxStr_Cmd => CtxStr_Cmd,
CtxStr_Resp => CtxStr_Resp,
CtxWin_Cmd => CtxWin_Cmd,
CtxWin_Resp => CtxWin_Resp
);
--------------------------------------------

View File

@ -79,12 +79,25 @@ package psi_ms_daq_pkg is
end record;
constant CtxWin_Sel_WincntWinlast_c : std_logic_vector(0 downto 0) := "0";
constant CtxWin_Sel_WinTs_c : std_logic_vector(0 downto 0) := "1";
type FromCtx_t is record
RdatLo : std_logic_vector(31 downto 0);
RdatHi : std_logic_vector(31 downto 0);
end record;
type TmemRqst_t is record
ADD : std_logic_vector(23 downto 0);
DATW : std_logic_vector(63 downto 0);
ENA ; std_logic;
WE : std_logic_vector(7 downto 0);
CS : std_logic_vector(1 downto 0);
end reord;
type TmemResp_t is record
DATR : std_logic_vector(63 downto 0);
BUSY : std_logic;
PIPE : std_logic_vector(1 downto 0);
end record;
end psi_ms_daq_pkg;

337
hdl/psi_ms_daq_reg_tmem.vhd Normal file
View File

@ -0,0 +1,337 @@
------------------------------------------------------------------------------
-- 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_fix_pkg.all;
------------------------------------------------------------------------------
-- Entity Declaration
------------------------------------------------------------------------------
entity psi_ms_daq_reg_tmem is
generic (
Streams_g : in integer range 1 to 32;
MaxWindows_g : in integer range 1 to 32
)
port (
-- control Ports
ToscaClk : in std_logic;
Rst : in std_logic;
-- TMEM Interface
TmemRqst : in TmemRqst_t;
TmemResp : out TmemResp_t;
-- Context Memory Interface
CtxStr_Cmd : in ToCtxStr_t;
CtxStr_Resp : out FromCtx_t;
CtxWin_Cmd : in ToCtxWin_t;
CtxWin_Resp : out FromCtx_t;
-- Logic Interface
StrIrq : in std_logic_vector(Streams_g-1 downto 0);
StrEna : out std_logic_vector(Streams_g-1 downto 0);
GlbEna : out std_logic;
IrqOut : out std_logic;
InLevel : in t_aslv16(Streams_g-1 downto 0);
PostTrig : out t_aslv32(Streams_g-1 downto 0);
Arm : out std_logic_vector(Streams_g-1 downto 0);
IsArmed : in std_logic_vector(Streams_g-1 downto 0);
RecMode : out t_aslv2(Streams_g-1 downto 0)
);
end entity;
architecture rtl of psi_ms_daq_reg_tmem is
-- Two process method
type two_process_r is record
Reg_Gcfg_Ena : std_logic;
Reg_Gcfg_IrqEna : std_logic;
Reg_IrqVec : std_logic_vector(Streams_g-1 downto 0);
Reg_IrqEna : std_logic_vector(Streams_g-1 downto 0);
Reg_StrEna : std_logic_vector(Streams_g-1 downto 0);
Reg_MaxLvl : t_aslv16(Streams_g-1 downto 0);
Reg_PostTrig : t_aslv32(Streams_g-1 downto 0);
Reg_Mode_Recm : t_aslv2(Streams_g-1 downto 0);
Reg_Mode_Arm : std_logic_vector(Streams_g-1 downto 0);
Irq : std_logic;
RegRdval : std_logic_vector(63 downto 0);
RdVal : std_logic_vector(63 downto 0);
AddrReg : std_logic_vector(23 downto 0);
end record;
signal r, r_next : two_process_r;
constant DwWrite_c : std_logic_vector(3 downto 0) := "1111";
subtype WeHigh_c is natural range 7 downto 4;
subtype WeLow_c is natural range 3 downto 0;
constant DepthCtxStr_c : integer := Streams_g*32/8;
constant CtxStrAddrHigh_c : integer := log2ceil(Streams_g*32)-1;
signal CtxStr_WeLo : std_logic;
signal CtxStr_WeHi : std_logic;
signal CtxStr_Rdval : std_logic_vector(63 downto 0);
signal CtxStr_AddrB : std_logic_vector(log2ceil(DepthCtxStr_c-1 downto 0);
signal AddrCtxStr : boolean;
constant DepthCtxWin_c : integer := Streams_g*MaxWindows_g*16/8;
constant CtxWinAddrHigh_c : integer := log2ceil(Streams_g*MaxWindows_g*16)-1;
signal CtxWin_WeLo : std_logic;
signal CtxWin_WeHi : std_logic;
signal CtxWin_Rdval : std_logic_vector(63 downto 0);
signal CtxWin_AddrB : std_logic_vector(log2ceil(DepthCtxWin_c-1 downto 0);
signal AddrCtxWin : boolean;
begin
--------------------------------------------
-- Combinatorial Process
--------------------------------------------
p_comb : process( r, TmemRqst, StrIrq, InLevel, IsArmed, CtxStr_Rdval, CtxWin_Rdval)
variable v : two_process_r;
variable Stream_v : integer range 0 to Streams_g-1;
begin
-- *** Hold variables stable ***
v := r;
-- *** Update Maximum Level
for i in 0 to Streams_g-1 loop
if unsigned(InLevel(i)) > unsigned(r.Reg_MaxLvl(i)) then
v.Reg_MaxLvl(i) := InLevel(i);
end if;
end loop;
-- *** General Register Accesses ***
v.RegRdval := (others => '0');
case TmemRqst.ADD is
-- GCFG / GSTAT
when X"000000" =>
-- GCFG
if Rqst.WE(0) = '1' then
v.Reg_Gcfg_Ena := TmemRqst.DATW(0);
end if;
if Rqst.WE(1) = '1' then
v.Reg_Gcfg_Ena := TmemRqst.DATW(8);
end if;
v.RegRdval(0) := r.Reg_Gcfg_Ena;
v.RegRdval(8) := r.Reg_Gcfg_IrqEna;
-- IRQVEC / IRQENA
when X"000010" =>
-- IRQVEC
if Rqst.WE(WeLow_c) = DwWrite_c then
v.Reg_IrqVec := r.IrqVec and (not TmemRqst.DATW(Streams_g-1 downto 0));
end if;
v.RegRdval(Streams_g-1 downto 0) := r.Reg_IrqVec;
-- IRQENA
if Rqst.WE(WeHigh_c) = DwWrite_c then
v.Reg_IrqEna := TmemRqst.DATW(Streams_g+32-1 downto 32);
end if;
v.RegRdval(Streams_g+32-1 downto 32) := r.Reg_IrqEna;
-- STRENA
when X"000020" =>
-- STRENA
if Rqst.WE(WeLow_c) = DwWrite_c then
v.Reg_StrEna := TmemRqst.DATW(Streams_g-1 downto 0);
end if;
v.RegRdval(Streams_g-1 downto 0) := r.Reg_StrEna;
-- others clause
when others => null;
end case;
-- *** Stream Register Accesses ***
v.Reg_Mode_Arm <= (others => '0');
if TmemRqst.ADD(23 downto 9) = X"000" & "001" then
Stream_v := to_integer(unsigned(TmemRqst.ADD(8 downto 4)));
-- MAXLVLn / POSTTRIGn
if TmemRqst.ADD(3 downto 0) = X"0" then
-- MAXLVLn
if Rqst.WE(WeLow_c) = DwWrite_c then
v.Reg_MaxLvl(Stream_v) := (others => '0');
end if;
v.RegRdval(15 downto 0) := r.Reg_MaxLvl(Stream_v);
-- POSTTRIGn
if Rqst.WE(WeHigh_c) = DwWrite_c then
v.Reg_PostTrig(Stream_v) := TmemRqst.DATW(63 downto 32);
end if;
v.RegRdval(63 downto 32) := r.Reg_PostTrig(Stream_v);
end if;
-- MODEn
if TmemRqst.ADD(3 downto 0) = X"8" then
-- MODEn
if Rqst.WE(0) = '1' then
v.Reg_Mode_Recm(Stream_v) := TmemRqst.DATW(1 downto 0);
end if;
if Rqst.WE(1) = '1' then
v.Reg_Mode_Arm(Stream_v) := TmemRqst.DATW(8);
end if;
v.RegRdval(1 downto 0) := r.Reg_Mode_Recm(Stream_v);
v.RegRdval(8) := IsArmed(Stream_v);
end if;
end if;
-- *** Read Data MUX ***
v.AddrReg := TmemRqst.ADD;
v.RdVal := (others => '0');
if r.AddrReg(23 downto 12) = X"000" then
v.RdVal := r.RegRdval;
elsif r.AddrReg(23 downto 12) = X"001" then
v.RdVal := CtxStr_Rdval;
elsif r.AddrReg(23 downto 14) = X"00" & "01" then
v.RdVal := CtxWin_Rdval;
end case;
-- *** IRQ Handling ***
for i in 0 to Streams_g-1 loop
if StrIrq(i) = '1' then
v.Reg_IrqVec(i) := '1';
end if;
end if;
if (r.Reg_IrqVec and r.Reg_IrqEna /= ZerosVector(Streams_g)) and (r.Reg_Gcfg_IrqEna = '1') then
v.Irq := '1';
else
v.Irq := '0';
end if;
-- *** Assign to signal ***
r_next <= v;
end process;
-- *** Registered Outputs ***
TmemResp.PIPE <= "10";
TmemResp.BUSY <= '0';
TmemResp.DATR <= r.RdVal;
IrqOut <= r.Irq;
StrEna <= r.Reg_StrEna;
GlbEna <= r.Reg_Gcfg_Ena;
PostTrig <= r.Reg_PostTrig;
Arm <= r.Reg_Mode_Arm;
RecMode <= r.Reg_Mode_Recm;
--------------------------------------------
-- Sequential Process
--------------------------------------------
p_seq : process(ToscaClk)
begin
if rising_edge(ToscaClk) then
r <= r_next;
if Rst = '1' then
r.Reg_Gcfg_Ena <= '0';
r.Reg_Gcfg_IrqEna <= '0';
r.Reg_IrqVec <= (others => '0');
r.Reg_IrqEna <= (others => '0');
r.Reg_StrEna <= (others => '0');
r.Irq <= '0';
r.Reg_MaxLvl <= (others => (others => '0'));
r.Reg_PostTrig <= (others => (others => '0'));
r.Reg_Mode_Recm <= (others => (others => '0'));
r.Reg_Mode_Arm <= (others => '0');
end if;
end if;
end process;
--------------------------------------------
-- Component Instantiations
--------------------------------------------
-- *** Stream Context Memory ***
-- Signal Assembly
AddrCtxStr <= TmemRqst.ADD(23 downto 12) = X"001";
CtxStr_WeLo <= '1' when Rqst.WE(WeLow_c) = DwWrite_c and AddrCtxStr else '0';
CtxStr_WeHi <= '1' when Rqst.WE(WeHigh_c) = DwWrite_c and AddrCtxStr else '0';
CtxStr_AddrB <= std_logic_vector(to_unsigned(CtxStr_Cmd.Stream, log2ceil(Streams_g))) & CtxStr_Cmd.Sel;
-- Low DWORD memory
i_mem_ctx_lo : entity work.psi_common_tdp_ram_rbw
generic map (
Depth_g => DepthCtxStr_c,
Width_g => 32
)
port map (
ClkA => ToscaClk,
AddrA => TmemRqst.ADD(CtxStrAddrHigh_c downto 4),
WrA => CtxStr_WeLo,
DinA => TmemRqst.DATW(31 downto 0),
DoutA => CtxStr_Rdval(31 downto 0),
ClkB => ToscaClk,
AddrB => CtxStr_AddrB,
WrB => CtxStr_Cmd.WenLo,
DinB => CtxStr_Cmd.WdatLo,
DoutB => CtxStr_Resp.RdatLo
);
-- High DWORD memory
i_mem_ctx_hi : entity work.psi_common_tdp_ram_rbw
generic map (
Depth_g => DepthCtxStr_c,
Width_g => 32
)
port map (
ClkA => ToscaClk,
AddrA => TmemRqst.ADD(CtxStrAddrHigh_c downto 4),
WrA => CtxStr_WeHi,
DinA => TmemRqst.DATW(63 downto 32),
DoutA => CtxStr_Rdval(63 downto 32),
ClkB => ToscaClk,
AddrB => CtxStr_AddrB,
WrB => CtxStr_Cmd.WenHi,
DinB => CtxStr_Cmd.WdatHi,
DoutB => CtxStr_Resp.RdatHi
);
-- *** Window Context Memory ***
-- Signal Assembly
AddrCtxWin <= TmemRqst.ADD(23 downto 14) = X"00" & "01";
CtxWin_WeLo <= '1' when Rqst.WE(WeLow_c) = DwWrite_c and AddrCtxWin else '0';
CtxWin_WeHi <= '1' when Rqst.WE(WeHigh_c) = DwWrite_c and AddrCtxWin else '0';
CtxWin_AddrB <= std_logic_vector(to_unsigned(CtxWin_Cmd.Stream, log2ceil(Streams_g))) & CtxWin_Cmd.Sel;
-- Low DWORD memory
i_mem_win_lo : entity work.psi_common_tdp_ram_rbw
generic map (
Depth_g => DepthCtxWin_c,
Width_g => 32
)
port map (
ClkA => ToscaClk,
AddrA => TmemRqst.ADD(CtxWinAddrHigh_c downto 4),
WrA => CtxWin_WeLo,
DinA => TmemRqst.DATW(31 downto 0),
DoutA => CtxWin_Rdval(31 downto 0),
ClkB => ToscaClk,
AddrB => CtxWin_AddrB,
WrB => CtxWin_Cmd.WenLo,
DinB => CtxWin_Cmd.WdatLo,
DoutB => CtxWin_Resp.RdatLo
);
-- High DWORD memory
i_mem_win_hi : entity work.psi_common_tdp_ram_rbw
generic map (
Depth_g => DepthCtxWin_c,
Width_g => 32
)
port map (
ClkA => ToscaClk,
AddrA => TmemRqst.ADD(CtxWinAddrHigh_c downto 4),
WrA => CtxWin_WeHi,
DinA => TmemRqst.DATW(63 downto 32),
DoutA => CtxWin_Rdval(63 downto 32),
ClkB => ToscaClk,
AddrB => CtxWin_AddrB,
WrB => CtxWin_Cmd.WenHi,
DinB => CtxWin_Cmd.WdatHi,
DoutB => CtxWin_Resp.RdatHi
);
end architecture;