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