SURF  1.0
SrpV0AxiLite.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : SrpV0AxiLite.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-04-09
5 -- Last update: 2016-05-11
6 -------------------------------------------------------------------------------
7 -- Description: SLAC Register Protocol Version 0, AXI-Lite Interface
8 --
9 -- Documentation: https://confluence.slac.stanford.edu/x/aRmVD
10 --
11 -- Note: This module only supports 32-bit aligned addresses and 32-bit transactions.
12 --
13 -------------------------------------------------------------------------------
14 -- This file is part of 'SLAC Firmware Standard Library'.
15 -- It is subject to the license terms in the LICENSE.txt file found in the
16 -- top-level directory of this distribution and at:
17 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
18 -- No part of 'SLAC Firmware Standard Library', including this file,
19 -- may be copied, modified, propagated, or distributed except according to
20 -- the terms contained in the LICENSE.txt file.
21 -------------------------------------------------------------------------------
22 
23 library ieee;
24 use ieee.std_logic_1164.all;
25 use ieee.std_logic_arith.all;
26 use ieee.std_logic_unsigned.all;
27 
28 use work.StdRtlPkg.all;
29 use work.AxiStreamPkg.all;
30 use work.SsiPkg.all;
31 use work.AxiLitePkg.all;
32 
33 --! @see entity
34  --! @ingroup protocols_srp
35 entity SrpV0AxiLite is
36  generic (
37  -- General Config
38  TPD_G : time := 1 ns;
39 
40  -- FIFO Config
41  RESP_THOLD_G : integer range 0 to (2**24) := 1; -- =1 = normal operation
42  SLAVE_READY_EN_G : boolean := false;
43  EN_32BIT_ADDR_G : boolean := false;
44  BRAM_EN_G : boolean := true;
45  XIL_DEVICE_G : string := "7SERIES"; --Xilinx only generic parameter
46  USE_BUILT_IN_G : boolean := false; --if set to true, this module is only Xilinx compatible only!!!
47  ALTERA_SYN_G : boolean := false;
48  ALTERA_RAM_G : string := "M9K";
49  GEN_SYNC_FIFO_G : boolean := false;
50  FIFO_ADDR_WIDTH_G : integer range 4 to 48 := 9;
51  FIFO_PAUSE_THRESH_G : integer range 1 to (2**24) := 2**8;
52 
53  -- AXI Stream IO Config
55  port (
56 
57  -- Streaming Slave (Rx) Interface (sAxisClk domain)
58  sAxisClk : in sl;
59  sAxisRst : in sl := '0';
63 
64  -- Streaming Master (Tx) Data Interface (mAxisClk domain)
65  mAxisClk : in sl;
66  mAxisRst : in sl := '0';
69 
70  -- AXI Lite Bus (axiLiteClk domain)
71  axiLiteClk : in sl;
72  axiLiteRst : in sl;
77  );
78 
79 end SrpV0AxiLite;
80 
81 architecture rtl of SrpV0AxiLite is
82 
83  constant SLAVE_FIFO_SSI_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(4, TKEEP_COMP_C);
84  constant MASTER_FIFO_SSI_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(4, TKEEP_COMP_C);
85 
86  signal sFifoAxisMaster : AxiStreamMasterType;
87  signal sFifoAxisSlave : AxiStreamSlaveType;
88  signal mFifoAxisMaster : AxiStreamMasterType;
89  signal mFifoAxisSlave : AxiStreamSlaveType;
90  signal mFifoAxisCtrl : AxiStreamCtrlType;
91 
92  type StateType is (S_IDLE_C, S_ADDR_C, S_WRITE_C, S_WRITE_AXI_C, S_READ_SIZE_C,
93  S_READ_C, S_READ_AXI_C, S_STATUS_C, S_DUMP_C);
94 
95  type RegType is record
96  echo : slv(31 downto 0);
97  address : slv(31 downto 0);
98  rdSize : slv(8 downto 0);
99  rdCount : slv(8 downto 0);
100  timer : slv(23 downto 0);
101  state : StateType;
102  timeout : sl;
103  fail : sl;
104 
107  sFifoAxisSlave : AxiStreamSlaveType;
108  mFifoAxisMaster : AxiStreamMasterType;
109 
110  end record RegType;
111 
112  constant REG_INIT_C : RegType := (
113  echo => (others => '0'),
114  address => (others => '0'),
115  rdSize => (others => '0'),
116  rdCount => (others => '0'),
117  timer => (others => '1'),
118  state => S_IDLE_C,
119  timeout => '0',
120  fail => '0',
123  sFifoAxisSlave => AXI_STREAM_SLAVE_INIT_C,
124  mFifoAxisMaster => AXI_STREAM_MASTER_INIT_C);
125 
126  signal r : RegType := REG_INIT_C;
127  signal rin : RegType;
128 
129  -- attribute dont_touch : string;
130  -- attribute dont_touch of r : signal is "TRUE";
131  -- attribute dont_touch of sFifoAxisMaster : signal is "TRUE";
132  -- attribute dont_touch of sFifoAxisSlave : signal is "TRUE";
133  -- attribute dont_touch of mFifoAxisMaster : signal is "TRUE";
134  -- attribute dont_touch of mFifoAxisSlave : signal is "TRUE";
135  -- attribute dont_touch of mFifoAxisCtrl : signal is "TRUE";
136 
137 begin
138 
139  ----------------------------------
140  -- Input FIFO
141  ----------------------------------
142  SlaveAxiStreamFifo : entity work.SsiFifo
143  generic map (
144  TPD_G => TPD_G,
145  EN_FRAME_FILTER_G => true,
146  PIPE_STAGES_G => 0,
148  BRAM_EN_G => BRAM_EN_G,
154  CASCADE_SIZE_G => 1,
156  FIFO_FIXED_THRESH_G => true,
159  MASTER_AXI_CONFIG_G => SLAVE_FIFO_SSI_CONFIG_C)
160  port map (
161  sAxisClk => sAxisClk,
162  sAxisRst => sAxisRst,
165  sAxisCtrl => sAxisCtrl,
166  mAxisClk => axiLiteClk,
167  mAxisRst => axiLiteRst,
168  mAxisMaster => sFifoAxisMaster,
169  mAxisSlave => sFifoAxisSlave);
170 
171  -------------------------------------
172  -- Master State Machine
173  -------------------------------------
174 
175  comb : process (axiLiteRst, mAxiLiteReadSlave, mAxiLiteWriteSlave, mFifoAxisCtrl, r, sFifoAxisMaster) is
176  variable v : RegType;
177  begin
178  v := r;
179 
180  -- Init
181  v.mFifoAxisMaster := sFifoAxisMaster;
182  v.mFifoAxisMaster.tUser := (others => '0');
183  v.mFifoAxisMaster.tKeep := (others => '1');
184  v.mFifoAxisMaster.tValid := '0';
185  v.mFifoAxisMaster.tLast := '0';
186 
187  v.sFifoAxisSlave.tReady := '0';
188 
189 
190  -- State machine
191  case r.state is
192 
193  -- Idle
194  when S_IDLE_C =>
197  v.address := (others => '0');
198  v.rdSize := (others => '0');
199  v.rdCount := (others => '0');
200  v.timeout := '0';
201  v.fail := '0';
202 
203  -- Frame is starting
204  if sFifoAxisMaster.tValid = '1' and mFifoAxisCtrl.pause = '0' then
205  v.sFifoAxisSlave.tReady := '1';
206 
207  -- Bad frame
208  if sFifoAxisMaster.tLast = '0' then
209  v.mFifoAxisMaster.tValid := '1'; -- Echo word 0
210  v.mFifoAxisMaster.tUser := sFifoAxisMaster.tUser;
211  v.mFifoAxisMaster.tData := sFifoAxisMaster.tData;
212  v.state := S_ADDR_C;
213  end if;
214  end if;
215 
216  -- Address Field
217  when S_ADDR_C =>
218  v.sFifoAxisSlave.tReady := '1';
219 
220  if sFifoAxisMaster.tValid = '1' then
221 
222  if EN_32BIT_ADDR_G = true then
223  v.address(31 downto 26) := sFifoAxisMaster.tData(29 downto 24);
224  end if;
225 
226  v.address(25 downto 2) := sFifoAxisMaster.tData(23 downto 0);
227  v.mFifoAxisMaster.tValid := '1'; -- Echo word 1
228 
229  -- Short frame, return error
230  if sFifoAxisMaster.tLast = '1' then
231  v.fail := '1';
232  v.state := S_STATUS_C;
233 
234  -- Read
235  elsif sFifoAxisMaster.tData(31 downto 30) = "00" then
236  v.state := S_READ_SIZE_C;
237 
238  -- Write
239  elsif sFifoAxisMaster.tData(31 downto 30) = "01" then
240  v.state := S_WRITE_C;
241 
242  -- Not supported
243  else
244  v.fail := '1';
245  v.state := S_DUMP_C;
246  end if;
247  end if;
248 
249  -- Prepare Write Transaction
250  when S_WRITE_C =>
251  v.mAxiLiteWriteMaster.awaddr := r.address;
252  v.mAxiLiteWriteMaster.awprot := (others => '0');
253  v.mAxiLiteWriteMaster.wstrb := (others => '1');
254  v.mAxiLiteWriteMaster.wdata := sFifoAxisMaster.tData(31 downto 0);
255  v.sFifoAxisSlave.tReady := '1';
256  v.timer := (others => '1');
257 
258  if sFifoAxisMaster.tValid = '1' then
259  if sFifoAxisMaster.tLast = '1' then
260  -- check tkeep here
261  if (not axiStreamPacked(SLAVE_FIFO_SSI_CONFIG_C, sFifoAxisMaster)) then
262  v.fail := '1';
263  end if;
264  v.state := S_STATUS_C;
265  else
266  v.mFifoAxisMaster.tValid := '1'; -- Echo write data
267  v.mAxiLiteWriteMaster.awvalid := '1';
268  v.mAxiLiteWriteMaster.wvalid := '1';
269  v.mAxiLiteWriteMaster.bready := '1';
270  v.state := S_WRITE_AXI_C;
271  end if;
272  end if;
273 
274  -- Write Transaction, AXI
275  when S_WRITE_AXI_C =>
276  v.timer := r.timer - 1;
277 
278  -- Clear control signals on ack
279  if mAxiLiteWriteSlave.awready = '1' then
280  v.mAxiLiteWriteMaster.awvalid := '0';
281  end if;
282  if mAxiLiteWriteSlave.wready = '1' then
283  v.mAxiLiteWriteMaster.wvalid := '0';
284  end if;
285  if mAxiLiteWriteSlave.bvalid = '1' then
286  v.mAxiLiteWriteMaster.bready := '0';
287 
289  v.fail := '1';
290  end if;
291  end if;
292 
293  -- End transaction on timeout
294  if r.timer = 0 then
295  v.mAxiLiteWriteMaster.awvalid := '0';
296  v.mAxiLiteWriteMaster.wvalid := '0';
297  v.mAxiLiteWriteMaster.bready := '0';
298  v.timeout := '1';
299  end if;
300 
301  -- Transaction is done
302  if v.mAxiLiteWriteMaster.awvalid = '0' and
303  v.mAxiLiteWriteMaster.wvalid = '0' and
304  v.mAxiLiteWriteMaster.bready = '0' then
305 
306  v.address := r.address + 4;
307  v.state := S_WRITE_C;
308  end if;
309 
310  -- Read size
311  when S_READ_SIZE_C =>
312  v.rdCount := (others => '0');
313  v.rdSize := sFifoAxisMaster.tData(8 downto 0);
314 
315  -- Don't read if EOF (need for dump later)
316  if sFifoAxisMaster.tValid = '1' then
317  v.sFifoAxisSlave.tReady := not sFifoAxisMaster.tLast;
318  v.state := S_READ_C;
319  end if;
320 
321  -- Read transaction
322  when S_READ_C =>
323  v.mAxiLiteReadMaster.araddr := r.address;
324  v.mAxiLiteReadMaster.arprot := (others => '0');
325  v.timer := (others => '1');
326 
327  -- Start AXI transaction
328  v.mAxiLiteReadMaster.arvalid := '1';
329  v.mAxiLiteReadMaster.rready := '1';
330  v.state := S_READ_AXI_C;
331 
332  -- Read AXI
333  when S_READ_AXI_C =>
334  v.timer := r.timer - 1;
335 
336  -- Clear control signals on ack
337  if mAxiLiteReadSlave.arready = '1' then
338  v.mAxiLiteReadMaster.arvalid := '0';
339  end if;
340  if mAxiLiteReadSlave.rvalid = '1' then
341  v.mAxiLiteReadMaster.rready := '0';
342  v.mFifoAxisMaster.tData(31 downto 0) := mAxiLiteReadSlave.rdata;
343 
345  v.fail := '1';
346  end if;
347  end if;
348 
349  -- End transaction on timeout
350  if r.timer = 0 then
351  v.mAxiLiteReadMaster.arvalid := '0';
352  v.mAxiLiteReadMaster.rready := '0';
353  v.timeout := '1';
354  end if;
355 
356  -- Transaction is done
357  if v.mAxiLiteReadMaster.arvalid = '0' and v.mAxiLiteReadMaster.rready = '0' then
358  v.mFifoAxisMaster.tValid := '1';
359  v.address := r.address + 4;
360  v.rdCount := r.rdCount + 1;
361 
362  if r.rdCount = r.rdSize then
363  v.state := S_DUMP_C;
364  else
365  v.state := S_READ_C;
366  end if;
367  end if;
368 
369  -- Dump until EOF
370  when S_DUMP_C =>
371  v.sFifoAxisSlave.tReady := '1';
372 
373  if sFifoAxisMaster.tValid = '1' and sFifoAxisMaster.tLast = '1' then
374  -- Check tKeep here
375  if (not axiStreamPacked(SLAVE_FIFO_SSI_CONFIG_C, sFifoAxisMaster)) then
376  v.fail := '1';
377  end if;
378  v.state := S_STATUS_C;
379  end if;
380 
381  -- Send Status
382  when S_STATUS_C =>
383  v.mFifoAxisMaster.tValid := '1';
384  v.mFifoAxisMaster.tLast := '1';
385  v.mFifoAxisMaster.tData(63 downto 0) := (others => '0');
386  v.mFifoAxisMaster.tData(17) := r.timeout;
387  v.mFifoAxisMaster.tData(16) := r.fail;
388  v.state := S_IDLE_C;
389 
390  when others =>
391  v.state := S_IDLE_C;
392 
393  end case;
394 
395  if (axiLiteRst = '1') then
396  v := REG_INIT_C;
397  end if;
398 
399  rin <= v;
400 
403  sFifoAxisSlave <= v.sFifoAxisSlave;
404  mFifoAxisMaster <= r.mFifoAxisMaster;
405 
406  end process comb;
407 
408  seq : process (axiLiteClk) is
409  begin
410  if (rising_edge(axiLiteClk)) then
411  r <= rin after TPD_G;
412  end if;
413  end process seq;
414 
415 
416  ----------------------------------
417  -- Output FIFO
418  ----------------------------------
419  MasterAxiStreamFifo : entity work.AxiStreamFifoV2
420  generic map (
421  TPD_G => TPD_G,
422  INT_PIPE_STAGES_G => 0,
423  PIPE_STAGES_G => 1,
425  BRAM_EN_G => BRAM_EN_G,
431  CASCADE_SIZE_G => 1,
433  FIFO_FIXED_THRESH_G => true,
435  SLAVE_AXI_CONFIG_G => ssiAxiStreamConfig(4, TKEEP_COMP_C),
437  port map (
438  sAxisClk => axiLiteClk,
439  sAxisRst => axiLiteRst,
440  sAxisMaster => mFifoAxisMaster,
441  sAxisSlave => mFifoAxisSlave,
442  sAxisCtrl => mFifoAxisCtrl,
443  mAxisClk => mAxisClk,
444  mAxisRst => mAxisRst,
447 
448 end rtl;
449 
slv( 2 downto 0) arprot
Definition: AxiLitePkg.vhd:62
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
in mAxisRstsl := '0'
out sAxisCtrlAxiStreamCtrlType
ALTERA_RAM_Gstring := "M9K"
SLAVE_READY_EN_Gboolean := true
Definition: SsiFifo.vhd:36
slv( 1 downto 0) rresp
Definition: AxiLitePkg.vhd:90
out mAxiLiteWriteMasterAxiLiteWriteMasterType
USE_BUILT_IN_Gboolean := false
PIPE_STAGES_Gnatural range 0 to 16:= 1
ALTERA_SYN_Gboolean := false
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
out mAxisMasterAxiStreamMasterType
Definition: SsiFifo.vhd:69
FIFO_PAUSE_THRESH_Gpositive := 1
Definition: SsiFifo.vhd:52
ALTERA_RAM_Gstring := "M9K"
AxiStreamMasterType :=(tValid => '0',tData =>( others => '0'),tStrb =>( others => '1'),tKeep =>( others => '1'),tLast => '0',tDest =>( others => '0'),tId =>( others => '0'),tUser =>( others => '0')) AXI_STREAM_MASTER_INIT_C
in axiLiteClksl
in mAxiLiteWriteSlaveAxiLiteWriteSlaveType
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
Definition: SsiFifo.vhd:50
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
slv( 15 downto 0) tKeep
in sAxisMasterAxiStreamMasterType
FIFO_FIXED_THRESH_Gboolean := true
in sAxisClksl
Definition: SsiFifo.vhd:58
in axiLiteRstsl
GEN_SYNC_FIFO_Gboolean := false
GEN_SYNC_FIFO_Gboolean := false
Definition: SsiFifo.vhd:45
TPD_Gtime := 1 ns
XIL_DEVICE_Gstring := "7SERIES"
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
XIL_DEVICE_Gstring := "7SERIES"
Definition: SsiFifo.vhd:43
_library_ ieeeieee
ALTERA_SYN_Gboolean := false
Definition: SsiFifo.vhd:46
AXI_STREAM_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
SLAVE_READY_EN_Gboolean := false
slv( 127 downto 0) tData
GEN_SYNC_FIFO_Gboolean := false
out sAxisCtrlAxiStreamCtrlType
FIFO_PAUSE_THRESH_Ginteger range 1 to ( 2** 24):= 2** 8
BRAM_EN_Gboolean := true
INT_PIPE_STAGES_Gnatural range 0 to 16:= 0
EN_32BIT_ADDR_Gboolean := false
FIFO_FIXED_THRESH_Gboolean := true
Definition: SsiFifo.vhd:51
slv( 2 downto 0) awprot
Definition: AxiLitePkg.vhd:114
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
XIL_DEVICE_Gstring := "7SERIES"
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
BRAM_EN_Gboolean := true
in mAxisClksl
Definition: SsiFifo.vhd:67
BRAM_EN_Gboolean := true
Definition: SsiFifo.vhd:42
USE_BUILT_IN_Gboolean := false
Definition: SsiFifo.vhd:44
slv( 31 downto 0) awaddr
Definition: AxiLitePkg.vhd:113
in sAxisRstsl
Definition: SsiFifo.vhd:59
slv( 127 downto 0) tUser
TPD_Gtime := 1 ns
Definition: SsiFifo.vhd:33
in mAxiLiteReadSlaveAxiLiteReadSlaveType
TPD_Gtime := 1 ns
slv( 1 downto 0) bresp
Definition: AxiLitePkg.vhd:150
out sAxisSlaveAxiStreamSlaveType
ALTERA_SYN_Gboolean := false
in mAxisSlaveAxiStreamSlaveType
Definition: SsiFifo.vhd:70
AxiLiteReadMasterType :=(araddr =>( others => '0'),arprot =>( others => '0'),arvalid => '0',rready => '1') AXI_LITE_READ_MASTER_INIT_C
Definition: AxiLitePkg.vhd:69
RESP_THOLD_Ginteger range 0 to ( 2** 24):= 1
out sAxisSlaveAxiStreamSlaveType
AxiStreamConfigType :=(TSTRB_EN_C => false,TDATA_BYTES_C => 16,TDEST_BITS_C => 4,TID_BITS_C => 0,TKEEP_MODE_C => TKEEP_NORMAL_C,TUSER_BITS_C => 4,TUSER_MODE_C => TUSER_NORMAL_C) AXI_STREAM_CONFIG_INIT_C
in sAxisRstsl := '0'
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
out mAxisMasterAxiStreamMasterType
EN_FRAME_FILTER_Gboolean := true
Definition: SsiFifo.vhd:37
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
AxiLiteWriteMasterType :=(awaddr =>( others => '0'),awprot =>( others => '0'),awvalid => '0',wdata =>( others => '0'),wstrb =>( others => '1'),wvalid => '0',bready => '1') AXI_LITE_WRITE_MASTER_INIT_C
Definition: AxiLitePkg.vhd:125
in sAxisMasterAxiStreamMasterType
out mAxisMasterAxiStreamMasterType
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
SLAVE_AXI_CONFIG_GAxiStreamConfigType := SSI_CONFIG_INIT_C
Definition: SsiFifo.vhd:54
in mAxisSlaveAxiStreamSlaveType
CASCADE_SIZE_Gpositive := 1
Definition: SsiFifo.vhd:48
out sAxisCtrlAxiStreamCtrlType
Definition: SsiFifo.vhd:62
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
ALTERA_RAM_Gstring := "M9K"
Definition: SsiFifo.vhd:47
slv( 3 downto 0) wstrb
Definition: AxiLitePkg.vhd:118
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
PIPE_STAGES_Gnatural := 1
Definition: SsiFifo.vhd:35
MASTER_AXI_CONFIG_GAxiStreamConfigType := SSI_CONFIG_INIT_C
Definition: SsiFifo.vhd:55
in mAxisRstsl
Definition: SsiFifo.vhd:68
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
out sAxisSlaveAxiStreamSlaveType
Definition: SsiFifo.vhd:61
out mAxiLiteReadMasterAxiLiteReadMasterType
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
in sAxisMasterAxiStreamMasterType
Definition: SsiFifo.vhd:60