1 ------------------------------------------------------------------------------- 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2015-06-15 5 -- Last update: 2017-02-08 6 ------------------------------------------------------------------------------- 7 -- Description: SSI wrapper for 7-series SEM module 8 ------------------------------------------------------------------------------- 9 -- This file is part of 'SLAC Firmware Standard Library'. 10 -- It is subject to the license terms in the LICENSE.txt file found in the 11 -- top-level directory of this distribution and at: 12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 13 -- No part of 'SLAC Firmware Standard Library', including this file, 14 -- may be copied, modified, propagated, or distributed except according to 15 -- the terms contained in the LICENSE.txt file. 16 ------------------------------------------------------------------------------- 19 use ieee.std_logic_1164.
all;
20 use ieee.std_logic_unsigned.
all;
21 use ieee.std_logic_arith.
all;
31 --! @ingroup xilinx_7Series_sem 41 -- SEM clock and reset 64 architecture rtl
of SsiSem is
67 constant RET_CHAR_C : := cr;
68 constant RET_SLV_C : slv(7 downto 0) := conv_std_logic_vector('pos(RET_CHAR_C), 8);
70 type RegType is record 72 count : slv(2 downto 0);
73 heartbeatCount : slv(31 downto 0);
74 iprogIcapReqLast : sl;
81 constant REG_INIT_C : RegType := ( 83 count => (others => '0'), 84 heartbeatCount => (others => '0'), 85 iprogIcapReqLast => '0', 89 txSsiMaster => ssiMasterInit(SEM_AXIS_CONFIG_C));
91 signal r : RegType := REG_INIT_C;
104 signal statusIdle : sl;
105 signal statusHalted : sl;
108 signal idx : slv(3 downto 0);
110 -- attribute dont_touch : string; 111 -- attribute dont_touch of r : signal is "TRUE"; 115 ------------------------------ 116 -- Soft Error Mitigation Core 117 ------------------------------ 129 ------------------------ 130 -- Sync the Module index 131 ------------------------ 146 ------------------------------------- 147 -- Synchronize AXI-Lite bus to semClk 148 ------------------------------------- 168 --------------------------------- 169 -- Synchronize AXIS bus to semClk 170 --------------------------------- 219 ------------------------------ 220 -- Determined the state of SEM 221 ------------------------------ 226 semRst, statusHalted, statusIdle, txAxisCtrl)
is 227 variable v : RegType;
229 variable c : range 0 to 7;
231 -- Latch the current value 239 v.heartbeatCount := r.heartbeatCount + 1;
242 --------------------------------------------------- 243 -- Convert tx data stream to 64-bit wide SSI frames 244 --------------------------------------------------- 245 if (r.sofNext = '1') then 246 v.txSsiMaster.data(7 downto 0) := toSlv('pos('F'), 8);
247 v.txSsiMaster.data(15 downto 8) := toSlv('pos('E'), 8);
248 v.txSsiMaster.data(23 downto 16) := toSlv('pos('B'), 8);
249 v.txSsiMaster.data(31 downto 24) := toSlv('pos(' '), 8);
250 v.txSsiMaster.data(39 downto 32) := toSlv('pos('0'), 8);
253 v.txSsiMaster.data(47 downto 40) := toSlv('pos('0'), 8);
255 v.txSsiMaster.data(47 downto 40) := toSlv('pos('1'), 8);
257 v.txSsiMaster.data(47 downto 40) := toSlv('pos('2'), 8);
259 v.txSsiMaster.data(47 downto 40) := toSlv('pos('3'), 8);
261 v.txSsiMaster.data(47 downto 40) := toSlv('pos('4'), 8);
263 v.txSsiMaster.data(47 downto 40) := toSlv('pos('5'), 8);
265 v.txSsiMaster.data(47 downto 40) := toSlv('pos('6'), 8);
267 v.txSsiMaster.data(47 downto 40) := toSlv('pos('7'), 8);
269 v.txSsiMaster.data(47 downto 40) := toSlv('pos('8'), 8);
271 v.txSsiMaster.data(47 downto 40) := toSlv('pos('9'), 8);
273 v.txSsiMaster.data(47 downto 40) := toSlv('pos('?
'), 8);
275 v.txSsiMaster.data(55 downto 48) := toSlv('pos(':'), 8);
276 v.txSsiMaster.data(63 downto 56) := toSlv('pos(' '), 8);
277 v.txSsiMaster.valid := '1';
278 v.txSsiMaster.sof := '1';
279 v.txSsiMaster.eof := '0';
280 v.count := (others => '0');
284 v.count := r.count + 1;
286 -- Stupid Vivado can't handle dynamic ranges properly so we have to do this shit instead 287 c := conv_integer(r.count);
289 when 0 => v.txSsiMaster.data := (others => '0');
290 v.txSsiMaster.data(7 downto 0) := semOb.txData;
291 when 1 => v.txSsiMaster.data(15 downto 8) := semOb.txData;
292 when 2 => v.txSsiMaster.data(23 downto 16) := semOb.txData;
293 when 3 => v.txSsiMaster.data(31 downto 24) := semOb.txData;
294 when 4 => v.txSsiMaster.data(39 downto 32) := semOb.txData;
295 when 5 => v.txSsiMaster.data(47 downto 40) := semOb.txData;
296 when 6 => v.txSsiMaster.data(55 downto 48) := semOb.txData;
297 when 7 => v.txSsiMaster.data(63 downto 56) := semOb.txData;
301 v.txSsiMaster.sof := '0';
304 if (v.txSsiMaster.valid = '1') then 305 -- Reset count on EOF so next frame starts at 0 306 if (v.txSsiMaster.eof = '1') then 312 ------------------------ 313 -- AXI-Lite Transactions 314 ------------------------ 316 -- Determine the transaction type 320 axiSlaveRegisterR(axilEp, x"00", 1, semOb.observation);
321 axiSlaveRegisterR(axilEp, x"00", 2, semOb.correction);
323 axiSlaveRegisterR(axilEp, x"00", 4, semOb.injection);
324 axiSlaveRegisterR(axilEp, x"00", 5, statusIdle);
325 axiSlaveRegisterR(axilEp, x"00", 6, statusHalted);
326 axiSlaveRegisterR(axilEp, x"00", 7, semOb.essential);
328 axiSlaveRegisterR(axilEp, x"04", 0, r.heartbeatCount);
329 axiSlaveRegister(axilEp, x"0C", 0, v.semIb.injectStrobe);
330 axiSlaveRegister(axilEp, x"10", 0, v.semIb.injectAddress(31 downto 0));
331 axiSlaveRegister(axilEp, x"14", 0, v.semIb.injectAddress(39 downto 32));
335 ----------------------------- 336 -- Allow IPROG access to ICAP 337 ----------------------------- 339 if (semOb.iprogIcapReq = '1' and r.iprogIcapReqLast = '0') then 351 -- Register the variable for next clock cycle 362 txAxisMaster <= ssi2AxisMaster(SEM_AXIS_CONFIG_C, r.txSsiMaster);
369 if (rising_edge(semClk)) then 370 r <= rin after TPD_G;
COMMON_CLK_Gboolean := false
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
out sAxisCtrlAxiStreamCtrlType
in fpgaReloadAddrslv( 31 downto 0) :=( others => '0')
in semIbAxisMasterAxiStreamMasterType
in semObAxisSlaveAxiStreamSlaveType
out axilReadSlaveAxiLiteReadSlaveType
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
in dinslv( DATA_WIDTH_G- 1 downto 0)
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
ADDR_WIDTH_Ginteger range 2 to 48:= 4
in axilReadMasterAxiLiteReadMasterType
out mAxiReadMasterAxiLiteReadMasterType
SLAVE_READY_EN_Gboolean := true
FIFO_FIXED_THRESH_Gboolean := true
BRAM_EN_Gboolean := false
AxiLiteWriteMasterType axiWriteMaster
in mAxiWriteSlaveAxiLiteWriteSlaveType
GEN_SYNC_FIFO_Gboolean := false
AxiLiteReadSlaveType axiReadSlave
COMMON_AXIS_CLK_Gboolean := false
out sAxiWriteSlaveAxiLiteWriteSlaveType
SLAVE_AXI_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 1)
out doutslv( DATA_WIDTH_G- 1 downto 0)
in axilWriteMasterAxiLiteWriteMasterType
SemIbType :=(injectStrobe => '0',injectAddress =>( others => '0'),txFull => '1',rxData =>( others => '0'),rxEmpty => '0',iprogIcapGrant => '0') SEM_IB_INIT_C
in sAxiReadMasterAxiLiteReadMasterType
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
in sAxiWriteMasterAxiLiteWriteMasterType
AxiLiteReadMasterType axiReadMaster
AxiLiteWriteSlaveType axiWriteSlave
COMMON_CLK_Gboolean := false
out semObAxisMasterAxiStreamMasterType
in moduleIndexslv( 3 downto 0) := x"0"
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
out sAxiReadSlaveAxiLiteReadSlaveType
out sAxisSlaveAxiStreamSlaveType
MASTER_AXI_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 1)
COMMON_AXIL_CLK_Gboolean := false
out semIbAxisSlaveAxiStreamSlaveType
slv( 39 downto 0) injectAddress
out axilWriteSlaveAxiLiteWriteSlaveType
in sAxisMasterAxiStreamMasterType
in mAxiReadSlaveAxiLiteReadSlaveType
out mAxisMasterAxiStreamMasterType
in mAxisSlaveAxiStreamSlaveType
CASCADE_SIZE_Ginteger range 1 to ( 2** 24):= 1
USE_BUILT_IN_Gboolean := false
FIFO_PAUSE_THRESH_Ginteger range 1 to ( 2** 24):= 1
VALID_THOLD_Ginteger range 0 to ( 2** 24):= 1
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
out mAxiWriteMasterAxiLiteWriteMasterType
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16