SURF  1.0
SsiSem.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : SsiSem.vhd
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 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_unsigned.all;
21 use ieee.std_logic_arith.all;
22 
23 use work.StdRtlPkg.all;
24 use work.TextUtilPkg.all;
25 use work.AxiLitePkg.all;
26 use work.AxiStreamPkg.all;
27 use work.SsiPkg.all;
28 use work.SemPkg.all;
29 
30 --! @see entity
31  --! @ingroup xilinx_7Series_sem
32 entity SsiSem is
33  generic (
34  TPD_G : time := 1 ns;
36  COMMON_AXIL_CLK_G : boolean := false;
37  COMMON_AXIS_CLK_G : boolean := false;
38  SLAVE_AXI_CONFIG_G : AxiStreamConfigType := ssiAxiStreamConfig(1);
39  MASTER_AXI_CONFIG_G : AxiStreamConfigType := ssiAxiStreamConfig(1));
40  port (
41  -- SEM clock and reset
42  semClk : in sl;
43  semRst : in sl;
44  -- IPROG Interface
45  fpgaReload : in sl := '0';
46  fpgaReloadAddr : in slv(31 downto 0) := (others => '0');
47  -- AXI-Lite Interface
48  axilClk : in sl;
49  axilRst : in sl;
54  moduleIndex : in slv(3 downto 0) := x"0";
55  -- AXI-Lite Interface
56  axisClk : in sl;
57  axisRst : in sl;
62 end entity SsiSem;
63 
64 architecture rtl of SsiSem is
65 
66  constant SEM_AXIS_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(8);
67  constant RET_CHAR_C : character := cr;
68  constant RET_SLV_C : slv(7 downto 0) := conv_std_logic_vector(character'pos(RET_CHAR_C), 8);
69 
70  type RegType is record
71  sofNext : sl;
72  count : slv(2 downto 0);
73  heartbeatCount : slv(31 downto 0);
74  iprogIcapReqLast : sl;
75  semIb : SemIbType;
78  txSsiMaster : SsiMasterType;
79  end record RegType;
80 
81  constant REG_INIT_C : RegType := (
82  sofNext => '1',
83  count => (others => '0'),
84  heartbeatCount => (others => '0'),
85  iprogIcapReqLast => '0',
86  semIb => SEM_IB_INIT_C,
89  txSsiMaster => ssiMasterInit(SEM_AXIS_CONFIG_C));
90 
91  signal r : RegType := REG_INIT_C;
92  signal rin : RegType;
93 
98 
99  signal txAxisMaster : AxiStreamMasterType;
100  signal txAxisCtrl : AxiStreamCtrlType;
101  signal rxAxisMaster : AxiStreamMasterType;
102  signal rxAxisSlave : AxiStreamSlaveType;
103 
104  signal statusIdle : sl;
105  signal statusHalted : sl;
106  signal semIb : SemIbType;
107  signal semOb : SemObType;
108  signal idx : slv(3 downto 0);
109 
110  -- attribute dont_touch : string;
111  -- attribute dont_touch of r : signal is "TRUE";
112 
113 begin
114 
115  ------------------------------
116  -- Soft Error Mitigation Core
117  ------------------------------
118  U_Sem : entity work.SemWrapper
119  generic map (
120  TPD_G => TPD_G)
121  port map (
122  -- Clock and Reset
123  semClk => semClk,
124  semRst => semRst,
125  -- SEM Interface
126  semIb => semIb,
127  semOb => semOb);
128 
129  ------------------------
130  -- Sync the Module index
131  ------------------------
132  U_SyncFifo : entity work.SynchronizerFifo
133  generic map (
134  TPD_G => TPD_G,
136  BRAM_EN_G => false,
137  DATA_WIDTH_G => 4,
138  ADDR_WIDTH_G => 4)
139  port map (
140  rst => axilRst,
141  wr_clk => axilClk,
142  din => moduleIndex,
143  rd_clk => semClk,
144  dout => idx);
145 
146  -------------------------------------
147  -- Synchronize AXI-Lite bus to semClk
148  -------------------------------------
149  U_AxiLiteAsync : entity work.AxiLiteAsync
150  generic map (
151  TPD_G => TPD_G,
154  port map (
155  sAxiClk => axilClk,
156  sAxiClkRst => axilRst,
161  mAxiClk => semClk,
162  mAxiClkRst => semRst,
167 
168  ---------------------------------
169  -- Synchronize AXIS bus to semClk
170  ---------------------------------
171  U_TxFifo : entity work.AxiStreamFifoV2
172  generic map (
173  TPD_G => TPD_G,
174  SLAVE_READY_EN_G => false,
175  VALID_THOLD_G => 0,
176  BRAM_EN_G => false,
177  USE_BUILT_IN_G => false,
179  CASCADE_SIZE_G => 1,
180  FIFO_ADDR_WIDTH_G => 4,
181  FIFO_FIXED_THRESH_G => true,
182  FIFO_PAUSE_THRESH_G => 14,
183  SLAVE_AXI_CONFIG_G => SEM_AXIS_CONFIG_C,
185  port map (
186  sAxisClk => semClk,
187  sAxisRst => semRst,
188  sAxisMaster => txAxisMaster,
189  sAxisCtrl => txAxisCtrl,
190  mAxisClk => axisClk,
191  mAxisRst => axisRst,
194 
195  U_RxFifo : entity work.AxiStreamFifoV2
196  generic map (
197  TPD_G => TPD_G,
198  SLAVE_READY_EN_G => true,
199  VALID_THOLD_G => 1,
200  BRAM_EN_G => false,
201  USE_BUILT_IN_G => false,
203  CASCADE_SIZE_G => 1,
204  FIFO_ADDR_WIDTH_G => 4,
205  FIFO_FIXED_THRESH_G => true,
206  FIFO_PAUSE_THRESH_G => 14,
208  MASTER_AXI_CONFIG_G => ssiAxiStreamConfig(1))
209  port map (
210  sAxisClk => axisClk,
211  sAxisRst => axisRst,
214  mAxisClk => semClk,
215  mAxisRst => semRst,
216  mAxisMaster => rxAxisMaster,
217  mAxisSlave => rxAxisSlave);
218 
219  ------------------------------
220  -- Determined the state of SEM
221  ------------------------------
222  statusIdle <= not (semOb.initialization or semOb.observation or semOb.correction or semOb.classification or semOb.injection);
223  statusHalted <= (semOb.initialization and semOb.observation and semOb.correction and semOb.classification and semOb.injection);
224 
225  comb : process (axiReadMaster, axiWriteMaster, idx, r, rxAxisMaster, semOb,
226  semRst, statusHalted, statusIdle, txAxisCtrl) is
227  variable v : RegType;
228  variable axilEp : AxiLiteEndpointType;
229  variable c : integer range 0 to 7;
230  begin
231  -- Latch the current value
232  v := r;
233 
234  -- Reset strobes
235  v.semIb.injectStrobe := '0';
236 
237  -- Count heartbeats
238  if (semOb.heartbeat = '1') then
239  v.heartbeatCount := r.heartbeatCount + 1;
240  end if;
241 
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(character'pos('F'), 8);
247  v.txSsiMaster.data(15 downto 8) := toSlv(character'pos('E'), 8);
248  v.txSsiMaster.data(23 downto 16) := toSlv(character'pos('B'), 8);
249  v.txSsiMaster.data(31 downto 24) := toSlv(character'pos(' '), 8);
250  v.txSsiMaster.data(39 downto 32) := toSlv(character'pos('0'), 8);
251  case idx is
252  when X"0" =>
253  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('0'), 8);
254  when X"1" =>
255  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('1'), 8);
256  when X"2" =>
257  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('2'), 8);
258  when X"3" =>
259  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('3'), 8);
260  when X"4" =>
261  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('4'), 8);
262  when X"5" =>
263  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('5'), 8);
264  when X"6" =>
265  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('6'), 8);
266  when X"7" =>
267  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('7'), 8);
268  when X"8" =>
269  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('8'), 8);
270  when X"9" =>
271  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('9'), 8);
272  when others =>
273  v.txSsiMaster.data(47 downto 40) := toSlv(character'pos('?'), 8);
274  end case;
275  v.txSsiMaster.data(55 downto 48) := toSlv(character'pos(':'), 8);
276  v.txSsiMaster.data(63 downto 56) := toSlv(character'pos(' '), 8);
277  v.txSsiMaster.valid := '1';
278  v.txSsiMaster.sof := '1';
279  v.txSsiMaster.eof := '0';
280  v.count := (others => '0');
281  v.sofNext := '0';
282  else
283  if (semOb.txWrite = '1') then
284  v.count := r.count + 1;
285  end if;
286  -- Stupid Vivado can't handle dynamic ranges properly so we have to do this shit instead
287  c := conv_integer(r.count);
288  case c is
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;
298  end case;
299 
300  v.txSsiMaster.valid := toSl((c = 7) or (semOb.txData = RET_SLV_C)) and semOb.txWrite;
301  v.txSsiMaster.sof := '0';
302  v.txSsiMaster.eof := toSl(semOb.txData = RET_SLV_C) and semOb.txWrite;
303 
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
307  v.sofNext := '1';
308  end if;
309  end if;
310  end if;
311 
312  ------------------------
313  -- AXI-Lite Transactions
314  ------------------------
315 
316  -- Determine the transaction type
317  axiSlaveWaitTxn(axilEp, axiWriteMaster, axiReadMaster, v.axiWriteSlave, v.axiReadSlave);
318 
319  axiSlaveRegisterR(axilEp, x"00", 0, semOb.initialization);
320  axiSlaveRegisterR(axilEp, x"00", 1, semOb.observation);
321  axiSlaveRegisterR(axilEp, x"00", 2, semOb.correction);
322  axiSlaveRegisterR(axilEp, x"00", 3, semOb.classification);
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);
327  axiSlaveRegisterR(axilEp, x"00", 8, semOb.uncorrectable);
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));
332 
333  axiSlaveDefault(axilEp, v.axiWriteSlave, v.axiReadSlave, AXI_ERROR_RESP_G);
334 
335  -----------------------------
336  -- Allow IPROG access to ICAP
337  -----------------------------
338  v.iprogIcapReqLast := semOb.iprogIcapReq;
339  if (semOb.iprogIcapReq = '1' and r.iprogIcapReqLast = '0') then
340  v.semIb.injectStrobe := '1';
341  v.semIb.injectAddress := X"E000000000";
342  end if;
343 
344  --------
345  -- Reset
346  --------
347  if (semRst = '1') then
348  v := REG_INIT_C;
349  end if;
350 
351  -- Register the variable for next clock cycle
352  rin <= v;
353 
354  -- Outputs
357  semIb <= r.semIb;
358  semIb.iprogIcapGrant <= statusIdle and semOb.iprogIcapReq;
359  semIb.rxData <= rxAxisMaster.tData(7 downto 0);
360  semIb.rxEmpty <= not(rxAxisMaster.tValid);
361  semIb.txFull <= txAxisCtrl.pause;
362  txAxisMaster <= ssi2AxisMaster(SEM_AXIS_CONFIG_C, r.txSsiMaster);
363  rxAxisSlave.tReady <= semOb.rxRead;
364 
365  end process comb;
366 
367  seq : process (semClk) is
368  begin
369  if (rising_edge(semClk)) then
370  r <= rin after TPD_G;
371  end if;
372  end process seq;
373 
374 end rtl;
slv( 127 downto 0) data
Definition: SsiPkg.vhd:67
in axisClksl
Definition: SsiSem.vhd:56
in axisRstsl
Definition: SsiSem.vhd:57
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')
Definition: SsiSem.vhd:46
in semIbAxisMasterAxiStreamMasterType
Definition: SsiSem.vhd:60
sl iprogIcapReq
Definition: SemPkg.vhd:39
sl sof
Definition: SsiPkg.vhd:72
SemIbType
Definition: SemPkg.vhd:42
in semObAxisSlaveAxiStreamSlaveType
Definition: SsiSem.vhd:59
out axilReadSlaveAxiLiteReadSlaveType
Definition: SsiSem.vhd:51
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
Definition: SsiSem.vhd:35
sl classification
Definition: SemPkg.vhd:32
in dinslv( DATA_WIDTH_G- 1 downto 0)
sl injectStrobe
Definition: SemPkg.vhd:43
sl txWrite
Definition: SemPkg.vhd:37
in semClksl
Definition: SsiSem.vhd:42
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
ADDR_WIDTH_Ginteger range 2 to 48:= 4
in axilReadMasterAxiLiteReadMasterType
Definition: SsiSem.vhd:50
out mAxiReadMasterAxiLiteReadMasterType
sl rxEmpty
Definition: SemPkg.vhd:47
SLAVE_READY_EN_Gboolean := true
FIFO_FIXED_THRESH_Gboolean := true
sl heartbeat
Definition: SemPkg.vhd:28
BRAM_EN_Gboolean := false
AxiLiteWriteMasterType axiWriteMaster
Definition: AxiLitePkg.vhd:181
in mAxiWriteSlaveAxiLiteWriteSlaveType
GEN_SYNC_FIFO_Gboolean := false
AxiLiteReadSlaveType axiReadSlave
Definition: AxiLitePkg.vhd:180
COMMON_AXIS_CLK_Gboolean := false
Definition: SsiSem.vhd:37
out sAxiWriteSlaveAxiLiteWriteSlaveType
SLAVE_AXI_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 1)
Definition: SsiSem.vhd:38
out doutslv( DATA_WIDTH_G- 1 downto 0)
in axilWriteMasterAxiLiteWriteMasterType
Definition: SsiSem.vhd:52
SemIbType :=(injectStrobe => '0',injectAddress =>( others => '0'),txFull => '1',rxData =>( others => '0'),rxEmpty => '0',iprogIcapGrant => '0') SEM_IB_INIT_C
Definition: SemPkg.vhd:51
sl txFull
Definition: SemPkg.vhd:45
in sAxiReadMasterAxiLiteReadMasterType
slv( 7 downto 0) rxData
Definition: SemPkg.vhd:46
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
Definition: AxiLitePkg.vhd:36
slv( 127 downto 0) tData
in sAxiWriteMasterAxiLiteWriteMasterType
sl correction
Definition: SemPkg.vhd:31
AxiLiteReadMasterType axiReadMaster
Definition: AxiLitePkg.vhd:179
in semIbSemIbType
Definition: SemWrapper.vhd:42
SsiMasterType
Definition: SsiPkg.vhd:65
AxiLiteWriteSlaveType axiWriteSlave
Definition: AxiLitePkg.vhd:182
COMMON_CLK_Gboolean := false
out semObAxisMasterAxiStreamMasterType
Definition: SsiSem.vhd:58
sl iprogIcapGrant
Definition: SemPkg.vhd:48
TPD_Gtime := 1 ns
Definition: SemWrapper.vhd:33
SemObType
Definition: SemPkg.vhd:27
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
BRAM_EN_Gboolean := true
in axilClksl
Definition: SsiSem.vhd:48
_library_ ieeeieee
Definition: SemWrapper.vhd:18
sl initialization
Definition: SemPkg.vhd:29
in semClksl
Definition: SemWrapper.vhd:36
TPD_Gtime := 1 ns
in moduleIndexslv( 3 downto 0) := x"0"
Definition: SsiSem.vhd:54
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:95
out sAxiReadSlaveAxiLiteReadSlaveType
sl observation
Definition: SemPkg.vhd:30
in semRstsl
Definition: SemWrapper.vhd:37
sl valid
Definition: SsiPkg.vhd:66
out sAxisSlaveAxiStreamSlaveType
MASTER_AXI_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 1)
Definition: SsiSem.vhd:39
sl uncorrectable
Definition: SemPkg.vhd:35
COMMON_AXIL_CLK_Gboolean := false
Definition: SsiSem.vhd:36
sl injection
Definition: SemPkg.vhd:33
slv( 7 downto 0) txData
Definition: SemPkg.vhd:36
out semIbAxisSlaveAxiStreamSlaveType
Definition: SsiSem.vhd:61
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
sl essential
Definition: SemPkg.vhd:34
sl rxRead
Definition: SemPkg.vhd:38
slv( 39 downto 0) injectAddress
Definition: SemPkg.vhd:44
out axilWriteSlaveAxiLiteWriteSlaveType
Definition: SsiSem.vhd:53
in sAxisMasterAxiStreamMasterType
in mAxiReadSlaveAxiLiteReadSlaveType
in mAxiClkRstsl
TPD_Gtime := 1 ns
Definition: SsiSem.vhd:34
out mAxisMasterAxiStreamMasterType
in fpgaReloadsl := '0'
Definition: SsiSem.vhd:45
in mAxisSlaveAxiStreamSlaveType
out semObSemObType
Definition: SemWrapper.vhd:43
CASCADE_SIZE_Ginteger range 1 to ( 2** 24):= 1
USE_BUILT_IN_Gboolean := false
TPD_Gtime := 1 ns
in semRstsl
Definition: SsiSem.vhd:43
FIFO_PAUSE_THRESH_Ginteger range 1 to ( 2** 24):= 1
VALID_THOLD_Ginteger range 0 to ( 2** 24):= 1
in axilRstsl
Definition: SsiSem.vhd:49
sl eof
Definition: SsiPkg.vhd:73
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:156
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
out mAxiWriteMasterAxiLiteWriteMasterType
in sAxiClkRstsl
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
std_logic_vector slv
Definition: StdRtlPkg.vhd:29