SURF  1.0
AxiStreamDmaV2Desc.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiStreamDmaV2Desc.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2017-02-02
5 -- Last update: 2017-02-02
6 -------------------------------------------------------------------------------
7 -- Description:
8 -- Descriptor manager for AXI DMA read and write engines.
9 -------------------------------------------------------------------------------
10 -- This file is part of 'SLAC Firmware Standard Library'.
11 -- It is subject to the license terms in the LICENSE.txt file found in the
12 -- top-level directory of this distribution and at:
13 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
14 -- No part of 'SLAC Firmware Standard Library', including this file,
15 -- may be copied, modified, propagated, or distributed except according to
16 -- the terms contained in the LICENSE.txt file.
17 -------------------------------------------------------------------------------
18 
19 library ieee;
20 use ieee.std_logic_1164.all;
21 use ieee.std_logic_arith.all;
22 use ieee.std_logic_unsigned.all;
23 use ieee.NUMERIC_STD.all;
24 
25 use work.StdRtlPkg.all;
26 use work.AxiPkg.all;
27 use work.AxiLitePkg.all;
28 use work.AxiDmaPkg.all;
29 use work.ArbiterPkg.all;
30 
31 --! @see entity
32  --! @ingroup axi
34  generic (
35  TPD_G : time := 1 ns;
36  CHAN_COUNT_G : integer range 1 to 16 := 1;
37  AXIL_BASE_ADDR_G : slv(31 downto 0) := x"00000000";
39  AXI_READY_EN_G : boolean := false;
41  DESC_AWIDTH_G : integer range 4 to 12 := 12;
42  ACK_WAIT_BVALID_G : boolean := true);
43  port (
44  -- Clock/Reset
45  axiClk : in sl;
46  axiRst : in sl;
47  -- Local AXI Lite Bus
52  -- Additional signals
53  interrupt : out sl;
54  online : out slv(CHAN_COUNT_G-1 downto 0);
55  acknowledge : out slv(CHAN_COUNT_G-1 downto 0);
56  -- DMA write descriptor request, ack and return
60  dmaWrDescRetAck : out slv(CHAN_COUNT_G-1 downto 0);
61  -- DMA read descriptor request, ack and return
63  dmaRdDescAck : in slv(CHAN_COUNT_G-1 downto 0);
65  dmaRdDescRetAck : out slv(CHAN_COUNT_G-1 downto 0);
66  -- Config
67  axiCache : out slv(3 downto 0);
68  -- AXI Interface
72 end AxiStreamDmaV2Desc;
73 
74 architecture rtl of AxiStreamDmaV2Desc is
75 
76  constant CROSSBAR_CONN_C : slv(15 downto 0) := x"FFFF";
77 
78  constant CB_COUNT_C : integer := 2;
79 
80  constant LOC_INDEX_C : natural := 0;
81  constant LOC_BASE_ADDR_C : slv(31 downto 0) := AXIL_BASE_ADDR_G(31 downto 16) & x"0000";
82  constant LOC_NUM_BITS_C : natural := 14;
83 
84  constant ADDR_INDEX_C : natural := 1;
85  constant ADDR_BASE_ADDR_C : slv(31 downto 0) := AXIL_BASE_ADDR_G(31 downto 16) & x"4000";
86  constant ADDR_NUM_BITS_C : natural := 14;
87 
88  constant AXI_CROSSBAR_MASTERS_CONFIG_C : AxiLiteCrossbarMasterConfigArray(CB_COUNT_C-1 downto 0) := (
89  LOC_INDEX_C => (
90  baseAddr => LOC_BASE_ADDR_C,
91  addrBits => LOC_NUM_BITS_C,
92  connectivity => CROSSBAR_CONN_C),
93  ADDR_INDEX_C => (
94  baseAddr => ADDR_BASE_ADDR_C,
95  addrBits => ADDR_NUM_BITS_C,
96  connectivity => CROSSBAR_CONN_C));
97 
98  signal intReadMasters : AxiLiteReadMasterArray(CB_COUNT_C-1 downto 0);
99  signal intReadSlaves : AxiLiteReadSlaveArray(CB_COUNT_C-1 downto 0);
100  signal intWriteMasters : AxiLiteWriteMasterArray(CB_COUNT_C-1 downto 0);
101  signal intWriteSlaves : AxiLiteWriteSlaveArray(CB_COUNT_C-1 downto 0);
102 
103  type DescStateType is ( IDLE_S, WRITE_S, READ_S, WAIT_S );
104 
105  constant CHAN_SIZE_C : integer := bitSize(CHAN_COUNT_G-1);
106  constant DESC_COUNT_C : integer := CHAN_COUNT_G*2;
107  constant DESC_SIZE_C : integer := bitSize(DESC_COUNT_C-1);
108 
109  type RegType is record
110 
111  -- Write descriptor interface
113  dmaWrDescRetAck : slv(CHAN_COUNT_G-1 downto 0);
114 
115  -- Read descriptor interface
117  dmaRdDescRetAck : slv(CHAN_COUNT_G-1 downto 0);
118 
119  -- Axi-Lite
122 
123  -- AXI
125 
126  -- Configuration
127  buffBaseAddr : slv(63 downto 32); -- For buffer entries
128  wrBaseAddr : slv(63 downto 0); -- For wr ring buffer
129  rdBaseAddr : slv(63 downto 0); -- For rd ring buffer
130  maxSize : slv(23 downto 0);
131  contEn : sl;
132  dropEn : sl;
133  enable : sl;
134  intEnable : sl;
135  online : slv(CHAN_COUNT_G-1 downto 0);
136  acknowledge : slv(CHAN_COUNT_G-1 downto 0);
137  fifoReset : sl;
138  intAckEn : sl;
139  intAckCount : slv(15 downto 0);
140  descCache : slv(3 downto 0);
141  buffCache : slv(3 downto 0);
142 
143  -- FIFOs
144  fifoDin : slv(31 downto 0);
145  wrFifoWr : sl;
146  rdFifoWr : slv(1 downto 0);
147  addrFifoSel : sl;
148  wrFifoRd : sl;
149  wrFifoValidDly : slv(1 downto 0);
150  wrAddr : slv(31 downto 0);
151  wrAddrValid : sl;
152  rdFifoRd : sl;
153  rdFifoValidDly : slv(1 downto 0);
154  rdAddr : slv(31 downto 0);
155  rdAddrValid : sl;
156 
157  -- Write Desc Request
158  wrReqValid : sl;
159  wrReqNum : slv(CHAN_SIZE_C-1 downto 0);
160  wrReqAcks : slv(CHAN_COUNT_G-1 downto 0);
161  wrReqMissed : slv(31 downto 0);
162 
163  -- Desc Return
164  descRetList : slv(DESC_COUNT_C-1 downto 0);
165  descState : DescStateType;
166  descRetNum : slv(DESC_SIZE_C-1 downto 0);
167  descRetAcks : slv(DESC_COUNT_C-1 downto 0);
168  wrIndex : slv(DESC_AWIDTH_G-1 downto 0);
169  wrMemAddr : slv(63 downto 0);
170  rdIndex : slv(DESC_AWIDTH_G-1 downto 0);
171  rdMemAddr : slv(63 downto 0);
172  intReqEn : sl;
173  intReqCount : slv(31 downto 0);
174  interrupt : sl;
175 
176  end record RegType;
177 
178  constant REG_INIT_C : RegType := (
180  dmaWrDescRetAck => (others=>'0'),
182  dmaRdDescRetAck => (others=>'0'),
185  axiWriteMaster => axiWriteMasterInit(AXI_CONFIG_G, '1', "01", "0000"),
186  buffBaseAddr => (others => '0'),
187  wrBaseAddr => (others => '0'),
188  rdBaseAddr => (others => '0'),
189  maxSize => (others => '0'),
190  contEn => '0',
191  dropEn => '0',
192  enable => '0',
193  intEnable => '0',
194  online => (others=>'0'),
195  acknowledge => (others=>'0'),
196  fifoReset => '1',
197  intAckEn => '0',
198  intAckCount => (others=>'0'),
199  descCache => (others=>'0'),
200  buffCache => (others=>'0'),
201  fifoDin => (others=>'0'),
202  wrFifoWr => '0',
203  rdFifoWr => (others=>'0'),
204  addrFifoSel => '0',
205  wrFifoRd => '0',
206  wrFifoValidDly => (others=>'0'),
207  wrAddr => (others=>'0'),
208  wrAddrValid => '0',
209  rdFifoRd => '0',
210  rdFifoValidDly => (others=>'0'),
211  rdAddr => (others=>'0'),
212  rdAddrValid => '0',
213  wrReqValid => '0',
214  wrReqNum => (others=>'0'),
215  wrReqAcks => (others=>'0'),
216  wrReqMissed => (others=>'0'),
217  descRetList => (others=>'0'),
218  descState => IDLE_S,
219  descRetNum => (others=>'0'),
220  descRetAcks => (others=>'0'),
221  wrIndex => (others=>'0'),
222  wrMemAddr => (others=>'0'),
223  rdIndex => (others=>'0'),
224  rdMemAddr => (others=>'0'),
225  intReqEn => '0',
226  intReqCount => (others=>'0'),
227  interrupt => '0'
228  );
229 
230  signal r : RegType := REG_INIT_C;
231  signal rin : RegType;
232  signal pause : sl;
233  signal rdFifoValid : slv(1 downto 0);
234  signal rdFifoDout : slv(63 downto 0);
235  signal wrFifoValid : sl;
236  signal wrFifoDout : slv(15 downto 0);
237  signal addrRamDout : slv(31 downto 0);
238  signal addrRamAddr : slv(DESC_AWIDTH_G-1 downto 0);
239 
240  attribute dont_touch : string;
241  attribute dont_touch of r : signal is "true";
242 
243  procedure axiWrDetect (
244  variable ep : inout AxiLiteEndpointType;
245  addr : in slv;
246  reg : inout sl)
247  is
248  -- Need to remap addr range to be (length-1 downto 0)
249  constant ADDR_LEN_C : integer := addr'length;
250  constant ADDR_C : slv(ADDR_LEN_C-1 downto 0) := addr;
251  begin
252  if (ep.axiStatus.writeEnable = '1') then
253  if std_match(ep.axiWriteMaster.awaddr(ADDR_LEN_C-1 downto 2), ADDR_C(ADDR_LEN_C-1 downto 2)) then
254  reg := '1';
255  axiSlaveWriteResponse(ep.axiWriteSlave);
256  end if;
257  end if;
258  end procedure;
259 
260 begin
261 
262  -----------------------------------------
263  -- Crossbar
264  -----------------------------------------
265  U_AxiCrossbar : entity work.AxiLiteCrossbar
266  generic map (
267  TPD_G => TPD_G,
268  NUM_SLAVE_SLOTS_G => 1,
269  NUM_MASTER_SLOTS_G => CB_COUNT_C,
271  MASTERS_CONFIG_G => AXI_CROSSBAR_MASTERS_CONFIG_C)
272  port map (
273  axiClk => axiClk,
274  axiClkRst => axiRst,
275  sAxiWriteMasters(0) => axilWriteMaster,
276  sAxiWriteSlaves(0) => axilWriteSlave,
277  sAxiReadMasters(0) => axilReadMaster,
278  sAxiReadSlaves(0) => axilReadSlave,
279  mAxiWriteMasters => intWriteMasters,
280  mAxiWriteSlaves => intWriteSlaves,
281  mAxiReadMasters => intReadMasters,
282  mAxiReadSlaves => intReadSlaves);
283 
284  -----------------------------------------
285  -- Write Free List FIFO
286  -----------------------------------------
287  U_DescFifo: entity work.Fifo
288  generic map (
289  TPD_G => TPD_G,
290  GEN_SYNC_FIFO_G => true,
291  FWFT_EN_G => true,
292  DATA_WIDTH_G => 16,
294  port map (
295  rst => r.fifoReset,
296  wr_clk => axiClk,
297  wr_en => r.wrFifoWr,
298  din => r.fifoDin(15 downto 0),
299  rd_clk => axiClk,
300  rd_en => r.wrFifoRd,
301  dout => wrFifoDout,
302  valid => wrFifoValid);
303 
304  -----------------------------------------
305  -- Read Transaction FIFOs
306  -----------------------------------------
307  U_RdLowFifo: entity work.Fifo
308  generic map (
309  TPD_G => TPD_G,
310  GEN_SYNC_FIFO_G => true,
311  FWFT_EN_G => true,
312  DATA_WIDTH_G => 32,
314  port map (
315  rst => r.fifoReset,
316  wr_clk => axiClk,
317  wr_en => r.rdFifoWr(0),
318  din => r.fifoDin,
319  rd_clk => axiClk,
320  rd_en => r.rdFifoRd,
321  dout => rdFifoDout(31 downto 0),
322  valid => rdFifoValid(0));
323 
324  U_RdHighFifo: entity work.Fifo
325  generic map (
326  TPD_G => TPD_G,
327  GEN_SYNC_FIFO_G => true,
328  FWFT_EN_G => true,
329  DATA_WIDTH_G => 32,
331  port map (
332  rst => r.fifoReset,
333  wr_clk => axiClk,
334  wr_en => r.rdFifoWr(1),
335  din => r.fifoDin,
336  rd_clk => axiClk,
337  rd_en => r.rdFifoRd,
338  dout => rdFifoDout(63 downto 32),
339  valid => rdFifoValid(1));
340 
341  -----------------------------------------
342  -- Address RAM
343  -----------------------------------------
344  U_AddrRam: entity work.AxiDualPortRam
345  generic map (
346  TPD_G => TPD_G,
347  REG_EN_G => true,
348  BRAM_EN_G => true,
349  COMMON_CLK_G => true,
351  DATA_WIDTH_G => 32)
352  port map (
353  axiClk => axiClk,
354  axiRst => axiRst,
355  axiReadMaster => intReadMasters(ADDR_INDEX_C),
356  axiReadSlave => intReadSlaves(ADDR_INDEX_C),
357  axiWriteMaster => intWriteMasters(ADDR_INDEX_C),
358  axiWriteSlave => intWriteSlaves(ADDR_INDEX_C),
359  clk => axiClk,
360  rst => axiRst,
361  addr => addrRamAddr,
362  dout => addrRamDout);
363 
364  addrRamAddr <= wrFifoDout(DESC_AWIDTH_G-1 downto 0) when r.addrFifoSel = '0' else
365  rdFifoDout(DESC_AWIDTH_G+3 downto 4);
366 
367  -----------------------------------------
368  -- Control Logic
369  -----------------------------------------
370 
371  -- Choose pause source
372  pause <= '0' when (AXI_READY_EN_G) else axiWriteCtrl.pause;
373 
374  comb : process (axiRst, intReadMasters, intWriteMasters, axiWriteSlave,
376  wrFifoDout, wrFifoValid, rdFifoDout, rdFifoValid, addrRamDout, pause, r) is
377 
378  variable v : RegType;
379  variable wrReqList : slv(CHAN_COUNT_G-1 downto 0);
380  --variable descRetList : slv(DESC_COUNT_C-1 downto 0);
381  variable descRetValid : sl;
382  variable descIndex : natural;
383  variable dmaRdReq : AxiReadDmaDescReqType;
384  variable rdIndex : natural;
385  variable regCon : AxiLiteEndPointType;
386  begin
387 
388  -- Latch the current value
389  v := r;
390 
391  -- Clear one shot signals
392  v.rdFifoWr := "00";
393  v.rdFifoRd := '0';
394  v.wrFifoWr := '0';
395  v.wrFifoRd := '0';
396  v.acknowledge := (others=>'0');
397 
398  -----------------------------
399  -- Register access
400  -----------------------------
401 
402  -- Start transaction block
403  axiSlaveWaitTxn(regCon, intWriteMasters(LOC_INDEX_C), intReadMasters(LOC_INDEX_C), v.axilWriteSlave, v.axilReadSlave);
404 
405  axiSlaveRegister(regCon, x"000", 0, v.enable);
406  axiSlaveRegisterR(regCon, x"000", 24, toSlv(2,8)); -- Version 2 = 2, Version1 = 0
407 
408  axiSlaveRegister(regCon, x"004", 0, v.intEnable);
409  axiSlaveRegister(regCon, x"008", 0, v.contEn);
410  axiSlaveRegister(regCon, x"00C", 0, v.dropEn);
411  axiSlaveRegister(regCon, x"010", 0, v.wrBaseAddr(31 downto 0));
412  axiSlaveRegister(regCon, x"014", 0, v.wrBaseAddr(63 downto 32));
413  axiSlaveRegister(regCon, x"018", 0, v.rdBaseAddr(31 downto 0));
414  axiSlaveRegister(regCon, x"01C", 0, v.rdBaseAddr(63 downto 32));
415  axiSlaveRegister(regCon, x"020", 0, v.fifoReset);
416  axiSlaveRegister(regCon, x"024", 0, v.buffBaseAddr(63 downto 32));
417  axiSlaveRegister(regCon, x"028", 0, v.maxSize);
418  axiSlaveRegister(regCon, x"02C", 0, v.online);
419  axiSlaveRegister(regCon, x"030", 0, v.acknowledge);
420 
421  axiSlaveRegisterR(regCon, x"034", 0, toSlv(CHAN_COUNT_G,8));
422  axiSlaveRegisterR(regCon, x"038", 0, toSlv(DESC_AWIDTH_G,8));
423  axiSlaveRegister(regCon, x"03C", 0, v.descCache);
424  axiSlaveRegister(regCon, x"03C", 8, v.buffCache);
425 
426  axiSlaveRegister(regCon, x"040", 0, v.fifoDin);
427  axiWrDetect(regCon, x"040", v.rdFifoWr(0));
428 
429  axiSlaveRegister(regCon, x"044", 0, v.fifoDin);
430  axiWrDetect(regCon, x"044", v.rdFifoWr(1));
431 
432  axiSlaveRegister(regCon, x"048", 0, v.fifoDin);
433  axiWrDetect(regCon, x"048", v.wrFifoWr);
434 
435  axiSlaveRegister(regCon, x"04C", 0, v.intAckCount);
436  axiSlaveRegister(regCon, x"04C", 17, v.intEnable);
437  axiWrDetect(regCon, x"04C", v.intAckEn);
438 
439  axiSlaveRegisterR(regCon, x"050", 0, r.intReqCount);
440  axiSlaveRegisterR(regCon, x"054", 0, r.wrIndex);
441  axiSlaveRegisterR(regCon, x"058", 0, r.rdIndex);
442 
443  axiSlaveRegisterR(regCon, x"05C", 0, r.wrReqMissed);
444 
445  -- End transaction block
446  axiSlaveDefault(regCon,v.axilWriteSlave, v.axilReadSlave, AXI_ERROR_RESP_G);
447 
448  --------------------------------------
449  -- Address FIFO Control
450  --------------------------------------
451  -- Alternate between read and write FIFOs to common address pool
452  v.addrFifoSel := not v.addrFifoSel;
453 
454  -- Write pipeline
455  if r.wrFifoRd = '1' then
456  v.wrFifoValidDly := (others=>'0');
457  v.wrAddr := (others=>'1');
458  v.wrAddrValid := '0';
459  else
460  v.wrFifoValidDly := (wrFifoValid and (not r.addrFifoSel)) & r.wrFifoValidDly(1);
461  if r.wrFifoValidDly(0) = '1' then
462  v.wrAddr := addrRamDout;
463  v.wrAddrValid := '1';
464  end if;
465  end if;
466 
467  -- Read pipeline
468  if r.rdFifoRd = '1' then
469  v.rdFifoValidDly := (others=>'0');
470  v.rdAddr := (others=>'1');
471  v.rdAddrValid := '0';
472  else
473  v.rdFifoValidDly := (rdFifoValid(0) and rdFifoValid(1) and r.addrFifoSel) & r.rdFifoValidDly(1);
474  if r.rdFifoValidDly(0) = '1' then
475  v.rdAddr := addrRamDout;
476  v.rdAddrValid := '1';
477  end if;
478  end if;
479 
480  --------------------------------------
481  -- Write Descriptor Requests
482  --------------------------------------
483 
484  -- Clear acks
485  for i in 0 to CHAN_COUNT_G-1 loop
486  v.dmaWrDescAck(i).valid := '0';
487  end loop;
488 
489  -- Arbitrate
490  if r.wrReqValid = '0' then
491 
492  -- Format requests
493  wrReqList := (others=>'0');
494  for i in 0 to CHAN_COUNT_G-1 loop
495  wrReqList(i) := dmaWrDescReq(i).valid;
496  end loop;
497 
498  -- Aribrate between requesters
499  if r.enable = '1' and r.wrFifoRd = '0' and r.wrAddrValid = '1' then
500  arbitrate(wrReqList, r.wrReqNum, v.wrReqNum, v.wrReqValid, v.wrReqAcks);
501  end if;
502 
503  if r.enable = '0' then
504  v.wrReqMissed := (others=>'0');
505  elsif wrReqList /= 0 and wrFifoValid = '0' then
506  v.wrReqMissed := r.wrReqMissed + 1;
507  end if;
508 
509  -- Valid arbitration result
510  else
511  for i in 0 to CHAN_COUNT_G-1 loop
512  v.dmaWrDescAck(i).address := r.buffBaseAddr & r.wrAddr;
513  v.dmaWrDescAck(i).dropEn := r.dropEn;
514  v.dmaWrDescAck(i).contEn := r.contEn;
515  v.dmaWrDescAck(i).buffId(11 downto 0) := wrFifoDout(11 downto 0);
516  v.dmaWrDescAck(i).maxSize(23 downto 0) := r.maxSize;
517  end loop;
518 
519  v.dmaWrDescAck(conv_integer(r.wrReqNum)).valid := '1';
520  v.wrFifoRd := '1';
521  v.wrReqValid := '0';
522 
523  end if;
524 
525 
526  --------------------------------------
527  -- Read/Write Descriptor Returns
528  --------------------------------------
529 
530  -- Clear acks
531  v.dmaWrDescRetAck := (others=>'0');
532  v.dmaRdDescRetAck := (others=>'0');
533 
534  -- Axi Cache
535  v.axiWriteMaster.awcache := r.descCache;
536 
537  -- Reset strobing Signals
538  if (axiWriteSlave.awready = '1') or (AXI_READY_EN_G = false) then
539  v.axiWriteMaster.awvalid := '0';
540  end if;
541  if (axiWriteSlave.wready = '1') or (AXI_READY_EN_G = false) then
542  v.axiWriteMaster.wvalid := '0';
543  v.axiWriteMaster.wlast := '0';
544  end if;
545 
546  -- Generate descriptor ring addresses
547  v.wrMemAddr := v.wrBaseAddr + (v.wrIndex & "000");
548  v.rdMemAddr := v.rdBaseAddr + (v.rdIndex & "000");
549 
550  -- State machine
551  case r.descState is
552  ----------------------------------------------------------------------
553  when IDLE_S =>
554 
555  -- Format requests
556  v.descRetList := (others=>'0');
557  for i in 0 to CHAN_COUNT_G-1 loop
558  v.descRetList(i*2) := dmaWrDescRet(i).valid;
559  v.descRetList(i*2+1) := dmaRdDescRet(i).valid;
560  end loop;
561 
562  -- Aribrate between requesters
563  if r.enable = '1' and pause = '0' then
564  arbitrate(v.descRetList, r.descRetNum, v.descRetNum, descRetValid, v.descRetAcks);
565 
566  -- Valid request
567  if descRetValid = '1' then
568  if v.descRetNum(0) = '1' then
569  v.descState := READ_S;
570  else
571  v.descState := WRITE_S;
572  end if;
573  end if;
574  end if;
575 
576  ----------------------------------------------------------------------
577  when WRITE_S =>
578  if CHAN_COUNT_G > 1 then
579  descIndex := conv_integer(r.descRetNum(DESC_SIZE_C-1 downto 1));
580  else
581  descIndex := 0;
582  end if;
583 
584  -- Write address channel
585  v.axiWriteMaster.awaddr := r.wrMemAddr;
586  v.axiWriteMaster.awlen := x"00"; -- Single transaction
587 
588  -- Write data channel
589  v.axiWriteMaster.wlast := '1';
590  v.axiWriteMaster.wstrb := resize(x"FF",128);
591 
592  -- Descriptor data
593  v.axiWriteMaster.wdata(63 downto 56) := dmaWrDescRet(descIndex).dest;
594  v.axiWriteMaster.wdata(55 downto 32) := dmaWrDescRet(descIndex).size(23 downto 0);
595  v.axiWriteMaster.wdata(31 downto 24) := dmaWrDescRet(descIndex).firstUser;
596  v.axiWriteMaster.wdata(23 downto 16) := dmaWrDescRet(descIndex).lastUser;
597  v.axiWriteMaster.wdata(15 downto 4) := dmaWrDescRet(descIndex).buffId(11 downto 0);
598  v.axiWriteMaster.wdata(3) := dmaWrDescRet(descIndex).continue;
599  v.axiWriteMaster.wdata(2 downto 0) := dmaWrDescRet(descIndex).result;
600 
601  -- Encoded channel into upper destination bits
602  if CHAN_COUNT_G > 1 then
603  v.axiWriteMaster.wdata(63 downto 64-CHAN_SIZE_C) := toSlv(descIndex,CHAN_SIZE_C);
604  end if;
605 
606  v.axiWriteMaster.awvalid := '1';
607  v.axiWriteMaster.wvalid := '1';
608  v.wrIndex := r.wrIndex + 1;
609  v.descState := WAIT_S;
610 
611  v.dmaWrDescRetAck(descIndex) := '1';
612 
613  ----------------------------------------------------------------------
614  when READ_S =>
615  if CHAN_COUNT_G > 1 then
616  descIndex := conv_integer(r.descRetNum(DESC_SIZE_C-1 downto 1));
617  else
618  descIndex := 0;
619  end if;
620 
621  -- Write address channel
622  v.axiWriteMaster.awaddr := r.rdMemAddr;
623  v.axiWriteMaster.awlen := x"00"; -- Single transaction
624 
625  -- Write data channel
626  v.axiWriteMaster.wlast := '1';
627  v.axiWriteMaster.wstrb := resize(x"FF",128);
628 
629  -- Descriptor data
630  v.axiWriteMaster.wdata(63 downto 32) := x"00000001";
631  v.axiWriteMaster.wdata(31 downto 16) := (others=>'0');
632  v.axiWriteMaster.wdata(15 downto 4) := dmaRdDescRet(descIndex).buffId(11 downto 0);
633  v.axiWriteMaster.wdata(3) := '0';
634  v.axiWriteMaster.wdata(2 downto 0) := dmaRdDescRet(descIndex).result;
635 
636  v.axiWriteMaster.awvalid := '1';
637  v.axiWriteMaster.wvalid := '1';
638  v.rdIndex := r.rdIndex + 1;
639  v.descState := WAIT_S;
640 
641  v.dmaRdDescRetAck(descIndex) := '1';
642 
643  ----------------------------------------------------------------------
644  when WAIT_S =>
645  if v.axiWriteMaster.awvalid = '0' and v.axiWriteMaster.wvalid = '0' and
646  (axiWriteSlave.bvalid = '1' or ACK_WAIT_BVALID_G = FALSE ) then
647  v.intReqEn := '1';
648  v.descState := IDLE_S;
649  end if;
650 
651  when others =>
652  v.descState := IDLE_S;
653 
654  end case;
655 
656  -- Driver interrupt
657  if r.intReqCount /= 0 then
658  v.interrupt := v.intEnable;
659  else
660  v.interrupt := '0';
661  end if;
662 
663  -- Ack from software
664  if r.intAckEn = '1' then
665  v.intAckEn := '0';
666  v.interrupt := '0';
667 
668  -- Just in case
669  if r.intAckCount > r.intReqCount then
670  v.intReqCount := (others=>'0');
671  else
672  v.intReqCount := r.intReqCount - r.intAckCount;
673  end if;
674 
675  -- Firmware posted an entry
676  elsif r.intReqEn = '1' then
677  v.intReqCount := r.intReqCount + 1;
678  v.intReqEn := '0';
679  end if;
680 
681  -- Engine disabled
682  if r.enable = '0' then
683  v.intAckEn := '0';
684  v.intReqEn := '0';
685  v.intReqCount := (others=>'0');
686  v.interrupt := '0';
687  end if;
688 
689  --------------------------------------
690  -- Read Descriptor Requests
691  --------------------------------------
692 
693  -- Clear requests
694  for i in 0 to CHAN_COUNT_G-1 loop
695  if dmaRdDescAck(i) = '1' then
696  v.dmaRdDescReq(i).valid := '0';
697  end if;
698  end loop;
699 
700  -- Format request
701  dmaRdReq := AXI_READ_DMA_DESC_REQ_INIT_C;
702  dmaRdReq.valid := r.rdAddrValid;
703  dmaRdReq.address := r.buffBaseAddr & r.rdAddr;
704  dmaRdReq.dest := rdFifoDout(63 downto 56);
705  dmaRdReq.size(23 downto 0) := rdFifoDout(55 downto 32);
706  dmaRdReq.firstUser := rdFifoDout(31 downto 24);
707  dmaRdReq.lastUser := rdFifoDout(23 downto 16);
708  dmaRdReq.buffId(11 downto 0) := rdFifoDout(15 downto 4);
709  dmaRdReq.continue := rdFifoDout(3);
710 
711  -- Upper dest bits select channel
712  if CHAN_COUNT_G > 1 then
713  rdIndex := conv_integer(dmaRdReq.dest(7 downto 8-CHAN_SIZE_C));
714  dmaRdReq.dest(7 downto 8-CHAN_SIZE_C) := (others=>'0');
715  else
716  rdIndex := 0;
717  end if;
718 
719  -- Pull next entry if we are not waiting for ack on given channel
720  if r.rdFifoRd = '0' and dmaRdReq.valid = '1' and v.dmaRdDescReq(rdIndex).valid = '0' then
721  v.dmaRdDescReq(rdIndex) := dmaRdReq;
722  v.rdFifoRd := '1';
723  end if;
724 
725  --------------------------------------
726  if r.enable = '0' then
727  v.wrIndex := (others=>'0');
728  v.rdIndex := (others=>'0');
729  end if;
730 
731  -- Reset
732  if (axiRst = '1') then
733  v := REG_INIT_C;
734  end if;
735 
736  -- Register the variable for next clock cycle
737  rin <= v;
738 
739  -- Outputs
740  intReadSlaves(LOC_INDEX_C) <= r.axilReadSlave;
741  intWriteSlaves(LOC_INDEX_C) <= r.axilWriteSlave;
742 
743  online <= r.online;
744  interrupt <= r.interrupt;
751  axiCache <= r.buffCache;
752 
753  end process comb;
754 
755  seq : process (axiClk) is
756  begin
757  if (rising_edge(axiClk)) then
758  r <= rin after TPD_G;
759  end if;
760  end process seq;
761 
762 end rtl;
763 
in dinslv( DATA_WIDTH_G- 1 downto 0)
Definition: Fifo.vhd:52
slv( 63 downto 0) address
Definition: AxiDmaPkg.vhd:49
in mAxiWriteSlavesAxiLiteWriteSlaveArray( NUM_MASTER_SLOTS_G- 1 downto 0)
out dmaRdDescReqAxiReadDmaDescReqArray( CHAN_COUNT_G- 1 downto 0)
out dmaRdDescRetAckslv( CHAN_COUNT_G- 1 downto 0)
slv( 15 downto 0) connectivity
Definition: AxiLitePkg.vhd:199
AxiCtrlType
Definition: AxiPkg.vhd:198
AXI_CONFIG_GAxiConfigType := AXI_CONFIG_INIT_C
slv( 7 downto 0) dest
Definition: AxiDmaPkg.vhd:78
in addrslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
out dmaWrDescRetAckslv( CHAN_COUNT_G- 1 downto 0)
array(natural range <> ) of AxiWriteDmaDescReqType AxiWriteDmaDescReqArray
Definition: AxiDmaPkg.vhd:168
array(natural range <> ) of AxiLiteWriteSlaveType AxiLiteWriteSlaveArray
Definition: AxiLitePkg.vhd:164
sl wvalid
Definition: AxiPkg.vhd:124
array(natural range <> ) of AxiReadDmaDescRetType AxiReadDmaDescRetArray
Definition: AxiDmaPkg.vhd:336
in mAxiReadSlavesAxiLiteReadSlaveArray( NUM_MASTER_SLOTS_G- 1 downto 0)
sl bvalid
Definition: AxiPkg.vhd:178
slv( 7 downto 0) firstUser
Definition: AxiDmaPkg.vhd:76
_library_ ieeeieee
TPD_Gtime := 1 ns
array(natural range <> ) of AxiReadDmaDescReqType AxiReadDmaDescReqArray
Definition: AxiDmaPkg.vhd:312
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
NUM_SLAVE_SLOTS_Gnatural range 1 to 16:= 4
array(natural range <> ) of AxiWriteDmaDescAckType AxiWriteDmaDescAckArray
Definition: AxiDmaPkg.vhd:200
sl wlast
Definition: AxiPkg.vhd:123
FWFT_EN_Gboolean := false
Definition: Fifo.vhd:33
slv( 1023 downto 0) wdata
Definition: AxiPkg.vhd:122
slv( 7 downto 0) awlen
Definition: AxiPkg.vhd:113
in axilWriteMasterAxiLiteWriteMasterType
out dmaWrDescAckAxiWriteDmaDescAckArray( CHAN_COUNT_G- 1 downto 0)
TPD_Gtime := 1 ns
sl awready
Definition: AxiPkg.vhd:173
out doutslv( DATA_WIDTH_G- 1 downto 0)
in axiWriteSlaveAxiWriteSlaveType
CHAN_COUNT_Ginteger range 1 to 16:= 1
array(natural range <> ) of AxiLiteReadMasterType AxiLiteReadMasterArray
Definition: AxiLitePkg.vhd:77
DATA_WIDTH_Ginteger := 32
out acknowledgeslv( CHAN_COUNT_G- 1 downto 0)
slv( 127 downto 0) wstrb
Definition: AxiPkg.vhd:126
AxiCtrlType :=(pause => '0',overflow => '0') AXI_CTRL_UNUSED_C
Definition: AxiPkg.vhd:206
slv( 15 downto 0) buffId
Definition: AxiDmaPkg.vhd:188
slv( 31 downto 0) baseAddr
Definition: AxiLitePkg.vhd:197
in rd_clksl
Definition: Fifo.vhd:61
TPD_Gtime := 1 ns
Definition: Fifo.vhd:28
in dmaWrDescRetAxiWriteDmaDescRetArray( CHAN_COUNT_G- 1 downto 0)
slv( 2 downto 0) result
Definition: AxiDmaPkg.vhd:219
in dmaRdDescRetAxiReadDmaDescRetArray( CHAN_COUNT_G- 1 downto 0)
array(natural range <> ) of AxiWriteDmaDescRetType AxiWriteDmaDescRetArray
Definition: AxiDmaPkg.vhd:236
AxiLiteStatusType axiStatus
Definition: AxiLitePkg.vhd:183
AxiWriteMasterType
Definition: AxiPkg.vhd:108
slv( 7 downto 0) lastUser
Definition: AxiDmaPkg.vhd:77
array(natural range <> ) of AxiLiteCrossbarMasterConfigType AxiLiteCrossbarMasterConfigArray
Definition: AxiLitePkg.vhd:202
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
Definition: Fifo.vhd:41
in wr_clksl
Definition: Fifo.vhd:50
MASTERS_CONFIG_GAxiLiteCrossbarMasterConfigArray := AXIL_XBAR_CFG_DEFAULT_C
sl wready
Definition: AxiPkg.vhd:175
DEC_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_DECERR_C
out axiReadSlaveAxiLiteReadSlaveType
in clksl := '0'
in axiWriteMasterAxiLiteWriteMasterType
natural addrBits
Definition: AxiLitePkg.vhd:198
COMMON_CLK_Gboolean := false
AxiReadDmaDescReqType :=(valid => '0',address =>( others => '0'),buffId =>( others => '0'),firstUser =>( others => '0'),lastUser =>( others => '0'),size =>( others => '0'),continue => '0',id =>( others => '0'),dest =>( others => '0')) AXI_READ_DMA_DESC_REQ_INIT_C
Definition: AxiDmaPkg.vhd:300
sl awvalid
Definition: AxiPkg.vhd:110
out validsl
Definition: Fifo.vhd:65
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
in axilReadMasterAxiLiteReadMasterType
in rd_ensl := '0'
Definition: Fifo.vhd:62
out axilReadSlaveAxiLiteReadSlaveType
out mAxiReadMastersAxiLiteReadMasterArray( NUM_MASTER_SLOTS_G- 1 downto 0)
sl pause
Definition: AxiPkg.vhd:199
AxiConfigType
Definition: AxiPkg.vhd:213
DESC_AWIDTH_Ginteger range 4 to 12:= 12
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:95
in dmaRdDescAckslv( CHAN_COUNT_G- 1 downto 0)
AxiWriteSlaveType
Definition: AxiPkg.vhd:171
GEN_SYNC_FIFO_Gboolean := false
Definition: Fifo.vhd:31
NUM_MASTER_SLOTS_Gnatural range 1 to 64:= 4
out axiCacheslv( 3 downto 0)
AxiReadDmaDescReqType
Definition: AxiDmaPkg.vhd:288
in dmaWrDescReqAxiWriteDmaDescReqArray( CHAN_COUNT_G- 1 downto 0)
out axilWriteSlaveAxiLiteWriteSlaveType
slv( 3 downto 0) awcache
Definition: AxiPkg.vhd:118
AxiWriteDmaDescAckType :=(valid => '0',address =>( others => '0'),dropEn => '0',maxSize =>( others => '0'),contEn => '0',buffId =>( others => '0')) AXI_WRITE_DMA_DESC_ACK_INIT_C
Definition: AxiDmaPkg.vhd:191
slv( 63 downto 0) awaddr
Definition: AxiPkg.vhd:111
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
out doutslv( DATA_WIDTH_G- 1 downto 0)
Definition: Fifo.vhd:63
in rstsl :=not RST_POLARITY_G
Definition: Fifo.vhd:48
array(natural range <> ) of AxiLiteWriteMasterType AxiLiteWriteMasterArray
Definition: AxiLitePkg.vhd:136
in rstsl := '0'
in axiWriteCtrlAxiCtrlType := AXI_CTRL_UNUSED_C
AXIL_BASE_ADDR_Gslv( 31 downto 0) := x"00000000"
slv( 31 downto 0) size
Definition: AxiDmaPkg.vhd:72
in axiReadMasterAxiLiteReadMasterType
slv( 31 downto 0) maxSize
Definition: AxiDmaPkg.vhd:50
out axiWriteSlaveAxiLiteWriteSlaveType
ADDR_WIDTH_Ginteger range 4 to 48:= 4
Definition: Fifo.vhd:42
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
AXI_READY_EN_Gboolean := false
BRAM_EN_Gboolean := false
array(natural range <> ) of AxiLiteReadSlaveType AxiLiteReadSlaveArray
Definition: AxiLitePkg.vhd:103
out mAxiWriteMastersAxiLiteWriteMasterArray( NUM_MASTER_SLOTS_G- 1 downto 0)
ADDR_WIDTH_Ginteger range 1 to ( 2** 24):= 5
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_OK_C
REG_EN_Gboolean := true
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
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:156
ACK_WAIT_BVALID_Gboolean := true
Definition: Fifo.vhd:26
out onlineslv( CHAN_COUNT_G- 1 downto 0)
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
out axiWriteMasterAxiWriteMasterType
in wr_ensl := '0'
Definition: Fifo.vhd:51