SURF  1.0
AxiStreamDmaRingWrite.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiStreamDmaRingWrite.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2015-09-29
5 -- Last update: 2017-02-20
6 -------------------------------------------------------------------------------
7 -- Description: AXI Stream to DMA Ring Buffer Write 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.AxiStreamPkg.all;
25 use work.SsiPkg.all;
26 use work.AxiLitePkg.all;
27 use work.AxiPkg.all;
28 use work.AxiDmaPkg.all;
29 use work.AxiStreamDmaRingPkg.all;
30 
31 --! @see entity
32  --! @ingroup axi
34  generic (
35  TPD_G : time := 1 ns;
36  BUFFERS_G : natural range 2 to 64 := 64;
37  BURST_SIZE_BYTES_G : natural range 4 to 2**17 := 4096;
38  ENABLE_UNALIGN_G : boolean := false;
39  TRIGGER_USER_BIT_G : natural range 0 to 7 := 2;
40  AXIL_BASE_ADDR_G : slv(31 downto 0) := (others => '0');
41  DATA_AXIS_CONFIG_G : AxiStreamConfigType := ssiAxiStreamConfig(8);
42  STATUS_AXIS_CONFIG_G : AxiStreamConfigType := ssiAxiStreamConfig(1);
43  AXI_WRITE_CONFIG_G : AxiConfigType := axiConfig(32, 8, 1, 8);
44  BYP_SHIFT_G : boolean := true; -- Bypass both because we do not want them to back-pressure
45  BYP_CACHE_G : boolean := true); -- Bypass both because we do not want them to back-pressure
46  port (
47  -- AXI-Lite Interface for local registers
48  axilClk : in sl;
49  axilRst : in sl;
54 
55  -- Status stream
60 
61  -- AXI (DDR) clock domain
62  axiClk : in sl;
63  axiRst : in sl;
64  -- Axi Stream data to be buffered
67  -- Low level buffer control
68  bufferClear : in slv(log2(BUFFERS_G)-1 downto 0) := (others => '0');
69  bufferClearEn : in sl := '0';
70  bufferEnabled : out slv(BUFFERS_G-1 downto 0);
71  bufferEmpty : out slv(BUFFERS_G-1 downto 0);
72  bufferFull : out slv(BUFFERS_G-1 downto 0);
73  bufferDone : out slv(BUFFERS_G-1 downto 0);
74  bufferTriggered : out slv(BUFFERS_G-1 downto 0);
75  bufferError : out slv(BUFFERS_G-1 downto 0);
76 
77  -- AXI4 Interface for RAM
80 
81 end entity AxiStreamDmaRingWrite;
82 
83 architecture rtl of AxiStreamDmaRingWrite is
84 
85  -- Ram contents represent AXI address shifted by 2
86  constant RAM_DATA_WIDTH_C : integer := AXI_WRITE_CONFIG_G.ADDR_WIDTH_C;
87  constant RAM_ADDR_WIDTH_C : integer := log2(BUFFERS_G);
88 
89  constant AXIL_RAM_ADDR_WIDTH_C : integer := RAM_ADDR_WIDTH_C + log2((RAM_DATA_WIDTH_C-1)/4);
90 
91  constant DMA_ADDR_LOW_C : integer := log2(BURST_SIZE_BYTES_G);
92 
93  -- Create burst size constant for status
94  -- 0 = burst size 4
95  -- 1 = burst size 8
96  -- 15 = burst size 131072
97  constant BURST_SIZE_SLV_C : slv(3 downto 0) := toSlv(DMA_ADDR_LOW_C-2, 4);
98 
99  function statusRamInit
100  return slv is
101  variable ret : slv(31 downto 0) := (others => '0');
102  begin
103  ret(EMPTY_C) := '1';
104  ret(FULL_C) := '0';
105  ret(DONE_C) := '1';
106  ret(TRIGGERED_C) := '0';
107  ret(ERROR_C) := '0';
108  ret(BURST_SIZE_C) := BURST_SIZE_SLV_C;
109  ret(FST_C) := (others => '0');
110  return ret;
111  end function statusRamInit;
112 
113  constant STATUS_RAM_INIT_C : slv(31 downto 0) := statusRamInit;
114 
115  constant AXIL_CONFIG_C : AxiLiteCrossbarMasterConfigArray := (
116  START_AXIL_C => (
117  baseAddr => getBufferAddr(AXIL_BASE_ADDR_G, START_AXIL_C, 0),
118  addrBits => AXIL_RAM_ADDR_WIDTH_C,
119  connectivity => X"FFFF"),
120  END_AXIL_C => (
121  baseAddr => getBufferAddr(AXIL_BASE_ADDR_G, END_AXIL_C, 0),
122  addrBits => AXIL_RAM_ADDR_WIDTH_C,
123  connectivity => X"FFFF"),
124  NEXT_AXIL_C => (
125  baseAddr => getBufferAddr(AXIL_BASE_ADDR_G, NEXT_AXIL_C, 0),
126  addrBits => AXIL_RAM_ADDR_WIDTH_C,
127  connectivity => X"FFFF"),
128  TRIG_AXIL_C => (
129  baseAddr => getBufferAddr(AXIL_BASE_ADDR_G, TRIG_AXIL_C, 0),
130  addrBits => AXIL_RAM_ADDR_WIDTH_C,
131  connectivity => X"FFFF"),
132  MODE_AXIL_C => (
133  baseAddr => getBufferAddr(AXIL_BASE_ADDR_G, MODE_AXIL_C, 0),
134  addrBits => RAM_ADDR_WIDTH_C+2,
135  connectivity => X"FFFF"),
136  STATUS_AXIL_C => (
137  baseAddr => getBufferAddr(AXIL_BASE_ADDR_G, STATUS_AXIL_C, 0),
138  addrBits => RAM_ADDR_WIDTH_C+2,
139  connectivity => X"FFFF"));
140 
141 
142  signal locAxilWriteMasters : AxiLiteWriteMasterArray(AXIL_MASTERS_C-1 downto 0);
143  signal locAxilWriteSlaves : AxiLiteWriteSlaveArray(AXIL_MASTERS_C-1 downto 0);
144  signal locAxilReadMasters : AxiLiteReadMasterArray(AXIL_MASTERS_C-1 downto 0);
145  signal locAxilReadSlaves : AxiLiteReadSlaveArray(AXIL_MASTERS_C-1 downto 0);
146 
147  constant INT_STATUS_AXIS_CONFIG_C : AxiStreamConfigType :=
148  ssiAxiStreamConfig(1, TKEEP_FIXED_C, TUSER_FIRST_LAST_C, 4);
149 -- (
150 -- TSTRB_EN_C => false,
151 -- TDATA_BYTES_C => 1,
152 -- TDEST_BITS_C => 4,
153 -- TID_BITS_C => 0,
154 -- TKEEP_MODE_C => TKEEP_FIXED_C, --ite(BSA_STREAM_BYTE_WIDTH_G = 4, TKEEP_FIXED_C, TKEEP_COMP_C),
155 -- TUSER_BITS_C => 2,
156 -- TUSER_MODE_C => TUSER_NONE_C);
157 
158  type StateType is (WAIT_TVALID_S, ASSERT_ADDR_S, LATCH_POINTERS_S, WAIT_DMA_DONE_S);
159 
160  type RegType is record
161  wrRamAddr : slv(RAM_ADDR_WIDTH_C-1 downto 0);
162  rdRamAddr : slv(RAM_ADDR_WIDTH_C-1 downto 0);
163  activeBuffer : slv(RAM_ADDR_WIDTH_C-1 downto 0);
164  initBufferEn : sl;
165  ramWe : sl;
166  nextAddr : slv(RAM_DATA_WIDTH_C-1 downto 0);
167  startAddr : slv(RAM_DATA_WIDTH_C-1 downto 0);
168  endAddr : slv(RAM_DATA_WIDTH_C-1 downto 0);
169  trigAddr : slv(RAM_DATA_WIDTH_C-1 downto 0);
170  mode : slv(31 downto 0);
171  status : slv(31 downto 0);
172  state : StateType;
173  dmaReq : AxiWriteDmaReqType;
174  trigger : sl;
175  softTrigger : slv(BUFFERS_G-1 downto 0);
176  eofe : sl;
177  bufferEnabled : slv(BUFFERS_G-1 downto 0);
178  bufferEmpty : slv(BUFFERS_G-1 downto 0);
179  bufferFull : slv(BUFFERS_G-1 downto 0);
180  bufferDone : slv(BUFFERS_G-1 downto 0);
181  bufferTriggered : slv(BUFFERS_G-1 downto 0);
182  bufferError : slv(BUFFERS_G-1 downto 0);
184  end record RegType;
185 
186  constant REG_INIT_C : RegType := (
187  wrRamAddr => (others => '0'),
188  rdRamAddr => (others => '0'),
189  activeBuffer => (others => '0'),
190  initBufferEn => '0',
191  ramWe => '0',
192  nextAddr => (others => '0'),
193  startAddr => (others => '0'),
194  endAddr => (others => '0'),
195  trigAddr => (others => '0'),
196  mode => (others => '0'),
197  status => (others => '0'),
198  state => WAIT_TVALID_S,
199  dmaReq => (
200  request => '0',
201  drop => '0',
202  address => (others => '0'),
203  maxSize => toSlv(BURST_SIZE_BYTES_G, 32)),
204  trigger => '0',
205  softTrigger => (others => '0'),
206  eofe => '0',
207  bufferEnabled => (others => '0'),
208  bufferEmpty => (others => '1'),
209  bufferFull => (others => '0'),
210  bufferDone => (others => '1'),
211  bufferTriggered => (others => '0'),
212  bufferError => (others => '0'),
213  axisStatusMaster => axiStreamMasterInit(INT_STATUS_AXIS_CONFIG_C));
214 
215  signal r : RegType := REG_INIT_C;
216  signal rin : RegType;
217 
218  signal dmaAck : AxiWriteDmaAckType;
219  signal startRamDout : slv(RAM_DATA_WIDTH_C-1 downto 0);
220  signal endRamDout : slv(RAM_DATA_WIDTH_C-1 downto 0);
221  signal nextRamDout : slv(RAM_DATA_WIDTH_C-1 downto 0);
222  signal trigRamDout : slv(RAM_DATA_WIDTH_C-1 downto 0);
223  signal modeRamDout : slv(31 downto 0);
224  signal statusRamDout : slv(31 downto 0);
225 
226  signal modeWrValid : sl;
227  signal modeWrStrobe : slv(3 downto 0);
228  signal modeWrAddr : slv(RAM_ADDR_WIDTH_C-1 downto 0);
229  signal modeWrData : slv(31 downto 0);
230 
231 begin
232  -- Assert that stream config has enough tdest bits for the number of buffers being tracked
233  -- Assert that BURST_SIZE_BYTES_G is a power of 2
234 
235  -- Crossbar
236  U_AxiLiteCrossbar_1 : entity work.AxiLiteCrossbar
237  generic map (
238  TPD_G => TPD_G,
239  NUM_SLAVE_SLOTS_G => 1,
242  MASTERS_CONFIG_G => AXIL_CONFIG_C,
243  DEBUG_G => true)
244  port map (
245  axiClk => axilClk, -- [in]
246  axiClkRst => axilRst, -- [in]
247  sAxiWriteMasters(0) => axilWriteMaster, -- [in]
248  sAxiWriteSlaves(0) => axilWriteSlave, -- [out]
249  sAxiReadMasters(0) => axilReadMaster, -- [in]
250  sAxiReadSlaves(0) => axilReadSlave, -- [out]
251  mAxiWriteMasters => locAxilWriteMasters, -- [out]
252  mAxiWriteSlaves => locAxilWriteSlaves, -- [in]
253  mAxiReadMasters => locAxilReadMasters, -- [out]
254  mAxiReadSlaves => locAxilReadSlaves); -- [in]
255 
256  -------------------------------------------------------------------------------------------------
257  -- AXI RAMs store buffer information
258  -------------------------------------------------------------------------------------------------
259  -- Start Addresses. AXIL writeable
260  U_AxiDualPortRam_Start : entity work.AxiDualPortRam
261  generic map (
262  TPD_G => TPD_G,
263  BRAM_EN_G => false,
264  REG_EN_G => false,
265  AXI_WR_EN_G => true,
266  SYS_WR_EN_G => false,
267  ADDR_WIDTH_G => RAM_ADDR_WIDTH_C,
268  DATA_WIDTH_G => RAM_DATA_WIDTH_C)
269  port map (
270  axiClk => axilClk,
271  axiRst => axilRst,
272  axiReadMaster => locAxilReadMasters(START_AXIL_C),
273  axiReadSlave => locAxilReadSlaves(START_AXIL_C),
274  axiWriteMaster => locAxilWriteMasters(START_AXIL_C),
275  axiWriteSlave => locAxilWriteSlaves(START_AXIL_C),
276  clk => axiClk,
277  rst => axiRst,
278  addr => r.rdRamAddr,
279  dout => startRamDout);
280 
281  -- End Addresses. AXIL writeable
282  U_AxiDualPortRam_End : entity work.AxiDualPortRam
283  generic map (
284  TPD_G => TPD_G,
285  BRAM_EN_G => false,
286  REG_EN_G => false,
287  AXI_WR_EN_G => true,
288  SYS_WR_EN_G => false,
289  ADDR_WIDTH_G => RAM_ADDR_WIDTH_C,
290  DATA_WIDTH_G => RAM_DATA_WIDTH_C)
291  port map (
292  axiClk => axilClk,
293  axiRst => axilRst,
294  axiReadMaster => locAxilReadMasters(END_AXIL_C),
295  axiReadSlave => locAxilReadSlaves(END_AXIL_C),
296  axiWriteMaster => locAxilWriteMasters(END_AXIL_C),
297  axiWriteSlave => locAxilWriteSlaves(END_AXIL_C),
298  clk => axiClk,
299  rst => axiRst,
300  addr => r.rdRamAddr,
301  dout => endRamDout);
302 
303 
304  -- Next Addresses. System writeable
305  U_AxiDualPortRam_Next : entity work.AxiDualPortRam
306  generic map (
307  TPD_G => TPD_G,
308  BRAM_EN_G => false,
309  REG_EN_G => false,
310  AXI_WR_EN_G => false,
311  SYS_WR_EN_G => true,
312  ADDR_WIDTH_G => RAM_ADDR_WIDTH_C,
313  DATA_WIDTH_G => RAM_DATA_WIDTH_C)
314  port map (
315  axiClk => axilClk,
316  axiRst => axilRst,
317  axiReadMaster => locAxilReadMasters(NEXT_AXIL_C),
318  axiReadSlave => locAxilReadSlaves(NEXT_AXIL_C),
319  axiWriteMaster => locAxilWriteMasters(NEXT_AXIL_C),
320  axiWriteSlave => locAxilWriteSlaves(NEXT_AXIL_C),
321  clk => axiClk,
322  rst => axiRst,
323  we => r.ramWe,
324  addr => r.wrRamAddr,
325  din => r.nextAddr,
326  dout => nextRamDout);
327 
328  U_AxiDualPortRam_Trigger : entity work.AxiDualPortRam
329  generic map (
330  TPD_G => TPD_G,
331  BRAM_EN_G => false,
332  REG_EN_G => false,
333  AXI_WR_EN_G => false,
334  SYS_WR_EN_G => true,
335  ADDR_WIDTH_G => RAM_ADDR_WIDTH_C,
336  DATA_WIDTH_G => RAM_DATA_WIDTH_C)
337  port map (
338  axiClk => axilClk,
339  axiRst => axilRst,
340  axiReadMaster => locAxilReadMasters(TRIG_AXIL_C),
341  axiReadSlave => locAxilReadSlaves(TRIG_AXIL_C),
342  axiWriteMaster => locAxilWriteMasters(TRIG_AXIL_C),
343  axiWriteSlave => locAxilWriteSlaves(TRIG_AXIL_C),
344  clk => axiClk,
345  rst => axiRst,
346  we => r.ramWe,
347  addr => r.wrRamAddr,
348  din => r.trigAddr,
349  dout => trigRamDout);
350 
351 
352  U_AxiDualPortRam_Mode : entity work.AxiDualPortRam
353  generic map (
354  TPD_G => TPD_G,
355  BRAM_EN_G => false,
356  REG_EN_G => false,
357  AXI_WR_EN_G => true,
358  SYS_WR_EN_G => false,
359  COMMON_CLK_G => false,
360  ADDR_WIDTH_G => RAM_ADDR_WIDTH_C,
361  DATA_WIDTH_G => 32)
362  port map (
363  axiClk => axilClk,
364  axiRst => axilRst,
365  axiReadMaster => locAxilReadMasters(MODE_AXIL_C),
366  axiReadSlave => locAxilReadSlaves(MODE_AXIL_C),
367  axiWriteMaster => locAxilWriteMasters(MODE_AXIL_C),
368  axiWriteSlave => locAxilWriteSlaves(MODE_AXIL_C),
369  clk => axiClk,
370  rst => axiRst,
371  addr => r.rdRamAddr,
372  dout => modeRamDout,
373  axiWrValid => modeWrValid,
374  axiWrStrobe => modeWrStrobe,
375  axiWrAddr => modeWrAddr,
376  axiWrData => modeWrData);
377 
378  U_AxiDualPortRam_Status : entity work.AxiDualPortRam
379  generic map (
380  TPD_G => TPD_G,
381  BRAM_EN_G => false,
382  REG_EN_G => false,
383  AXI_WR_EN_G => false,
384  SYS_WR_EN_G => true,
385  ADDR_WIDTH_G => RAM_ADDR_WIDTH_C,
386  DATA_WIDTH_G => 32,
387  INIT_G => STATUS_RAM_INIT_C)
388  port map (
389  axiClk => axilClk,
390  axiRst => axilRst,
391  axiReadMaster => locAxilReadMasters(STATUS_AXIL_C),
392  axiReadSlave => locAxilReadSlaves(STATUS_AXIL_C),
393  axiWriteMaster => locAxilWriteMasters(STATUS_AXIL_C),
394  axiWriteSlave => locAxilWriteSlaves(STATUS_AXIL_C),
395  clk => axiClk,
396  rst => axiRst,
397  we => r.ramWe,
398  addr => r.wrRamAddr,
399  din => r.status,
400  dout => statusRamDout);
401 
402  -- DMA Write block
403  U_AxiStreamDmaWrite_1 : entity work.AxiStreamDmaWrite
404  generic map (
405  TPD_G => TPD_G,
406  AXI_READY_EN_G => true,
409  AXI_BURST_G => "01", -- INCR
410  AXI_CACHE_G => "0011", -- Cacheable
411  ACK_WAIT_BVALID_G => false,
412  BYP_SHIFT_G => BYP_SHIFT_G, -- Bypass both because we do not want them to back-pressure
413  BYP_CACHE_G => BYP_CACHE_G) -- Bypass both because we do not want them to back-pressure
414  port map (
415  axiClk => axiClk, -- [in]
416  axiRst => axiRst, -- [in]
417  dmaReq => r.dmaReq, -- [in]
418  dmaAck => dmaAck, -- [out]
419  axisMaster => axisDataMaster, -- [in]
420  axisSlave => axisDataSlave, -- [out]
421  axiWriteMaster => axiWriteMaster, -- [out]
422  axiWriteSlave => axiWriteSlave); -- [in]
423 
424  -- Pass status message through a small fifo to convert to statusClk
425  -- And convert width
426  U_AxiStreamFifo_MSG : entity work.AxiStreamFifoV2
427  generic map (
428  TPD_G => TPD_G,
429  PIPE_STAGES_G => 1,
430  SLAVE_READY_EN_G => false,
431  VALID_THOLD_G => 1,
432  BRAM_EN_G => false,
433  USE_BUILT_IN_G => false,
434  GEN_SYNC_FIFO_G => false,
435  FIFO_ADDR_WIDTH_G => 4,
436  FIFO_FIXED_THRESH_G => true,
437  FIFO_PAUSE_THRESH_G => 15,
438  SLAVE_AXI_CONFIG_G => INT_STATUS_AXIS_CONFIG_C,
440  port map (
441  sAxisClk => axiClk, -- [in]
442  sAxisRst => axiRst, -- [in]
443  sAxisMaster => r.axisStatusMaster, -- [in]
444  sAxisSlave => open, -- [out]
445  mAxisClk => axisStatusClk, -- [in]
446  mAxisRst => axisStatusRst, -- [in]
447  mAxisMaster => axisStatusMaster, -- [out]
448  mAxisSlave => axisStatusSlave); -- [in]
449 
450  -------------------------------------------------------------------------------------------------
451  -- Main logic
452  -------------------------------------------------------------------------------------------------
453  comb : process (axiRst, axisDataMaster, bufferClear, bufferClearEn, dmaAck, endRamDout,
454  modeRamDout, modeWrAddr, modeWrData, modeWrStrobe, modeWrValid, nextRamDout, r,
455  startRamDout, statusRamDout, trigRamDout) is
456  variable v : RegType;
457  variable axilEndpoint : AxiLiteEndpointType;
458  begin
459  v := r;
460 
461  -- These registers default to zero
462  v.ramWe := '0';
463  v.initBufferEn := '0';
464  v.axisStatusMaster.tValid := '0';
465 
466  -- If last txn of frame, check for trigger condition and EOFE and latch them in registers.
467  if (axisDataMaster.tValid = '1' and axisDataMaster.tLast = '1') then
468  if(axiStreamGetUserBit(DATA_AXIS_CONFIG_G, axisDataMaster, TRIGGER_USER_BIT_G) = '1') then
469  v.trigger := '1';
470  end if;
471  if (axiStreamGetUserBit(DATA_AXIS_CONFIG_G, axisDataMaster, SSI_EOFE_C) = '1') then
472  v.eofe := '1';
473  end if;
474  end if;
475 
476  -- Check for software trigger.
477  if (modeWrValid = '1' and modeWrStrobe(SOFT_TRIGGER_C/8) = '1' and modeWrData(SOFT_TRIGGER_C) = '1') then
478  v.softTrigger := r.softTrigger or decode(modeWrAddr);
479  end if;
480 
481  -- Override state machine if a buffer clear is being requested
482  -- This could occur through the ports (bufferClearEn+bufferClear)
483  -- Or through the mode registers
484  if (bufferClearEn = '1') then
485  v.initBufferEn := '1';
486  v.rdRamAddr := bufferClear;
487  v.state := ASSERT_ADDR_S;
488  elsif(modeWrValid = '1' and modeWrData(INIT_C) = '1' and modeWrStrobe(INIT_C/8) = '1') then
489  v.initBufferEn := '1';
490  v.rdRamAddr := modeWrAddr;
491  v.state := ASSERT_ADDR_S;
492  end if;
493 
494  -- Set status and pointers back to init state and write the values to the local ram registers
495  if (r.initBufferEn = '1') then
496  v.status(DONE_C) := '0';
497  v.status(FULL_C) := '0';
498  v.status(EMPTY_C) := '1';
499  v.status(TRIGGERED_C) := '0';
500  v.status(ERROR_C) := '0';
501  v.status(FST_C) := (others => '0');
502  v.wrRamAddr := r.rdRamAddr;
503  v.nextAddr := startRamDout;
504  v.trigAddr := (others => '1');
505  v.ramWe := '1';
506  end if;
507 
508 
509  case (r.state) is
510  when WAIT_TVALID_S =>
511  -- Only final burst before readout can be short, so no need to worry about next
512  -- burst wrapping awkwardly. Whole thing will be reset after readout.
513  -- Don't do anything if in the middle of a buffer address clear
514  if (axisDataMaster.tvalid = '1' and v.initBufferEn = '0' and dmaAck.done = '0') then
515  v.activeBuffer := axisDataMaster.tdest(RAM_ADDR_WIDTH_C-1 downto 0);
516  v.state := ASSERT_ADDR_S;
517  elsif (v.initBufferEn = '1') then
518  -- Stay in this state if bufferes need to be cleared
519  v.state := WAIT_TVALID_S;
520  end if;
521 
522  when ASSERT_ADDR_S =>
523  -- State holds here as long buffers are being initialized
524  if (v.initBufferEn = '0' and r.initBufferEn = '0') then
525  v.rdRamAddr := r.activeBuffer;
526  v.wrRamAddr := r.activeBuffer;
527  v.state := LATCH_POINTERS_S;
528  end if;
529 
530  when LATCH_POINTERS_S =>
531  -- Latch pointers
532  -- Might go back to ASSERT_ADDR_S if bufferClearEn is high
533  -- But everything this state asserts is still valid
534  v.startAddr := startRamDout; -- Address of start of buffer
535  v.endAddr := endRamDout; -- Address of end of buffer
536  v.nextAddr := nextRamDout; -- Address of next frame in buffer
537  v.trigAddr := trigRamDout; -- Start address of frame where trigger was seen
538  v.mode := modeRamDout; -- Number of frames since trigger seen
539  v.status := statusRamDout; -- Number of frames to log after trigger seen
540 
541  -- Assert a new request.
542  -- Direct that frame be dropped if buffer is done with trigger sequence
543  -- Writes always start on a BURST_SIZE_BYTES_G boundary, so can drive low dmaReq.address
544  -- bits to zero for optimization.
545  v.dmaReq.address(AXI_WRITE_CONFIG_G.ADDR_WIDTH_C-1 downto 0) := nextRamDout;
546  if not ENABLE_UNALIGN_G then
547  v.dmaReq.address(DMA_ADDR_LOW_C-1 downto 0) := (others => '0');
548  v.dmaReq.drop := v.status(DONE_C);
549  else
550  -- status(DONE_C) indicates a push, but maybe more than one
551  v.dmaReq.drop := '0';
552  end if;
553  v.dmaReq.request := '1';
554  v.state := WAIT_DMA_DONE_S;
555 
556  when WAIT_DMA_DONE_S =>
557  -- Wait until DMA transaction is done.
558  -- Must also check that buffer not being cleared so as not to step on the addresses
559  if (dmaAck.done = '1' and v.initBufferEn = '0') then
560 
561  v.dmaReq.request := '0'; -- Deassert dma request
562  v.status(EMPTY_C) := '0'; -- Update empty status
563  v.ramWe := '1'; -- write new values into register ram
564 
565  -- Increment address of last burst in buffer.
566  -- Wrap back to start when it hits the end of the buffer.
567  v.nextAddr := r.nextAddr + dmaAck.size; --(BURST_SIZE_BYTES_G); --
568  if (v.nextAddr = r.endAddr) then
569  v.status(FULL_C) := '1';
570  if (r.mode(DONE_WHEN_FULL_C) = '1') then
571  v.status(DONE_C) := '1';
572  end if;
573  v.nextAddr := r.startAddr;
574  end if;
575 
576  -- Record trigger position if a trigger was seen on current frame
577  v.trigger := '0';
578  v.softTrigger(conv_integer(r.activeBuffer)) := '0';
579  if ((r.trigger = '1' or r.softTrigger(conv_integer(r.activeBuffer)) = '1') and r.status(TRIGGERED_C) = '0') then
580  v.trigAddr := r.nextAddr;
581  v.status(TRIGGERED_C) := '1';
582  end if;
583 
584  -- Check for EOFE
585  v.eofe := '0';
586  if (r.eofe = '1') then
587  v.status(ERROR_C) := '1';
588  v.status(DONE_C) := '1';
589  end if;
590 
591 
592  -- Increment FramesSinceTrigger when necessary
593  if (v.status(TRIGGERED_C) = '1' and r.status(DONE_C) = '0') then
594  v.status(FST_C) := r.status(FST_C) + 1;
595  if (r.mode(FAT_C) = r.status(FST_C) and r.mode(DONE_WHEN_FULL_C) = '0') then
596  v.status(DONE_C) := '1';
597  v.status(FST_C) := r.status(FST_C);
598  end if;
599  end if;
600 
601  -- Output status message when done
602  if (v.status(DONE_C) = '1' and r.dmaReq.drop = '0') then
603  v.axisStatusMaster.tValid := '1';
604  v.axisStatusMaster.tLast := '1';
605  v.axisStatusMaster.tData(7 downto 0) := resize(r.rdRamAddr, 8);
606  v.axisStatusMaster.tDest(3 downto 0) := r.mode(STATUS_TDEST_C);
607  ssiSetUserSof(INT_STATUS_AXIS_CONFIG_C, v.axisStatusMaster, '1');
608  end if;
609 
610  v.state := WAIT_TVALID_S;
611 
612  end if;
613 
614  end case;
615 
616  -- Assign status outputs
617  if (r.ramWe = '1') then
618  v.bufferEmpty(conv_integer(r.wrRamAddr)) := r.status(EMPTY_C);
619  v.bufferFull(conv_integer(r.wrRamAddr)) := r.status(FULL_C);
620  v.bufferDone(conv_integer(r.wrRamAddr)) := r.status(DONE_C);
621  v.bufferTriggered(conv_integer(r.wrRamAddr)) := r.status(TRIGGERED_C);
622  v.bufferError(conv_integer(r.wrRamAddr)) := r.status(ERROR_C);
623  end if;
624 
625  if(modeWrValid = '1' and modeWrStrobe(ENABLED_C/8) = '1') then
626  v.bufferEnabled(conv_integer(modeWrAddr)) := modeWrData(ENABLED_C);
627  end if;
628 
629 
630  ----------------------------------------------------------------------------------------------
631  -- Reset and output assignment
632  ----------------------------------------------------------------------------------------------
633  if (axiRst = '1') then
634  v := REG_INIT_C;
635  end if;
636 
637  rin <= v;
640  bufferFull <= r.bufferFull;
641  bufferDone <= r.bufferDone;
644 
645  end process comb;
646 
647  seq : process (axiClk) is
648  begin
649  if (rising_edge(axiClk)) then
650  r <= rin after TPD_G;
651  end if;
652  end process seq;
653 
654 end architecture rtl;
655 
BYP_SHIFT_Gboolean := false
in dmaReqAxiWriteDmaReqType
AXI_WRITE_CONFIG_GAxiConfigType := axiConfig( 32, 8, 1, 8)
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
out dmaAckAxiWriteDmaAckType
slv( 63 downto 0) address
Definition: AxiDmaPkg.vhd:49
in mAxiWriteSlavesAxiLiteWriteSlaveArray( NUM_MASTER_SLOTS_G- 1 downto 0)
slv( 15 downto 0) connectivity
Definition: AxiLitePkg.vhd:199
out axiWrAddrslv( ADDR_WIDTH_G- 1 downto 0)
in addrslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
out axiWriteMasterAxiWriteMasterType
array(natural range <> ) of AxiLiteWriteSlaveType AxiLiteWriteSlaveArray
Definition: AxiLitePkg.vhd:164
out axisDataSlaveAxiStreamSlaveType
in mAxiReadSlavesAxiLiteReadSlaveArray( NUM_MASTER_SLOTS_G- 1 downto 0)
PIPE_STAGES_Gnatural range 0 to 16:= 1
TPD_Gtime := 1 ns
out axilReadSlaveAxiLiteReadSlaveType
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
NUM_SLAVE_SLOTS_Gnatural range 1 to 16:= 4
integer := 0 SSI_EOFE_C
Definition: SsiPkg.vhd:30
sl eofe
Definition: SsiPkg.vhd:74
out bufferEnabledslv( BUFFERS_G- 1 downto 0)
ACK_WAIT_BVALID_Gboolean := true
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
TPD_Gtime := 1 ns
out doutslv( DATA_WIDTH_G- 1 downto 0)
integer range 31 downto 16 FST_C
DATA_AXIS_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 8)
BURST_SIZE_BYTES_Gnatural range 4 to 2** 17:= 4096
array(natural range <> ) of AxiLiteReadMasterType AxiLiteReadMasterArray
Definition: AxiLitePkg.vhd:77
DATA_WIDTH_Ginteger := 32
SLAVE_READY_EN_Gboolean := true
FIFO_FIXED_THRESH_Gboolean := true
BUFFERS_Gnatural range 2 to 64:= 64
in axilWriteMasterAxiLiteWriteMasterType
out axiWriteMasterAxiWriteMasterType
DEBUG_Gboolean := false
slv( 31 downto 0) baseAddr
Definition: AxiLitePkg.vhd:197
GEN_SYNC_FIFO_Gboolean := false
INIT_Gslv := "0"
in bufferClearslv( log2(BUFFERS_G )- 1 downto 0) :=( others => '0')
AxiWriteDmaAckType
Definition: AxiDmaPkg.vhd:69
positive range 12 to 64 ADDR_WIDTH_C
Definition: AxiPkg.vhd:214
AxiWriteMasterType
Definition: AxiPkg.vhd:108
array(natural range <> ) of AxiLiteCrossbarMasterConfigType AxiLiteCrossbarMasterConfigArray
Definition: AxiLitePkg.vhd:202
MASTERS_CONFIG_GAxiLiteCrossbarMasterConfigArray := AXIL_XBAR_CFG_DEFAULT_C
TRIGGER_USER_BIT_Gnatural range 0 to 7:= 2
slv( 127 downto 0) tData
DEC_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_DECERR_C
out axiReadSlaveAxiLiteReadSlaveType
slv( 1 downto 0) := "11" AXI_RESP_DECERR_C
Definition: AxiLitePkg.vhd:49
in clksl := '0'
in axiWriteMasterAxiLiteWriteMasterType
natural addrBits
Definition: AxiLitePkg.vhd:198
COMMON_CLK_Gboolean := false
STATUS_AXIS_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 1)
BYP_CACHE_Gboolean := false
in axisStatusSlaveAxiStreamSlaveType := AXI_STREAM_SLAVE_FORCE_C
AXI_CACHE_Gslv( 3 downto 0) := "1111"
SYS_WR_EN_Gboolean := false
out bufferTriggeredslv( BUFFERS_G- 1 downto 0)
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
BRAM_EN_Gboolean := true
AxiWriteDmaReqType
Definition: AxiDmaPkg.vhd:46
out mAxiReadMastersAxiLiteReadMasterArray( NUM_MASTER_SLOTS_G- 1 downto 0)
out axiWrDataslv( DATA_WIDTH_G- 1 downto 0)
AxiConfigType
Definition: AxiPkg.vhd:213
out axilWriteSlaveAxiLiteWriteSlaveType
TPD_Gtime := 1 ns
in axiWriteSlaveAxiWriteSlaveType
AxiWriteSlaveType
Definition: AxiPkg.vhd:171
AXI_BURST_Gslv( 1 downto 0) := "01"
NUM_MASTER_SLOTS_Gnatural range 1 to 64:= 4
out sAxisSlaveAxiStreamSlaveType
in axiWriteSlaveAxiWriteSlaveType
in axisMasterAxiStreamMasterType
out bufferEmptyslv( BUFFERS_G- 1 downto 0)
integer range 11 downto 8 BURST_SIZE_C
slv( 7 downto 0) tDest
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
in wesl := '0'
array(natural range <> ) of AxiLiteWriteMasterType AxiLiteWriteMasterArray
Definition: AxiLitePkg.vhd:136
in rstsl := '0'
slv( 31 downto 0) size
Definition: AxiDmaPkg.vhd:72
in axiReadMasterAxiLiteReadMasterType
out axisStatusMasterAxiStreamMasterType
slv( 31 downto 0) maxSize
Definition: AxiDmaPkg.vhd:50
in sAxisMasterAxiStreamMasterType
out axiWriteSlaveAxiLiteWriteSlaveType
in dinslv( DATA_WIDTH_G- 1 downto 0) :=( others => '0')
out mAxisMasterAxiStreamMasterType
out bufferFullslv( BUFFERS_G- 1 downto 0)
BRAM_EN_Gboolean := false
AxiStreamSlaveType :=(tReady => '1') AXI_STREAM_SLAVE_FORCE_C
out bufferErrorslv( BUFFERS_G- 1 downto 0)
integer range 31 downto 16 FAT_C
AXIS_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
array(natural range <> ) of AxiLiteReadSlaveType AxiLiteReadSlaveArray
Definition: AxiLitePkg.vhd:103
AXIL_BASE_ADDR_Gslv( 31 downto 0) :=( others => '0')
ENABLE_UNALIGN_Gboolean := false
in mAxisSlaveAxiStreamSlaveType
out mAxiWriteMastersAxiLiteWriteMasterArray( NUM_MASTER_SLOTS_G- 1 downto 0)
USE_BUILT_IN_Gboolean := false
integer range 7 downto 4 STATUS_TDEST_C
sl request
Definition: AxiDmaPkg.vhd:47
ADDR_WIDTH_Ginteger range 1 to ( 2** 24):= 5
FIFO_PAUSE_THRESH_Ginteger range 1 to ( 2** 24):= 1
VALID_THOLD_Ginteger range 0 to ( 2** 24):= 1
in axilReadMasterAxiLiteReadMasterType
REG_EN_Gboolean := true
in axisDataMasterAxiStreamMasterType
out axiWrStrobeslv( wordCount( DATA_WIDTH_G, 8)- 1 downto 0)
AXI_CONFIG_GAxiConfigType := AXI_CONFIG_INIT_C
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
AXI_WR_EN_Gboolean := true
out axisSlaveAxiStreamSlaveType
AXI_READY_EN_Gboolean := false
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
out bufferDoneslv( BUFFERS_G- 1 downto 0)