SURF  1.0
AxiStreamDmaV2Write.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiStreamDmaV2Write.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2017-02-02
5 -- Last update: 2017-02-02
6 -------------------------------------------------------------------------------
7 -- Description:
8 -- Block to transfer a single AXI Stream frame into memory using an AXI
9 -- interface. Version 2 supports interleaved frames.
10 -------------------------------------------------------------------------------
11 -- This file is part of 'SLAC Firmware Standard Library'.
12 -- It is subject to the license terms in the LICENSE.txt file found in the
13 -- top-level directory of this distribution and at:
14 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
15 -- No part of 'SLAC Firmware Standard Library', including this file,
16 -- may be copied, modified, propagated, or distributed except according to
17 -- the terms contained in the LICENSE.txt file.
18 -------------------------------------------------------------------------------
19 
20 library ieee;
21 use ieee.std_logic_1164.all;
22 use ieee.std_logic_arith.all;
23 use ieee.std_logic_unsigned.all;
24 
25 use work.StdRtlPkg.all;
26 use work.AxiStreamPkg.all;
27 use work.AxiPkg.all;
28 use work.AxiDmaPkg.all;
29 
30 --! @see entity
31  --! @ingroup axi
33  generic (
34  TPD_G : time := 1 ns;
35  AXI_READY_EN_G : boolean := false;
38  BURST_BYTES_G : integer range 1 to 4096 := 4096;
39  ACK_WAIT_BVALID_G : boolean := true);
40  port (
41  -- Clock/Reset
42  axiClk : in sl;
43  axiRst : in sl;
44  -- DMA write descriptor request, ack and return
49  -- Config and status
50  dmaWrIdle : out sl;
51  axiCache : in slv(3 downto 0);
52  -- Streaming Interface
55  -- AXI Interface
59 end AxiStreamDmaV2Write;
60 
61 architecture rtl of AxiStreamDmaV2Write is
62 
63  constant DATA_BYTES_C : integer := AXIS_CONFIG_G.TDATA_BYTES_C;
64  constant ADDR_LSB_C : integer := bitSize(DATA_BYTES_C-1);
65  constant FIFO_ADDR_WIDTH_C : natural := (AXI_CONFIG_G.LEN_BITS_C+1);
66 
67  type StateType is (
68  RESET_S,
69  INIT_S,
70  IDLE_S,
71  REQ_S,
72  ADDR_S,
73  MOVE_S,
74  PAD_S,
75  RETURN_S,
76  DUMP_S);
77 
78  type RegType is record
80  dmaWrTrack : AxiWriteDmaTrackType;
82  result : slv(1 downto 0);
83  reqCount : slv(31 downto 0);
84  ackCount : slv(31 downto 0);
85  stCount : slv(15 downto 0);
86  awlen : slv(AXI_CONFIG_G.LEN_BITS_C-1 downto 0);
87  wMaster : AxiWriteMasterType;
88  slave : AxiStreamSlaveType;
89  state : StateType;
90  lastUser : slv(7 downto 0);
91  continue : sl;
92  dmaWrIdle : sl;
93  end record RegType;
94 
95  constant REG_INIT_C : RegType := (
97  dmaWrTrack => AXI_WRITE_DMA_TRACK_INIT_C,
99  result => (others => '0'),
100  reqCount => (others => '0'),
101  ackCount => (others => '0'),
102  stCount => (others => '0'),
103  awlen => (others => '0'),
104  wMaster => axiWriteMasterInit(AXI_CONFIG_G, '1', "01", "0000"),
105  slave => AXI_STREAM_SLAVE_INIT_C,
106  state => RESET_S,
107  lastUser => (others=>'0'),
108  continue => '0',
109  dmaWrIdle => '0');
110 
111  signal r : RegType := REG_INIT_C;
112  signal rin : RegType;
113  signal pause : sl;
114  signal intAxisMaster : AxiStreamMasterType;
115  signal intAxisSlave : AxiStreamSlaveType;
116  signal trackDin : slv(AXI_WRITE_DMA_TRACK_SIZE_C-1 downto 0);
117  signal trackDout : slv(AXI_WRITE_DMA_TRACK_SIZE_C-1 downto 0);
118  signal trackData : AxiWriteDmaTrackType;
119 
120  attribute dont_touch : string;
121  attribute dont_touch of r : signal is "true";
122 
123 begin
124 
126  report "AXIS (" & integer'image(AXIS_CONFIG_G.TDATA_BYTES_C) & ") and AXI ("
127  & integer'image(AXI_CONFIG_G.DATA_BYTES_C) & ") must have equal data widths" severity failure;
128 
129  -- Placeholder for potential FIFO
130  intAxisMaster <= axisMaster;
131  axisSlave <= intAxisSlave;
132 
133  -- Pause when enabled
134  pause <= '0' when (AXI_READY_EN_G) else axiWriteCtrl.pause;
135 
136  -- State machine
137  comb : process (axiRst, axiWriteSlave, dmaWrDescAck, dmaWrDescRetAck,
138  intAxisMaster, trackData, pause, r, axiCache) is
139  variable v : RegType;
140  variable bytes : natural;
141  begin
142  -- Latch the current value
143  v := r;
144 
145  -- Clear stream slave
146  v.slave.tReady := '0';
147 
148  -- Cache setting
149  v.wMaster.awcache := axiCache;
150 
151  -- Reset AXI Signals
152  if (axiWriteSlave.awready = '1') or (AXI_READY_EN_G = false) then
153  v.wMaster.awvalid := '0';
154  end if;
155  if (axiWriteSlave.wready = '1') or (AXI_READY_EN_G = false) then
156  v.wMaster.wvalid := '0';
157  v.wMaster.wlast := '0';
158  end if;
159 
160  -- Wait for memory bus response
161  if (axiWriteSlave.bvalid = '1') and (ACK_WAIT_BVALID_G = true) then
162  -- Increment the counter
163  v.ackCount := r.ackCount + 1;
164  -- Check for error response
165  if (axiWriteSlave.bresp /= "00") and (r.result = 0) then
166  -- Latch the response value
168  end if;
169  end if;
170 
171  -- Descriptor handshaking
172  if dmaWrDescRetAck = '1' then
173  v.dmaWrDescRet.valid := '0';
174  end if;
175  if dmaWrDescAck.valid = '1' then
176  v.dmaWrDescReq.valid := '0';
177  end if;
178 
179  -- Count number of bytes in return data
180  bytes := getTKeep(intAxisMaster.tKeep(DATA_BYTES_C-1 downto 0));
181 
182  -- State machine
183  case r.state is
184  ----------------------------------------------------------------------
185  when RESET_S =>
186  v := REG_INIT_C;
187  if r.stCount = 100 then
188  v.state := INIT_S;
189  else
190  v.stCount := r.stCount + 1;
191  end if;
192  ----------------------------------------------------------------------
193  when INIT_S =>
194  v.dmaWrTrack.dest := r.dmaWrTrack.dest + 1;
195  if r.dmaWrTrack.dest = 255 then
196  v.state := IDLE_S;
197  end if;
198  ----------------------------------------------------------------------
199  when IDLE_S =>
200  if intAxisMaster.tValid = '1' then
201  -- Current destination matches incoming frame
202  if r.dmaWrTrack.dest = intAxisMaster.tDest and r.dmaWrTrack.inUse = '1' then
203  if r.dmaWrTrack.dropEn = '1' then
204  v.state := DUMP_S;
205  else
206  v.state := ADDR_S;
207  end if;
208 
209  -- Wait for mem selection to match incoming frame
210  elsif trackData.dest = intAxisMaster.tDest then
211  -- Set tracking data and setup request
212  v.dmaWrTrack := trackData;
213  v.dmaWrDescReq.dest := trackData.dest;
214 
215  -- Is entry valid or do we need a new buffer
216  if trackData.inUse = '1' then
217  if trackData.dropEn = '1' then
218  v.state := DUMP_S;
219  else
220  v.state := ADDR_S;
221  end if;
222  else
223  v.state := REQ_S;
224  v.dmaWrDescReq.valid := '1';
225  end if;
226  end if;
227  end if;
228  ----------------------------------------------------------------------
229  when REQ_S =>
230  -- Wait for response and latch fields
231  if dmaWrDescAck.valid = '1' then
232  v.dmaWrTrack.inUse := '1';
233  v.dmaWrTrack.address := dmaWrDescAck.address;
234  v.dmaWrTrack.maxSize := dmaWrDescAck.maxSize;
235  v.dmaWrTrack.size := (others=>'0');
236  v.dmaWrTrack.firstUser := (others=>'0');
237  v.dmaWrTrack.contEn := dmaWrDescAck.contEn;
238  v.dmaWrTrack.dropEn := dmaWrDescAck.dropEn;
239  v.dmaWrTrack.buffId := dmaWrDescAck.buffId;
240  v.dmaWrTrack.overflow := '0';
241 
242  -- Descriptor return calls for dumping frame?
243  if dmaWrDescAck.dropEn = '1' then
244  v.state := DUMP_S;
245  else
246  v.state := ADDR_S;
247  end if;
248  end if;
249  ----------------------------------------------------------------------
250  when ADDR_S =>
251  -- Reset counter, continue and last user
252  v.stCount := (others=>'0');
253  v.continue := '0';
254  v.lastUser := (others=>'0');
255  -- Address can be sent
256  if (v.wMaster.awvalid = '0') then
257  -- Set the memory address
258  v.wMaster.awaddr(AXI_CONFIG_G.ADDR_WIDTH_C-1 downto 0) :=
259  r.dmaWrTrack.address(AXI_CONFIG_G.ADDR_WIDTH_C-1 downto 0);
260  -- Determine transfer size aligned to 4k boundaries
261  v.wMaster.awlen := getAxiLen(AXI_CONFIG_G,BURST_BYTES_G,r.dmaWrTrack.maxSize,r.dmaWrTrack.address);
262  -- Latch AXI awlen value
263  v.awlen := v.wMaster.awlen(AXI_CONFIG_G.LEN_BITS_C-1 downto 0);
264  -- Check if enough room
265  if pause = '0' then
266  -- Set the flag
267  v.wMaster.awvalid := '1';
268  -- Increment the counter
269  v.reqCount := r.reqCount + 1;
270  -- Next state
271  v.state := MOVE_S;
272  end if;
273  end if;
274  ----------------------------------------------------------------------
275  when MOVE_S =>
276  -- Incoming valid data
277  if intAxisMaster.tValid = '1' then
278  v.stCount := (others=>'0');
279  -- Destination has changed, complete current write
280  if intAxisMaster.tDest /= r.dmaWrDescReq.dest then
281  v.state := PAD_S;
282  -- Overflow detect
283  elsif bytes > r.dmaWrTrack.maxSize then
284  -- Multi-descriptor DMA is supported
285  if r.dmaWrTrack.contEn = '1' then
286  v.continue := '1';
287  v.dmaWrTrack.inUse := '0';
288  else
289  v.dmaWrTrack.overflow := '1';
290  v.dmaWrTrack.dropEn := '1';
291  end if;
292  -- Pad current write, dump of incoming frame will occur
293  -- after state machine returns to idle due to dropEn being set.
294  -- Return will follow pad with inUse = '0'
295  v.state := PAD_S;
296  -- We are able to push more data
297  elsif v.wMaster.wvalid = '0' then
298  -- Accept the data
299  v.slave.tReady := '1';
300  -- Move the data
301  v.wMaster.wvalid := '1';
302  v.wMaster.wdata((DATA_BYTES_C*8)-1 downto 0) := intAxisMaster.tData((DATA_BYTES_C*8)-1 downto 0);
303  -- Set byte write strobes
304  v.wMaster.wstrb(DATA_BYTES_C-1 downto 0) := intAxisMaster.tKeep(DATA_BYTES_C-1 downto 0);
305  -- Address and size increment
306  v.dmaWrTrack.address := r.dmaWrTrack.address + DATA_BYTES_C;
307  v.dmaWrTrack.address(ADDR_LSB_C-1 downto 0) := (others => '0');
308  -- Increment the byte counter
309  v.dmaWrTrack.size := r.dmaWrTrack.size + bytes;
310  v.dmaWrTrack.maxSize := r.dmaWrTrack.maxSize - bytes;
311  -- First word
312  if r.dmaWrTrack.size = 0 then
313  -- Latch the tDest/tId/tUser values
314  v.dmaWrTrack.id := intAxisMaster.tId;
315  v.dmaWrTrack.firstUser(AXIS_CONFIG_G.TUSER_BITS_C-1 downto 0) :=
316  axiStreamGetUserField(AXIS_CONFIG_G, intAxisMaster, 0);
317  end if;
318  -- -- Check for last AXIS word
319  if intAxisMaster.tLast = '1' then
320  -- Latch the tUser value
321  v.lastUser(AXIS_CONFIG_G.TUSER_BITS_C-1 downto 0) :=
322  axiStreamGetUserField(AXIS_CONFIG_G, intAxisMaster);
323  v.dmaWrTrack.inUse := '0';
324  -- Pad write if transaction is not done, return will following PAD because inUse = 0
325  if r.awlen = 0 then
326  v.state := RETURN_S;
327  else
328  v.state := PAD_S;
329  end if;
330  end if;
331  -- Check for last AXI transfer
332  if r.awlen = 0 then
333  -- Set the flag
334  v.wMaster.wlast := '1';
335  -- If next state has not already been updated go to idle
336  if v.state = MOVE_S then
337  v.state := IDLE_S;
338  end if;
339  else
340  -- Decrement the transaction counter
341  v.awlen := r.awlen - 1;
342  end if;
343  end if;
344  -- Timeout on stalled writes to avoid locking AXI crossbar
345  elsif r.stCount = 100 then
346  v.state := PAD_S;
347  else
348  v.stCount := r.stCount + 1;
349  end if;
350  ----------------------------------------------------------------------
351  when PAD_S =>
352  v.stCount := (others=>'0');
353  -- We are able to push more data
354  if v.wMaster.wvalid = '0' then
355  v.wMaster.wvalid := '1';
356  v.wMaster.wstrb := (others=>'0');
357  -- Check for last AXI transfer
358  if r.awlen = 0 then
359  -- Set the flag
360  v.wMaster.wlast := '1';
361  -- Frame is done. Go to return. Otherwise go to idle.
362  if r.dmaWrTrack.inUse = '0' then
363  v.state := RETURN_S;
364  else
365  v.state := IDLE_S;
366  end if;
367  else
368  -- Decrement the counter
369  v.awlen := r.awlen - 1;
370  end if;
371  end if;
372  ----------------------------------------------------------------------
373  when RETURN_S =>
374  -- Previous return was acked
375  if v.dmaWrDescRet.valid = '0' then
376  -- Setup return record
377  v.dmaWrDescRet.buffId := r.dmaWrTrack.buffId;
378  v.dmaWrDescRet.firstUser := r.dmaWrTrack.firstUser;
379  v.dmaWrDescRet.size := r.dmaWrTrack.size;
380  v.dmaWrDescRet.dest := r.dmaWrTrack.dest;
381  v.dmaWrDescRet.id := r.dmaWrTrack.id;
384  v.dmaWrDescRet.result(2) := r.dmaWrTrack.overflow;
385  v.dmaWrDescRet.result(1 downto 0) := r.result;
386  -- Init record
387  v.dmaWrTrack.inUse := '0';
388  -- Wait for all transactions to complete before returning descriptor
389  if (r.ackCount = r.reqCount) or (ACK_WAIT_BVALID_G = false) then
390  v.dmaWrDescRet.valid := '1';
391  v.state := IDLE_S;
392  -- Check for ACK timeout
393  elsif (r.stCount = x"FFFF") then
394  -- Set the flags
395  v.dmaWrDescRet.result(1 downto 0) := "11";
396  v.dmaWrDescRet.valid := '1';
397  v.reqCount := (others => '0');
398  v.ackCount := (others => '0');
399  v.state := IDLE_S;
400  else
401  -- Increment the counter
402  v.stCount := r.stCount + 1;
403  end if;
404  else
405  v.stCount := (others=>'0');
406  end if;
407  ----------------------------------------------------------------------
408  when DUMP_S =>
409  -- Incoming valid data
410  if intAxisMaster.tValid = '1' then
411  -- Destination has changed, complete current write
412  if intAxisMaster.tDest /= r.dmaWrDescReq.dest then
413  v.state := IDLE_S;
414  else
415  -- Accept the data
416  v.slave.tReady := '1';
417  -- -- Check for last AXIS word
418  if intAxisMaster.tLast = '1' then
419  v.dmaWrTrack.inUse := '0';
420  v.state := RETURN_S;
421  end if;
422  end if;
423  end if;
424  ----------------------------------------------------------------------
425  when others =>
426  v.state := RESET_S;
427  end case;
428 
429  -- Forward the state of the state machine
430  if (v.state = IDLE_S) then
431  v.dmaWrIdle := '1';
432  else
433  v.dmaWrIdle := '0';
434  end if;
435 
436  -- Reset
437  if (axiRst = '1') then
438  v := REG_INIT_C;
439  end if;
440 
441  -- Register the variable for next clock cycle
442  rin <= v;
443 
444  -- Outputs
445  intAxisSlave <= v.slave;
446  axiWriteMaster <= r.wMaster;
449  dmaWrIdle <= r.dmaWrIdle;
450 
451  end process comb;
452 
453  seq : process (axiClk) is
454  begin
455  if (rising_edge(axiClk)) then
456  r <= rin after TPD_G;
457  end if;
458  end process seq;
459 
460  --------------------------
461  -- Tracking RAM
462  --------------------------
463  U_TrackRam: entity work.DualPortRam
464  generic map (
465  TPD_G => TPD_G,
467  ADDR_WIDTH_G => 8)
468  port map (
469  clka => axiClk,
470  wea => '1',
471  rsta => axiRst,
472  addra => r.dmaWrTrack.dest,
473  dina => trackDin,
474  clkb => axiClk,
475  rstb => axiRst,
476  addrb => intAxisMaster.tDest,
477  doutb => trackDout);
478 
479  trackDin <= toSlv(r.dmaWrTrack);
480  trackData <= toAxiWriteDmaTrack(trackDout);
481 
482 end rtl;
integer := 172 AXI_WRITE_DMA_TRACK_SIZE_C
Definition: AxiDmaPkg.vhd:278
in axiWriteCtrlAxiCtrlType := AXI_CTRL_UNUSED_C
slv( 7 downto 0) tId
slv( 63 downto 0) address
Definition: AxiDmaPkg.vhd:49
AxiCtrlType
Definition: AxiPkg.vhd:198
slv( 7 downto 0) dest
Definition: AxiDmaPkg.vhd:78
sl wvalid
Definition: AxiPkg.vhd:124
sl bvalid
Definition: AxiPkg.vhd:178
slv( 7 downto 0) firstUser
Definition: AxiDmaPkg.vhd:76
std_logic sl
Definition: StdRtlPkg.vhd:28
sl wlast
Definition: AxiPkg.vhd:123
in axisMasterAxiStreamMasterType
out doutbslv( DATA_WIDTH_G- 1 downto 0)
Definition: DualPortRam.vhd:57
slv( 1023 downto 0) wdata
Definition: AxiPkg.vhd:122
slv( 7 downto 0) awlen
Definition: AxiPkg.vhd:113
TPD_Gtime := 1 ns
Definition: DualPortRam.vhd:29
out dmaWrDescRetAxiWriteDmaDescRetType
slv( 7 downto 0) id
Definition: AxiDmaPkg.vhd:79
sl awready
Definition: AxiPkg.vhd:173
slv( 15 downto 0) tKeep
ADDR_WIDTH_Ginteger range 1 to ( 2** 24):= 4
Definition: DualPortRam.vhd:39
ACK_WAIT_BVALID_Gboolean := true
slv( 127 downto 0) wstrb
Definition: AxiPkg.vhd:126
in axiWriteSlaveAxiWriteSlaveType
AxiCtrlType :=(pause => '0',overflow => '0') AXI_CTRL_UNUSED_C
Definition: AxiPkg.vhd:206
slv( 15 downto 0) buffId
Definition: AxiDmaPkg.vhd:188
natural range 1 to 16 TDATA_BYTES_C
AxiWriteDmaDescReqType
Definition: AxiDmaPkg.vhd:158
BURST_BYTES_Ginteger range 1 to 4096:= 4096
AXI_CONFIG_GAxiConfigType := AXI_CONFIG_INIT_C
slv( 2 downto 0) result
Definition: AxiDmaPkg.vhd:219
AxiWriteDmaDescReqType :=(valid => '0',dest =>( others => '0')) AXI_WRITE_DMA_DESC_REQ_INIT_C
Definition: AxiDmaPkg.vhd:163
in clkasl := '0'
Definition: DualPortRam.vhd:43
positive range 12 to 64 ADDR_WIDTH_C
Definition: AxiPkg.vhd:214
AxiWriteMasterType
Definition: AxiPkg.vhd:108
AXIS_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
slv( 7 downto 0) lastUser
Definition: AxiDmaPkg.vhd:77
AxiWriteDmaDescAckType
Definition: AxiDmaPkg.vhd:182
slv( 127 downto 0) tData
sl wready
Definition: AxiPkg.vhd:175
in clkbsl := '0'
Definition: DualPortRam.vhd:53
AxiWriteDmaTrackType
Definition: AxiDmaPkg.vhd:248
sl awvalid
Definition: AxiPkg.vhd:110
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
AXI_READY_EN_Gboolean := false
out axiWriteMasterAxiWriteMasterType
out dmaWrDescReqAxiWriteDmaDescReqType
in addrbslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
Definition: DualPortRam.vhd:56
in dmaWrDescAckAxiWriteDmaDescAckType
in weasl := '0'
Definition: DualPortRam.vhd:45
AxiConfigType
Definition: AxiPkg.vhd:213
out axisSlaveAxiStreamSlaveType
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
Definition: DualPortRam.vhd:37
in rstasl :=not ( RST_POLARITY_G)
Definition: DualPortRam.vhd:47
AxiWriteSlaveType
Definition: AxiPkg.vhd:171
AxiWriteDmaTrackType :=(dest =>( others => '0'),inUse => '0',address =>( others => '0'),maxSize =>( others => '0'),size =>( others => '0'),firstUser =>( others => '0'),contEn => '0',dropEn => '0',id =>( others => '0'),buffId =>( others => '0'),overflow => '0') AXI_WRITE_DMA_TRACK_INIT_C
Definition: AxiDmaPkg.vhd:262
in axiCacheslv( 3 downto 0)
natural range 0 to 8 TUSER_BITS_C
AxiWriteDmaDescRetType :=(valid => '0',buffId =>( others => '0'),firstUser =>( others => '0'),lastUser =>( others => '0'),size =>( others => '0'),continue => '0',result =>( others => '0'),dest =>( others => '0'),id =>( others => '0')) AXI_WRITE_DMA_DESC_RET_INIT_C
Definition: AxiDmaPkg.vhd:224
in dinaslv( DATA_WIDTH_G- 1 downto 0) :=( others => '0')
Definition: DualPortRam.vhd:49
slv( 3 downto 0) awcache
Definition: AxiPkg.vhd:118
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
slv( 7 downto 0) tDest
slv( 63 downto 0) awaddr
Definition: AxiPkg.vhd:111
positive range 1 to 128 DATA_BYTES_C
Definition: AxiPkg.vhd:215
slv( 31 downto 0) size
Definition: AxiDmaPkg.vhd:72
slv( 31 downto 0) maxSize
Definition: AxiDmaPkg.vhd:50
in addraslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
Definition: DualPortRam.vhd:48
slv( 1 downto 0) bresp
Definition: AxiPkg.vhd:177
AxiConfigType :=axiConfig(ADDR_WIDTH_C => 32,DATA_BYTES_C => 4,ID_BITS_C => 12,LEN_BITS_C => 4) AXI_CONFIG_INIT_C
Definition: AxiPkg.vhd:227
in rstbsl :=not ( RST_POLARITY_G)
Definition: DualPortRam.vhd:55
AxiWriteDmaDescRetType
Definition: AxiDmaPkg.vhd:212
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
natural range 0 to 8 LEN_BITS_C
Definition: AxiPkg.vhd:217