SURF  1.0
AxiLiteSrpV0.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiLiteSrpV0.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-04-09
5 -- Last update: 2016-06-09
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 AxiLiteSrpV0 is
36  generic (
37  -- General Config
38  TPD_G : time := 1 ns;
39 
41 
42  -- FIFO Config
43  RESP_THOLD_G : integer range 0 to (2**24) := 1; -- =1 = normal operation
44  SLAVE_READY_EN_G : boolean := false;
45  BRAM_EN_G : boolean := true;
46  XIL_DEVICE_G : string := "7SERIES"; --Xilinx only generic parameter
47  USE_BUILT_IN_G : boolean := false; --if set to true, this module is only Xilinx compatible only!!!
48  ALTERA_SYN_G : boolean := false;
49  ALTERA_RAM_G : string := "M9K";
50  GEN_SYNC_FIFO_G : boolean := false;
51  FIFO_ADDR_WIDTH_G : integer range 4 to 48 := 9;
52  FIFO_PAUSE_THRESH_G : integer range 1 to (2**24) := 2**8;
53 
54  -- AXI Stream IO Config
56  port (
57 
58  -- Streaming Master (Tx) Data Interface (mAxisClk domain)
59  mAxisClk : in sl;
60  mAxisRst : in sl := '0';
63 
64  -- Streaming Slave (Rx) Interface (sAxisClk domain)
65  sAxisClk : in sl;
66  sAxisRst : in sl := '0';
70 
71  -- AXI Lite Bus Slave (axiLiteClk domain)
72  axilClk : in sl;
73  axilRst : in sl;
78  );
79 
80 end AxiLiteSrpV0;
81 
82 architecture rtl of AxiLiteSrpV0 is
83 
84  constant INTERNAL_AXIS_CFG_C : AxiStreamConfigType := ssiAxiStreamConfig(16, TKEEP_COMP_C);
85 
86  constant TIMEOUT_COUNT_C : integer := 156250000;
87 
88  signal rxFifoAxisMaster : AxiStreamMasterType;
89  signal rxFifoAxisSlave : AxiStreamSlaveType;
90  signal txFifoAxisMaster : AxiStreamMasterType;
91  signal txFifoAxisSlave : AxiStreamSlaveType;
92 
93 
94  type StateType is (WAIT_AXIL_REQ_S, WAIT_AXIS_RESP_S, BLEED_S);
95 
96  type RegType is record
97  state : StateType;
98  txnCount : slv(31 downto 0);
99  timeoutCount : slv(31 downto 0);
102  txFifoAxisMaster : AxiStreamMasterType;
103  rxFifoAxisSlave : AxiStreamSlaveType;
104  end record RegType;
105 
106  constant REG_INIT_C : RegType := (
107  state => WAIT_AXIL_REQ_S,
108  txnCount => (others => '0'),
109  timeoutCount => (others => '0'),
112  txFifoAxisMaster => AXI_STREAM_MASTER_INIT_C,
113  rxFifoAxisSlave => AXI_STREAM_SLAVE_INIT_C);
114 
115 
116  signal r : RegType := REG_INIT_C;
117  signal rin : RegType;
118 
119  -- attribute dont_touch : string;
120  -- attribute dont_touch of r : signal is "TRUE";
121  -- attribute dont_touch of rxFifoAxisMaster : signal is "TRUE";
122  -- attribute dont_touch of rxFifoAxisSlave : signal is "TRUE";
123  -- attribute dont_touch of txFifoAxisMaster : signal is "TRUE";
124  -- attribute dont_touch of txFifoAxisSlave : signal is "TRUE";
125 
126 begin
127 
128  ----------------------------------
129  -- Output FIFO
130  ----------------------------------
131  TxAxiStreamFifo : entity work.AxiStreamFifoV2
132  generic map (
133  TPD_G => TPD_G,
134  PIPE_STAGES_G => 1,
135  INT_PIPE_STAGES_G => 0,
137  BRAM_EN_G => BRAM_EN_G,
143  CASCADE_SIZE_G => 1,
145  FIFO_FIXED_THRESH_G => true,
147  SLAVE_AXI_CONFIG_G => INTERNAL_AXIS_CFG_C,
149  port map (
150  sAxisClk => axilClk,
151  sAxisRst => axilRst,
152  sAxisMaster => txFifoAxisMaster,
153  sAxisSlave => txFifoAxisSlave,
154  sAxisCtrl => open,
155  mAxisClk => mAxisClk,
156  mAxisRst => mAxisRst,
159 
160  ----------------------------------
161  -- Input FIFO
162  ----------------------------------
163  RxAxiStreamFifo : entity work.AxiStreamFifoV2
164  generic map (
165  TPD_G => TPD_G,
166  PIPE_STAGES_G => 1,
167  INT_PIPE_STAGES_G => 0,
169  BRAM_EN_G => BRAM_EN_G,
175  CASCADE_SIZE_G => 1,
177  FIFO_FIXED_THRESH_G => true,
180  MASTER_AXI_CONFIG_G => INTERNAL_AXIS_CFG_C)
181  port map (
182  sAxisClk => sAxisClk,
183  sAxisRst => sAxisRst,
186  sAxisCtrl => sAxisCtrl,
187  mAxisClk => axilClk,
188  mAxisRst => axilRst,
189  mAxisMaster => rxFifoAxisMaster,
190  mAxisSlave => rxFifoAxisSlave);
191 
192  -------------------------------------
193  -- Master State Machine
194  -------------------------------------
195 
196  comb : process (axilRst, r, rxFifoAxisMaster, sAxilReadMaster, sAxilWriteMaster, txFifoAxisSlave) is
197  variable v : RegType;
198  variable axilStatus : AxiLiteStatusType;
199  begin
200  v := r;
201 
202  v.rxFifoAxisSlave.tReady := '0';
203 
204  if (txFifoAxisSlave.tReady = '1') then
205  v.txFifoAxisMaster.tValid := '0';
206  end if;
207 
208  axiSlaveWaitTxn(sAxilWriteMaster, sAxilReadMaster, v.sAxilWriteSlave, v.sAxilReadSlave, axilStatus);
209 
210  case (r.state) is
211 
212  when WAIT_AXIL_REQ_S =>
213  v.timeoutCount := (others => '0');
214  if (axilStatus.writeEnable = '1') then
215  v.txFifoAxisMaster.tData(31 downto 0) := r.txnCount;
216  v.txFifoAxisMaster.tData(61 downto 32) := sAxilWriteMaster.awaddr(31 downto 2);
217  v.txFifoAxisMaster.tData(63 downto 62) := "01";
218  v.txFifoAxisMaster.tData(95 downto 64) := sAxilWriteMaster.wdata(31 downto 0);
219  v.txFifoAxisMaster.tData(127 downto 96) := (others => '0');
220  v.txFifoAxisMaster.tKeep := X"FFFF";
221  v.txFifoAxisMaster.tValid := '1';
222  v.txFifoAxisMaster.tLast := '1';
223  ssiSetUserSof(INTERNAL_AXIS_CFG_C, v.txFifoAxisMaster, '1');
224  v.state := WAIT_AXIS_RESP_S;
225  elsif (axilStatus.readEnable = '1') then
226  v.txFifoAxisMaster.tData(31 downto 0) := r.txnCount;
227  v.txFifoAxisMaster.tData(61 downto 32) := sAxilReadMaster.araddr(31 downto 2);
228  v.txFifoAxisMaster.tData(63 downto 62) := "00";
229  v.txFifoAxisMaster.tData(95 downto 64) := (others => '0');
230  v.txFifoAxisMaster.tData(127 downto 96) := (others => '0');
231  v.txFifoAxisMaster.tKeep := X"FFFF";
232  v.txFifoAxisMaster.tValid := '1';
233  v.txFifoAxisMaster.tLast := '1';
234  ssiSetUserSof(INTERNAL_AXIS_CFG_C, v.txFifoAxisMaster, '1');
235  v.state := WAIT_AXIS_RESP_S;
236  end if;
237 
238  when WAIT_AXIS_RESP_S =>
239  v.timeoutCount := r.timeoutCount + 1;
240  if (rxFifoAxisMaster.tValid = '1') then
241  v.txnCount := r.txnCount + 1;
242  v.rxFifoAxisSlave.tReady := '1';
243 
244  -- Check write response
245  if (axilStatus.writeEnable = '1') then
246  if (rxFifoAxisMaster.tData(31 downto 0) = r.txnCount and
247  rxFifoAxisMaster.tData(61 downto 32) = sAxilWriteMaster.awaddr(31 downto 2) and
248  rxFifoAxisMaster.tData(63 downto 62) = "01" and
249  rxFifoAxisMaster.tData(95 downto 64) = sAxilWriteMaster.wdata and
250  rxFifoAxisMaster.tData(127 downto 96) = 0 and
251  rxFifoAxisMaster.tKeep = X"FFFF" and
252  rxFifoAxisMaster.tLast = '1' and
253  ssiGetUserSof(INTERNAL_AXIS_CFG_C, rxFifoAxisMaster) = '1')
254  then
255  axiSlaveWriteResponse(v.sAxilWriteSlave, AXI_RESP_OK_C);
256  v.state := WAIT_AXIL_REQ_S;
257  elsif (rxFifoAxisMaster.tLast = '0') then
258  axiSlaveWriteResponse(v.sAxilWriteSlave, AXIL_ERR_RESP_G);
259  v.state := BLEED_S;
260  else
261  axiSlaveWriteResponse(v.sAxilWriteSlave, AXIL_ERR_RESP_G);
262  v.state := WAIT_AXIL_REQ_S;
263  end if;
264 
265  -- Check read response
266  elsif (axilStatus.readEnable = '1') then
267  if (rxFifoAxisMaster.tData(31 downto 0) = r.txnCount and
268  rxFifoAxisMaster.tData(61 downto 32) = sAxilReadMaster.araddr(31 downto 2) and
269  rxFifoAxisMaster.tData(63 downto 62) = "00" and
270  rxFifoAxisMaster.tData(127 downto 96) = 0 and
271  rxFifoAxisMaster.tKeep = X"FFFF" and
272  rxFifoAxisMaster.tLast = '1' and
273  ssiGetUserSof(INTERNAL_AXIS_CFG_C, rxFifoAxisMaster) = '1')
274  then
275  v.sAxilReadSlave.rdata := rxFifoAxisMaster.tdata(95 downto 64);
276  axiSlaveReadResponse(v.sAxilReadSlave, AXI_RESP_OK_C);
277  v.state := WAIT_AXIL_REQ_S;
278  elsif (rxFifoAxisMaster.tLast = '0') then
279  v.sAxilReadSlave.rdata := (others => '1');
280  axiSlaveReadResponse(v.sAxilReadSlave, AXIL_ERR_RESP_G);
281  v.state := BLEED_S;
282  else
283  v.sAxilReadSlave.rdata := (others => '1');
284  axiSlaveReadResponse(v.sAxilReadSlave, AXIL_ERR_RESP_G);
285  v.state := WAIT_AXIL_REQ_S;
286  end if;
287  end if;
288 
289  -- Handle timeout
290  elsif (r.timeoutCount = TIMEOUT_COUNT_C) then
291  if (axilStatus.writeEnable = '1') then
292  axiSlaveWriteResponse(v.sAxilWriteSlave, AXIL_ERR_RESP_G);
293  else
294  v.sAxilReadSlave.rdata := (others => '1');
295  axiSlaveReadResponse(v.sAxilReadSlave, AXIL_ERR_RESP_G);
296  end if;
297  end if;
298 
299  when BLEED_S =>
300  v.rxFifoAxisSlave.tReady := '1';
301  if (rxFifoAxisMaster.tValid = '1' and rxFifoAxisMaster.tLast = '1') then
302  v.state := WAIT_AXIL_REQ_S;
303  end if;
304  end case;
305 
306 
307  if (axilRst = '1') then
308  v := REG_INIT_C;
309  end if;
310 
311  rin <= v;
312 
315  txFifoAxisMaster <= r.txFifoAxisMaster;
316  rxFifoAxisSlave <= v.rxFifoAxisSlave;
317 
318 
319  end process comb;
320 
321  seq : process (axilClk) is
322  begin
323  if (rising_edge(axilClk)) then
324  r <= rin after TPD_G;
325  end if;
326  end process seq;
327 
328 end rtl;
329 
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
out sAxisCtrlAxiStreamCtrlType
ALTERA_RAM_Gstring := "M9K"
AXI_STREAM_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
SLAVE_READY_EN_Gboolean := false
PIPE_STAGES_Gnatural range 0 to 16:= 1
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
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 sAxilReadMasterAxiLiteReadMasterType
in mAxisRstsl := '0'
AXIL_ERR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
out sAxilWriteSlaveAxiLiteWriteSlaveType
slv( 15 downto 0) tKeep
SLAVE_READY_EN_Gboolean := true
_library_ ieeeieee
Definition: SpiSlave.vhd:18
FIFO_FIXED_THRESH_Gboolean := true
ALTERA_SYN_Gboolean := false
GEN_SYNC_FIFO_Gboolean := false
out sAxisCtrlAxiStreamCtrlType
XIL_DEVICE_Gstring := "7SERIES"
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
in sAxilWriteMasterAxiLiteWriteMasterType
GEN_SYNC_FIFO_Gboolean := false
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
Definition: AxiLitePkg.vhd:36
slv( 127 downto 0) tData
in sAxisRstsl := '0'
out sAxilReadSlaveAxiLiteReadSlaveType
INT_PIPE_STAGES_Gnatural range 0 to 16:= 0
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
BRAM_EN_Gboolean := true
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
BRAM_EN_Gboolean := true
out mAxisMasterAxiStreamMasterType
TPD_Gtime := 1 ns
slv( 31 downto 0) awaddr
Definition: AxiLitePkg.vhd:113
TPD_Gtime := 1 ns
in mAxisSlaveAxiStreamSlaveType
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:95
in sAxisMasterAxiStreamMasterType
out sAxisSlaveAxiStreamSlaveType
ALTERA_SYN_Gboolean := false
FIFO_PAUSE_THRESH_Ginteger range 1 to ( 2** 24):= 2** 8
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
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
in sAxisMasterAxiStreamMasterType
out mAxisMasterAxiStreamMasterType
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
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
Definition: AxiLitePkg.vhd:156
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
RESP_THOLD_Ginteger range 0 to ( 2** 24):= 1
XIL_DEVICE_Gstring := "7SERIES"
ALTERA_RAM_Gstring := "M9K"
USE_BUILT_IN_Gboolean := false
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
out sAxisSlaveAxiStreamSlaveType