SURF  1.0
SsiFrameLimiter.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : SsiFrameLimiter.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2016-05-20
5 -- Last update: 2017-06-18
6 -------------------------------------------------------------------------------
7 -- Description: Limits the amount of data being sent across a SSI AXIS bus
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.AxiStreamPkg.all;
25 use work.SsiPkg.all;
26 
27 --! @see entity
28  --! @ingroup protocols_ssi
29 entity SsiFrameLimiter is
30  generic (
31  TPD_G : time := 1 ns;
32  EN_TIMEOUT_G : boolean := true;
33  MAXIS_CLK_FREQ_G : real := 156.25E+06; -- In units of Hz
34  TIMEOUT_G : real := 1.0E-3; -- In units of seconds
35  FRAME_LIMIT_G : positive := 1024; -- In units of MASTER_AXI_CONFIG_G.TDATA_BYTES_C
36  COMMON_CLK_G : boolean := false; -- True if sAxisClk and mAxisClk are the same clock
37  SLAVE_FIFO_G : boolean := false;
38  MASTER_FIFO_G : boolean := false;
39  SLAVE_READY_EN_G : boolean := true;
42  port (
43  -- Slave Port
44  sAxisClk : in sl;
45  sAxisRst : in sl;
48  -- Master Port
49  mAxisClk : in sl;
50  mAxisRst : in sl;
53 end SsiFrameLimiter;
54 
55 architecture rtl of SsiFrameLimiter is
56 
57  constant TIMEOUT_C : natural := getTimeRatio(MAXIS_CLK_FREQ_G * TIMEOUT_G, 1.0);
58 
59  type StateType is (
60  IDLE_S,
61  MOVE_S);
62 
63  type RegType is record
64  cnt : natural range 0 to FRAME_LIMIT_G-1;
65  timer : natural range 0 to TIMEOUT_C-1;
66  rxSlave : AxiStreamSlaveType;
67  txMaster : AxiStreamMasterType;
68  state : StateType;
69  end record RegType;
70  constant REG_INIT_C : RegType := (
71  cnt => 0,
72  timer => 0,
73  rxSlave => AXI_STREAM_SLAVE_INIT_C,
74  txMaster => AXI_STREAM_MASTER_INIT_C,
75  state => IDLE_S);
76 
77  signal r : RegType := REG_INIT_C;
78  signal rin : RegType;
79 
80  signal rxMaster : AxiStreamMasterType;
81  signal rxSlave : AxiStreamSlaveType;
82  signal txMaster : AxiStreamMasterType;
83  signal txSlave : AxiStreamSlaveType;
84 
85 begin
86 
87  BYPASS_FIFO_RX : if ((SLAVE_FIFO_G = false) and (COMMON_CLK_G = true) and (SLAVE_AXI_CONFIG_G = MASTER_AXI_CONFIG_G)) generate
88  rxMaster <= sAxisMaster;
89  sAxisSlave <= rxSlave;
90  end generate;
91 
92  GEN_FIFO_RX : if ((SLAVE_FIFO_G = true) or (COMMON_CLK_G = false) or (SLAVE_AXI_CONFIG_G /= MASTER_AXI_CONFIG_G)) generate
93  FIFO_RX : entity work.AxiStreamFifoV2
94  generic map (
95  -- General Configurations
96  TPD_G => TPD_G,
97  PIPE_STAGES_G => 0,
99  VALID_THOLD_G => 1,
100  -- FIFO configurations
101  BRAM_EN_G => false,
102  USE_BUILT_IN_G => false,
104  CASCADE_SIZE_G => 1,
105  FIFO_ADDR_WIDTH_G => 4,
106  -- AXI Stream Port Configurations
109  port map (
110  -- Slave Port
111  sAxisClk => sAxisClk,
112  sAxisRst => sAxisRst,
115  -- Master Port
116  mAxisClk => mAxisClk,
117  mAxisRst => mAxisRst,
118  mAxisMaster => rxMaster,
119  mAxisSlave => rxSlave);
120  end generate;
121 
122  comb : process (mAxisRst, r, rxMaster, txSlave) is
123  variable v : RegType;
124  variable i : natural;
125  begin
126  -- Latch the current value
127  v := r;
128 
129  -- Reset the flags
130  v.rxSlave := AXI_STREAM_SLAVE_INIT_C;
131  if (txSlave.tReady = '1') or (SLAVE_READY_EN_G = false) then
132  v.txMaster.tValid := '0';
133  end if;
134 
135  -- State Machine
136  case r.state is
137  ----------------------------------------------------------------------
138  when IDLE_S =>
139  -- Preset the counter
140  v.cnt := 1;
141  -- Check if ready to move data
142  if (v.txMaster.tValid = '0') and (rxMaster.tValid = '1') then
143  -- Accept the data
144  v.rxSlave.tReady := '1';
145  -- Check for SOF
146  if ssiGetUserSof(MASTER_AXI_CONFIG_G, rxMaster) = '1' then
147  -- Move the data
148  v.txMaster := rxMaster;
149  -- Check for non-EOF
150  if rxMaster.tLast = '0' then
151  -- Next state
152  v.state := MOVE_S;
153  end if;
154  end if;
155  end if;
156  ----------------------------------------------------------------------
157  when MOVE_S =>
158  -- Check if ready to move data
159  if (v.txMaster.tValid = '0') and (rxMaster.tValid = '1') then
160  -- Accept the data
161  v.rxSlave.tReady := '1';
162  -- Move the data
163  v.txMaster := rxMaster;
164  -- Check for EOF
165  if rxMaster.tLast = '1' then
166  -- Next state
167  v.state := IDLE_S;
168  -- Check if reach limiter value
169  elsif r.cnt = (FRAME_LIMIT_G-1) then
170  -- Set EOF and EOFE
171  v.txMaster.tLast := '1';
172  ssiSetUserEofe(MASTER_AXI_CONFIG_G, v.txMaster, '1');
173  -- Next state
174  v.state := IDLE_S;
175  else
176  -- Increment the counter
177  v.cnt := r.cnt + 1;
178  end if;
179  end if;
180  ----------------------------------------------------------------------
181  end case;
182 
183  -- Check if timeout is enabled
184  if EN_TIMEOUT_G then
185  -- Check if in (or going into) IDLE state
186  if (r.state = IDLE_S) or (v.state = IDLE_S) then
187  -- Reset the timer
188  v.timer := 0;
189  else
190  -- Check the timer
191  if (r.timer /= (TIMEOUT_C-1)) then
192  -- Increment the timer
193  v.timer := r.timer + 1;
194  else
195  -- Check ready to move data
196  if (v.txMaster.tValid = '0') then
197  -- Set EOF and EOFE
198  v.txMaster.tValid := '1';
199  v.txMaster.tLast := '1';
200  ssiSetUserEofe(MASTER_AXI_CONFIG_G, v.txMaster, '1');
201  -- Next state
202  v.state := IDLE_S;
203  end if;
204  end if;
205  end if;
206  end if;
207 
208  -- Check if using tReady
209  if (SLAVE_READY_EN_G = false) then
210  v.rxSlave.tReady := '1';
211  end if;
212 
213  -- Reset
214  if (mAxisRst = '1') then
215  v := REG_INIT_C;
216  end if;
217 
218  -- Register the variable for next clock cycle
219  rin <= v;
220 
221  -- Outputs
222  rxSlave <= v.rxSlave;
223  txMaster <= r.txMaster;
224 
225  end process comb;
226 
227  seq : process (mAxisClk) is
228  begin
229  if rising_edge(mAxisClk) then
230  r <= rin after TPD_G;
231  end if;
232  end process seq;
233 
234  BYPASS_FIFO_TX : if (MASTER_FIFO_G = false) generate
235  mAxisMaster <= txMaster;
236  txSlave <= mAxisSlave;
237  end generate;
238 
239  GEN_FIFO_TX : if (MASTER_FIFO_G = true) generate
240  FIFO_TX : entity work.AxiStreamFifoV2
241  generic map (
242  -- General Configurations
243  TPD_G => TPD_G,
244  PIPE_STAGES_G => 0,
246  VALID_THOLD_G => 1,
247  -- FIFO configurations
248  BRAM_EN_G => false,
249  USE_BUILT_IN_G => false,
250  GEN_SYNC_FIFO_G => true,
251  CASCADE_SIZE_G => 1,
252  FIFO_ADDR_WIDTH_G => 4,
253  -- AXI Stream Port Configurations
256  port map (
257  -- Slave Port
258  sAxisClk => mAxisClk,
259  sAxisRst => mAxisRst,
260  sAxisMaster => txMaster,
261  sAxisSlave => txSlave,
262  -- Master Port
263  mAxisClk => mAxisClk,
264  mAxisRst => mAxisRst,
267  end generate;
268 
269 end rtl;
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
FRAME_LIMIT_Gpositive := 1024
in mAxisSlaveAxiStreamSlaveType
SLAVE_FIFO_Gboolean := false
out mAxisMasterAxiStreamMasterType
PIPE_STAGES_Gnatural range 0 to 16:= 1
std_logic sl
Definition: StdRtlPkg.vhd:28
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
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
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
SLAVE_READY_EN_Gboolean := true
TPD_Gtime := 1 ns
COMMON_CLK_Gboolean := false
GEN_SYNC_FIFO_Gboolean := false
in sAxisMasterAxiStreamMasterType
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
SLAVE_READY_EN_Gboolean := true
BRAM_EN_Gboolean := true
TPD_Gtime := 1 ns
TIMEOUT_Greal := 1.0E-3
out sAxisSlaveAxiStreamSlaveType
out sAxisSlaveAxiStreamSlaveType
_library_ ieeeieee
Definition: SsiFifo.vhd:21
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 sAxisMasterAxiStreamMasterType
out mAxisMasterAxiStreamMasterType
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
in mAxisSlaveAxiStreamSlaveType
CASCADE_SIZE_Ginteger range 1 to ( 2** 24):= 1
USE_BUILT_IN_Gboolean := false
EN_TIMEOUT_Gboolean := true
VALID_THOLD_Ginteger range 0 to ( 2** 24):= 1
MAXIS_CLK_FREQ_Greal := 156.25E+06
MASTER_FIFO_Gboolean := false
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C