SURF  1.0
AxiLitePkg.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiLitePkg.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2013-04-02
5 -- Last update: 2017-05-09
6 -------------------------------------------------------------------------------
7 -- Description: AXI-Lite Package File
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.NUMERIC_STD.all;
21 use work.StdRtlPkg.all;
22 use work.TextUtilPkg.all;
23 
24 package AxiLitePkg is
25 --! @file
26  --! @ingroup axi
27 
28  -------------------------------------------------------------------------------------------------
29  -- AXI bus response codes
30  -------------------------------------------------------------------------------------------------
31  constant AXI_RESP_OK_C : slv(1 downto 0) := "00"; -- Access ok
32 
33  constant AXI_RESP_EXOKAY_C : slv(1 downto 0) := "01"; -- Exclusive access ok
34  -- Note: There are no "exclusive access" in AXI-Lite. This is just a placeholder constant.
35 
36  constant AXI_RESP_SLVERR_C : slv(1 downto 0) := "10"; -- Slave Error
37  -- Note: A SLVERR response is returned to the master if the AXI peripheral interface receives any
38  -- of the following unsupported accesses:
39  --
40  -- 1) Any accesses with AWSIZE information other than 32-bit receives a SLVERR response.
41  -- 2) Any accesses with AWLEN information other than zero receives a SLVERR response.
42  -- 3) Any access that is unaligned, for example, where AWADDRP[1:0] is not equal to 2'b00,
43  -- returns a SLVERR response where a read access returns all zeros and a write access
44  -- does not modify the address location.
45  -- 4) Any write access that attempts to make use of the WSTRB lines,
46  -- for example where any bits of WSTRB[3:0] are 0, returns a SLVERR response
47  -- and does not modify the address location.
48 
49  constant AXI_RESP_DECERR_C : slv(1 downto 0) := "11"; -- Decode Error
50  -- Note: Any transaction that does not decode to a legal master interface destination,
51  -- or programmers view register, receives a DECERR response. For an AHB master,
52  -- the AXI DECERR is mapped back to an AHB ERROR.
53 
54  --------------------------------------------------------
55  -- AXI bus, read master signal record
56  --------------------------------------------------------
57 
58  -- Base Record
59  type AxiLiteReadMasterType is record
60  -- Read Address channel
61  araddr : slv(31 downto 0);
62  arprot : slv(2 downto 0);
64  -- Read data channel
66  end record;
67 
68  -- Initialization constants
70  araddr => (others => '0'),
71  arprot => (others => '0'),
72  arvalid => '0',
73  rready => '1'
74  );
75 
76  -- Array
77  type AxiLiteReadMasterArray is array (natural range<>) of AxiLiteReadMasterType;
78 
79 
80  --------------------------------------------------------
81  -- AXI bus, read slave signal record
82  --------------------------------------------------------
83 
84  -- Base Record
85  type AxiLiteReadSlaveType is record
86  -- Read Address channel
88  -- Read data channel
89  rdata : slv(31 downto 0);
90  rresp : slv(1 downto 0);
92  end record;
93 
94  -- Initialization constants
96  arready => '0',
97  rdata => (others => '0'),
98  rresp => (others => '0'),
99  rvalid => '0'
100  );
101 
102  -- Array
103  type AxiLiteReadSlaveArray is array (natural range<>) of AxiLiteReadSlaveType;
104 
105 
106  --------------------------------------------------------
107  -- AXI bus, write master signal record
108  --------------------------------------------------------
109 
110  -- Base Record
111  type AxiLiteWriteMasterType is record
112  -- Write address channel
113  awaddr : slv(31 downto 0);
114  awprot : slv(2 downto 0);
116  -- Write data channel
117  wdata : slv(31 downto 0);
118  wstrb : slv(3 downto 0);
120  -- Write ack channel
122  end record;
123 
124  -- Initialization constants
126  awaddr => (others => '0'),
127  awprot => (others => '0'),
128  awvalid => '0',
129  wdata => (others => '0'),
130  wstrb => (others => '1'),
131  wvalid => '0',
132  bready => '1'
133  );
134 
135  -- Array
136  type AxiLiteWriteMasterArray is array (natural range<>) of AxiLiteWriteMasterType;
137 
138 
139  --------------------------------------------------------
140  -- AXI bus, write slave signal record
141  --------------------------------------------------------
142 
143  -- Base Record
144  type AxiLiteWriteSlaveType is record
145  -- Write address channel
147  -- Write data channel
149  -- Write ack channel
150  bresp : slv(1 downto 0);
152 
153  end record;
154 
155  -- Initialization constants
157  awready => '0',
158  wready => '0',
159  bresp => (others => '0'),
160  bvalid => '0'
161  );
162 
163  -- Array
164  type AxiLiteWriteSlaveArray is array (natural range<>) of AxiLiteWriteSlaveType;
165 
166  type AxiLiteStatusType is record
169  end record AxiLiteStatusType;
170 
172  writeEnable => '0',
173  readEnable => '0');
174 
175  --------------------------------------------------------
176  -- AXI bus, read/write endpoint record, RTH 1/27/2016
177  --------------------------------------------------------
178  type AxiLiteEndpointType is record
184  end record AxiLiteEndpointType;
185 
192 
193  -------------------------------------------------------------------------------------------------
194  -- Crossbar Config Generic Types
195  -------------------------------------------------------------------------------------------------
197  baseAddr : slv(31 downto 0);
198  addrBits : natural;
199  connectivity : slv(15 downto 0);
200  end record;
201 
203 
205  0 => (baseAddr => X"00000000",
206  addrBits => 16,
207  connectivity => X"FFFF"),
208  1 => (baseAddr => X"00010000",
209  addrBits => 16,
210  connectivity => X"FFFF"),
211  2 => (baseAddr => X"00020000",
212  addrBits => 16,
213  connectivity => X"FFFF"),
214  3 => (baseAddr => X"00030000",
215  addrBits => 16,
216  connectivity => X"FFFF"));
217 
218  -------------------------------------------------------------------------------------------------
219  -- Initilize masters with uppder address bits already set to configuration base address
220  -------------------------------------------------------------------------------------------------
225 
226 
227  -------------------------------------------------------------------------------------------------
228  -- Slave AXI Processing procedures
229  -------------------------------------------------------------------------------------------------
230 
233  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
234  variable writeEnable : inout sl);
235 
238  variable axiReadSlave : inout AxiLiteReadSlaveType;
239  variable readEnable : inout sl);
240 
241  procedure axiSlaveWaitTxn (
244  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
245  variable axiReadSlave : inout AxiLiteReadSlaveType;
246  variable axiStatus : inout AxiLiteStatusType);
247 
249  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
250  axiResp : in slv(1 downto 0) := AXI_RESP_OK_C);
251 
253  variable axiReadSlave : inout AxiLiteReadSlaveType;
254  axiResp : in slv(1 downto 0) := AXI_RESP_OK_C);
255 
256  -------------------------------------------------------------------------------------------------
257  -- Address decode procedures
258  -------------------------------------------------------------------------------------------------
259 "0" procedure axiSlaveRegister (
262  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
263  variable axiReadSlave : inout AxiLiteReadSlaveType;
264  variable axiStatus : in AxiLiteStatusType;
265  addr : in slv;
266  offset : in integer;
267  reg : inout slv;
268  constAssign : in boolean := false;
269  constVal : in slv := );
270 
271  procedure axiSlaveRegister (
273  variable axiReadSlave : inout AxiLiteReadSlaveType;
274  variable axiStatus : in AxiLiteStatusType;
275  addr : in slv;
276  offset : in integer;
277  reg : in slv);
278 
279  procedure axiSlaveRegister (
282  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
283  variable axiReadSlave : inout AxiLiteReadSlaveType;
284  variable axiStatus : in AxiLiteStatusType;
285  addr : in slv;
286  offset : in integer;
287  reg : inout sl;
288  constAssign : in boolean := false;
289  constVal : in sl := '0');
290 
291  procedure axiSlaveRegister (
293  variable axiReadSlave : inout AxiLiteReadSlaveType;
294  variable axiStatus : in AxiLiteStatusType;
295  addr : in slv;
296  offset : in integer;
297  reg : in sl);
298 
299  procedure axiSlaveDefault (
302  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
303  variable axiReadSlave : inout AxiLiteReadSlaveType;
304  variable axiStatus : in AxiLiteStatusType;
305  axiResp : in slv(1 downto 0) := AXI_RESP_OK_C;
306  extTxn : in sl := '0');
307 
308 
309  -------------------------------------------------------------------------------------------------
310  -- Simplified Address decode procedures, RTH 1/27/2016
311  -------------------------------------------------------------------------------------------------
312  procedure axiSlaveWaitTxn (
313  variable ep : inout AxiLiteEndpointType;
316  variable axiWriteSlave : in AxiLiteWriteSlaveType;
317  variable axiReadSlave : in AxiLiteReadSlaveType);
318 
319 "X" procedure axiSlaveRegister (
320  variable ep : inout AxiLiteEndpointType;
321  addr : in slv;
322  offset : in integer;
323  reg : inout slv;
324  constVal : in slv := );
325 
326  procedure axiSlaveRegisterR (
327  variable ep : inout AxiLiteEndpointType;
328  addr : in slv;
329  offset : in integer;
330  reg : in slv);
331 
332  procedure axiSlaveRegister (
333  variable ep : inout AxiLiteEndpointType;
334  addr : in slv;
335  offset : in integer;
336  reg : inout sl;
337  constVal : in sl := 'X');
338 
339  procedure axiSlaveRegisterR (
340  variable ep : inout AxiLiteEndpointType;
341  addr : in slv;
342  offset : in integer;
343  reg : in sl);
344 
345  procedure axiSlaveRegister (
346  variable ep : inout AxiLiteEndpointType;
347  addr : in slv;
348  regs : inout slv32Array);
349 
350  procedure axiSlaveRegisterR (
351  variable ep : inout AxiLiteEndpointType;
352  addr : in slv;
353  regs : in slv32Array);
354 
355  procedure axiSlaveDefault (
356  variable ep : inout AxiLiteEndpointType;
357  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
358  variable axiReadSlave : inout AxiLiteReadSlaveType;
359  axiResp : in slv(1 downto 0) := AXI_RESP_OK_C;
360  extTxn : in sl := '0');
361 
362 
363  -------------------------------------------------------------------------------------------------
364  -- Slave AXI Processing functions
365  -------------------------------------------------------------------------------------------------
366 
367  -- Generate evenly distributed address map
368  function genAxiLiteConfig (num : positive;
369  base : slv(31 downto 0);
370  baseBot : integer range 0 to 32;
371  addrBits : integer range 0 to 32)
373 
374 
375  -------------------------------------------------------------------------------------------------
376  -- Simulation procedures
377  -------------------------------------------------------------------------------------------------
378  procedure axiLiteBusSimWrite (
379  signal axilClk : in sl;
380  signal axilWriteMaster : out AxiLiteWriteMasterType;
381  signal axilWriteSlave : in AxiLiteWriteSlaveType;
382  addr : in slv(31 downto 0);
383  data : in slv;
384  debug : in boolean := false);
385 
386  procedure axiLiteBusSimRead (
387  signal axilClk : in sl;
388  signal axilReadMaster : out AxiLiteReadMasterType;
389  signal axilReadSlave : in AxiLiteReadSlaveType;
390  addr : in slv(31 downto 0);
391  data : out slv;
392  debug : in boolean := false);
393 
395  function ite(i : boolean; t : AxiLiteReadSlaveType; e : AxiLiteReadSlaveType) return AxiLiteReadSlaveType;
398 
399 end AxiLitePkg;
400 
401 package body AxiLitePkg is
402 
404  variable ret : AxiLiteReadMasterType;
405  begin
407  ret.araddr := config.baseAddr;
408  return ret;
409  end function axiReadMasterInit;
410 
412  variable ret : AxiLiteReadMasterArray(config'range);
413  begin
414  for i in config'range loop
415  ret(i) := axiReadMasterInit(config(i));
416  end loop;
417  return ret;
418  end function axiReadMasterInit;
419 
421  variable ret : AxiLiteWriteMasterType;
422  begin
424  ret.awaddr := config.baseAddr;
425  return ret;
426  end function axiWriteMasterInit;
427 
429  variable ret : AxiLiteWriteMasterArray(config'range);
430  begin
431  for i in config'range loop
432  ret(i) := axiWriteMasterInit(config(i));
433  end loop;
434  return ret;
435  end function axiWriteMasterInit;
436 
439  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
440  variable writeEnable : inout sl) is
441  begin
442  ----------------------------------------------------------------------------------------------
443  -- AXI Write Logic
444  ----------------------------------------------------------------------------------------------
445  writeEnable := '0';
446 
447  axiWriteSlave.awready := '0';
448  axiWriteSlave.wready := '0';
449 
450  -- Incomming Write txn and last txn has concluded
451  if (axiWriteMaster.awvalid = '1' and axiWriteMaster.wvalid = '1' and axiWriteSlave.bvalid = '0') then
452  writeEnable := '1';
453  end if;
454 
455  -- Reset resp valid
456  if (axiWriteMaster.bready = '1') then
457  axiWriteSlave.bvalid := '0';
458  end if;
459  end procedure;
460 
463  variable axiReadSlave : inout AxiLiteReadSlaveType;
464  variable readEnable : inout sl) is
465  begin
466  ----------------------------------------------------------------------------------------------
467  -- AXI Read Logic
468  ----------------------------------------------------------------------------------------------
469  readEnable := '0';
470 
471  axiReadSlave.arready := '0';
472 
473  -- Incomming read txn and last txn has concluded
474  if (axiReadMaster.arvalid = '1' and axiReadSlave.rvalid = '0') then
475  readEnable := '1';
476  end if;
477 
478  -- Reset rvalid upon rready
479  if (axiReadMaster.rready = '1') then
480  axiReadSlave.rvalid := '0';
481  end if;
482  end procedure axiSlaveWaitReadTxn;
483 
484  procedure axiSlaveWaitTxn (
487  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
488  variable axiReadSlave : inout AxiLiteReadSlaveType;
489  variable axiStatus : inout AxiLiteStatusType) is
490  begin
491  axiSlaveWaitWriteTxn(axiWriteMaster, axiWriteSlave, axiStatus.writeEnable);
492  axiSlaveWaitReadTxn(axiReadMaster, axiReadSlave, axiStatus.readEnable);
493  end procedure;
494 
496  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
497  axiResp : in slv(1 downto 0) := AXI_RESP_OK_C) is
498  begin
499  axiWriteSlave.awready := '1';
500  axiWriteSlave.wready := '1';
501  axiWriteSlave.bvalid := '1';
502  axiWriteSlave.bresp := axiResp;
503  end procedure;
504 
506  variable axiReadSlave : inout AxiLiteReadSlaveType;
507  axiResp : in slv(1 downto 0) := AXI_RESP_OK_C) is
508  begin
509  axiReadSlave.arready := '1'; -- not sure this is necessary
510  axiReadSlave.rvalid := '1';
511  axiReadSlave.rresp := axiResp;
512  end procedure;
513 
514  -------------------------------------------------------------------------------------------------
515  -- Procedures for simplified address decoding
516  -------------------------------------------------------------------------------------------------
517 "0" procedure axiSlaveRegister (
520  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
521  variable axiReadSlave : inout AxiLiteReadSlaveType;
522  variable axiStatus : in AxiLiteStatusType;
523  addr : in slv;
524  offset : in integer;
525  reg : inout slv;
526  constAssign : in boolean := false;
527  constVal : in slv := ) is
528  begin
529  -- Read must come first so as not to overwrite the variable if read and write happen at once
530  if (axiStatus.readEnable = '1') then
531  if (std_match(axiReadMaster.araddr(addr'length-1 downto 0), addr)) then
532  axiReadSlave.rdata(offset+reg'length-1 downto offset) := reg;
533  axiSlaveReadResponse(axiReadSlave);
534  end if;
535  end if;
536 
537  if (axiStatus.writeEnable = '1') then
538  if (std_match(axiWriteMaster.awaddr(addr'length-1 downto 0), addr)) then
539  if (constAssign) then
540  reg := constVal;
541  else
542  reg := axiWriteMaster.wdata(offset+reg'length-1 downto offset);
543  end if;
544  axiSlaveWriteResponse(axiWriteSlave);
545  end if;
546  end if;
547 
548  end procedure;
549 
550  procedure axiSlaveRegister (
552  variable axiReadSlave : inout AxiLiteReadSlaveType;
553  variable axiStatus : in AxiLiteStatusType;
554  addr : in slv;
555  offset : in integer;
556  reg : in slv) is
557  begin
558  if (axiStatus.readEnable = '1') then
559  if (std_match(axiReadMaster.araddr(addr'length-1 downto 0), addr)) then
560  axiReadSlave.rdata(offset+reg'length-1 downto offset) := reg;
561  axiSlaveReadResponse(axiReadSlave);
562  end if;
563  end if;
564  end procedure;
565 
566  procedure axiSlaveRegister (
569  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
570  variable axiReadSlave : inout AxiLiteReadSlaveType;
571  variable axiStatus : in AxiLiteStatusType;
572  addr : in slv;
573  offset : in integer;
574  reg : inout sl;
575  constAssign : in boolean := false;
576  constVal : in sl := '0')
577  is
578  variable tmpReg : slv(0 downto 0);
579  variable tmpVal : slv(0 downto 0);
580  begin
581  tmpReg(0) := reg;
582  tmpVal(0) := constVal;
583  axiSlaveRegister(axiWriteMaster, axiReadMaster, axiWriteSlave, axiReadSlave, axiStatus, addr, offset, tmpReg, constAssign, tmpVal);
584  reg := tmpReg(0);
585  end procedure;
586 
587  procedure axiSlaveRegister (
589  variable axiReadSlave : inout AxiLiteReadSlaveType;
590  variable axiStatus : in AxiLiteStatusType;
591  addr : in slv;
592  offset : in integer;
593  reg : in sl)
594  is
595  variable tmp : slv(0 downto 0);
596  begin
597  tmp(0) := reg;
598  axiSlaveRegister(axiReadMaster, axiReadSlave, axiStatus, addr, offset, tmp);
599  end procedure;
600 
601  procedure axiSlaveDefault (
604  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
605  variable axiReadSlave : inout AxiLiteReadSlaveType;
606  variable axiStatus : in AxiLiteStatusType;
607  axiResp : in slv(1 downto 0) := AXI_RESP_OK_C;
608  extTxn : in sl := '0') is
609  begin
610  if (axiStatus.writeEnable = '1' and axiWriteSlave.awready = '0' and extTxn = '0') then
611  axiSlaveWriteResponse(axiWriteSlave, axiResp);
612  end if;
613 
614  if (axiStatus.readEnable = '1' and axiReadSlave.arready = '0' and extTxn = '0') then
615  axiSlaveReadResponse(axiReadSlave, axiResp);
616  end if;
617  end procedure;
618 
619  -------------------------------------------------------------------------------------------------
620  -- Simplified Address decode procedures, RTH 1/27/2016
621  -------------------------------------------------------------------------------------------------
622  procedure axiSlaveWaitTxn (
623  variable ep : inout AxiLiteEndpointType;
626  variable axiWriteSlave : in AxiLiteWriteSlaveType;
627  variable axiReadSlave : in AxiLiteReadSlaveType) is
628  begin
630 
635 
636  axiSlaveWaitTxn(axiWriteMaster, axiReadMaster,
638  ep.axiStatus);
639  end procedure;
640 
641 
642 
643 
644 "X" procedure axiSlaveRegister (
645  variable ep : inout AxiLiteEndpointType;
646  addr : in slv;
647  offset : in integer;
648  reg : inout slv;
649  constVal : in slv := )
650  is
651  -- Need to remap addr range to be (length-1 downto 0)
652  constant ADDR_LEN_C : integer := addr'length;
653  constant ADDR_C : slv(ADDR_LEN_C-1 downto 0) := addr;
654  -- Offset as measured from addr[1:0]="00"
655  constant ABS_OFFSET_C : integer := offset + (to_integer(unsigned(ADDR_C(1 downto 0)))*8);
656  -- Normalized address and offset (for when addr[1:0]!=00)
657  constant NORMAL_ADDR_C : slv(ADDR_LEN_C-1 downto 0) := ite(ABS_OFFSET_C /= 0,
658  slv((unsigned(slv(ADDR_C))) + ((ABS_OFFSET_C/32)*4)),
659  ADDR_C);
660  constant NORMAL_OFFSET_C : integer := ABS_OFFSET_C mod 32;
661  -- Most significant register bit before wrapping to the next word address
662  constant REG_HIGH_BIT_C : integer := minimum(31-NORMAL_OFFSET_C+reg'low, reg'high);
663  -- Most significant data bus bit to be used in this recursion (max out at 31)
664  constant BUS_HIGH_BIT_C : integer := minimum(NORMAL_OFFSET_C+reg'length-1, 31);
665 
666  variable strobeMask : slv(3 downto 0) := (others => '-');
667  begin
668 
669  for i in BUS_HIGH_BIT_C downto NORMAL_OFFSET_C loop
670  strobeMask(i/8) := '1';
671  end loop;
672 
673  -- Read must come first so as not to overwrite the variable if read and write happen at once
674  if (ep.axiStatus.readEnable = '1') then
675  if (std_match(ep.axiReadMaster.araddr(ADDR_LEN_C-1 downto 2), NORMAL_ADDR_C(ADDR_LEN_C-1 downto 2))) then
676  ep.axiReadSlave.rdata(BUS_HIGH_BIT_C downto NORMAL_OFFSET_C) := reg(REG_HIGH_BIT_C downto reg'low);
677  axiSlaveReadResponse(ep.axiReadSlave);
678  end if;
679  end if;
680 
681  if (ep.axiStatus.writeEnable = '1') then
682  if (std_match(ep.axiWriteMaster.awaddr(ADDR_LEN_C-1 downto 2), NORMAL_ADDR_C(ADDR_LEN_C-1 downto 2)) and
683  std_match(ep.axiWriteMaster.wstrb, strobeMask)) then
684  if (constVal /= "X") then
685  reg(REG_HIGH_BIT_C downto reg'low) := constVal;
686  else
687  reg(REG_HIGH_BIT_C downto reg'low) := ep.axiWriteMaster.wdata(BUS_HIGH_BIT_C downto NORMAL_OFFSET_C);
688  end if;
689  axiSlaveWriteResponse(ep.axiWriteSlave);
690  end if;
691  end if;
692 
693  if (REG_HIGH_BIT_C < reg'high) then
694  axiSlaveRegister(ep, slv(unsigned(NORMAL_ADDR_C)+4), 0, reg(reg'high downto REG_HIGH_BIT_C+1), "X");
695  end if;
696 
697  end procedure;
698 
699  procedure axiSlaveRegisterR (
700  variable ep : inout AxiLiteEndpointType;
701  addr : in slv;
702  offset : in integer;
703  reg : in slv)
704  is
705  variable regTmp : slv(reg'length-1 downto 0);
706  begin
707  regTmp := reg;
708  axiSlaveRegister(ep, addr, offset, regTmp, "X");
709  end procedure;
710 
711  procedure axiSlaveRegister (
712  variable ep : inout AxiLiteEndpointType;
713  addr : in slv;
714  offset : in integer;
715  reg : inout sl;
716  constVal : in sl := 'X')
717  is
718  variable tmpReg : slv(0 downto 0);
719  variable tmpVal : slv(0 downto 0);
720  begin
721  tmpReg(0) := reg;
722  tmpVal(0) := constVal;
723  axiSlaveRegister(ep, addr, offset, tmpReg, tmpVal);
724  reg := tmpReg(0);
725  end procedure;
726 
727  procedure axiSlaveRegisterR (
728  variable ep : inout AxiLiteEndpointType;
729  addr : in slv;
730  offset : in integer;
731  reg : in sl)
732  is
733  variable tmp : slv(0 downto 0);
734  begin
735  tmp(0) := reg;
736  axiSlaveRegisterR(ep, addr, offset, tmp);
737  end procedure;
738 
739  procedure axiSlaveRegister (
740  variable ep : inout AxiLiteEndpointType;
741  addr : in slv;
742  regs : inout slv32Array)
743  is
744  begin
745  for i in regs'range loop
746  axiSlaveRegister(ep, slv(unsigned(addr) + to_unsigned(i*4, addr'length)), 0, regs(i));
747  end loop;
748 
749  end procedure;
750 
751  procedure axiSlaveRegisterR (
752  variable ep : inout AxiLiteEndpointType;
753  addr : in slv;
754  regs : in slv32Array)
755  is
756  constant ADDR_BITS_C : integer := log2(regs'length);
757  variable addrLocal : slv(addr'length-1 downto 0) := addr;
758  variable tmp : slv(31 downto 0);
759  begin
760  -- Select regs word based on araddr
761  tmp := regs(to_integer(unsigned(ep.axiReadMaster.araddr(ADDR_BITS_C+2-1 downto 2))));
762 
763  addrLocal := addr;
764  addrLocal(ADDR_BITS_C+2-1 downto 2) := (others => '-');
765  addrLocal(1 downto 0) := "00";
766 -- print("MULTI! - Addr: " & hstr(addrLocal));
767  axiSlaveRegister(ep, addrLocal, 0, tmp);
768  end procedure;
769 
770  procedure axiSlaveDefault (
771  variable ep : inout AxiLiteEndpointType;
772  variable axiWriteSlave : inout AxiLiteWriteSlaveType;
773  variable axiReadSlave : inout AxiLiteReadSlaveType;
774  axiResp : in slv(1 downto 0) := AXI_RESP_OK_C;
775  extTxn : in sl := '0') is
776  begin
777  if (ep.axiStatus.writeEnable = '1' and ep.axiWriteSlave.awready = '0' and extTxn = '0') then
778  axiSlaveWriteResponse(ep.axiWriteSlave, axiResp);
779  end if;
780 
781  if (ep.axiStatus.readEnable = '1' and ep.axiReadSlave.arready = '0' and extTxn = '0') then
782  axiSlaveReadResponse(ep.axiReadSlave, axiResp);
783  end if;
786  end procedure;
787 
788 
789  -------------------------------------------------------------------------------------------------
790  -- Slave AXI Processing functions
791  -------------------------------------------------------------------------------------------------
792 
793  -- Generate evenly distributed address map
794  function genAxiLiteConfig (num : positive;
795  base : slv(31 downto 0);
796  baseBot : integer range 0 to 32;
797  addrBits : integer range 0 to 32)
799  variable retConf : AxiLiteCrossbarMasterConfigArray(num-1 downto 0);
800  variable addr : slv(31 downto 0);
801  begin
802 
803  -- Init
804  addr := base;
805  addr(baseBot-1 downto 0) := (others => '0');
806 
807  -- Generate records
808  for i in 0 to num-1 loop
809  addr(baseBot-1 downto addrBits) := toSlv(i, baseBot-addrBits);
810  retConf(i).baseAddr := addr;
811  retConf(i).addrBits := addrBits;
812  retConf(i).connectivity := x"FFFF";
813  end loop;
814 
815  return retConf;
816  end function;
817 
818 
819  -------------------------------------------------------------------------------------------------
820  -- Simulation procedures
821  -------------------------------------------------------------------------------------------------
822 
823  procedure axiLiteBusSimWrite (
824  signal axilClk : in sl;
825  signal axilWriteMaster : out AxiLiteWriteMasterType;
826  signal axilWriteSlave : in AxiLiteWriteSlaveType;
827  addr : in slv(31 downto 0);
828  data : in slv;
829  debug : in boolean := false)
830  is
831  variable dataTmp : slv(31 downto 0);
832  variable addrTmp : slv(31 downto 0);
833  begin
834  dataTmp := resize(data, 32);
835 
836  wait until axilClk = '1';
837  axilWriteMaster.awaddr <= addr;
838  axilWriteMaster.wdata <= dataTmp;
839  axilWriteMaster.awprot <= (others => '0');
840  axilWriteMaster.wstrb <= (others => '1');
841  axilWriteMaster.awvalid <= '1';
842  axilWriteMaster.wvalid <= '1';
843  axilWriteMaster.bready <= '1';
844 
845 
846  wait until axilClk = '1';
847  -- Wait for a response
848  while (axilWriteSlave.bvalid = '0') loop
849  -- Clear control signals when acked
850  if axilWriteSlave.awready = '1' then
851  axilWriteMaster.awvalid <= '0';
852  end if;
853  if axilWriteSlave.wready = '1' then
854  axilWriteMaster.wvalid <= '0';
855  end if;
856 
857  wait until axilClk = '1';
858  end loop;
859 
860  -- Clear control signals if bvalid and ready arrive at the same time
861  if axilWriteSlave.awready = '1' then
862  axilWriteMaster.awvalid <= '0';
863  end if;
864  if axilWriteSlave.wready = '1' then
865  axilWriteMaster.wvalid <= '0';
866  end if;
867 
868  -- Done. Check for errors
869  axilWriteMaster.bready <= '0';
870 
871  print(debug, "AxiLitePkg::axiLiteBusSimWrite(addr:" & hstr(addr) & ", data: " & hstr(dataTmp) & ")");
872  if (axilWriteSlave.bresp = AXI_RESP_SLVERR_C) then
873  report "AxiLitePkg::axiLiteBusSimWrite(): - BRESP = SLAVE_ERROR" severity warning;
874  elsif (axilWriteSlave.bresp = AXI_RESP_DECERR_C) then
875  report "AxiLitePkg::axiLiteBusSimWrite(): BRESP = DECODE_ERROR" severity warning;
876  end if;
877 
878 
879  -- If data size is greater than 32, make a recursive call to write the next word
880  if (data'length > 32) then
881  addrTmp := slv(unsigned(addr) + 4);
882  axiLiteBusSimWrite(axilClk, axilWriteMaster, axilWriteSlave, addrTmp, data(data'high downto 32), debug);
883  end if;
884 
885  end procedure axiLiteBusSimWrite;
886 
887 
888  procedure axiLiteBusSimRead (
889  signal axilClk : in sl;
890  signal axilReadMaster : out AxiLiteReadMasterType;
891  signal axilReadSlave : in AxiLiteReadSlaveType;
892  addr : in slv(31 downto 0);
893  data : out slv;
894  debug : in boolean := false)
895  is
896  variable dataTmp : slv(31 downto 0);
897  variable addrTmp : slv(31 downto 0);
898  begin
899  -- Put the write req on the bus
900  wait until axilClk = '1';
901  axilReadMaster.araddr <= addr;
902  axilReadMaster.arprot <= (others => '0');
903  axilReadMaster.arvalid <= '1';
904  axilReadMaster.rready <= '1';
905 
906  wait until axilClk = '1';
907  -- Wait for a response
908  while (axilReadSlave.rvalid = '0') loop
909  -- Clear control signals when acked
910  if axilReadSlave.arready = '1' then
911  axilReadMaster.arvalid <= '0';
912  end if;
913 
914  wait until axilClk = '1';
915  end loop;
916 
917  -- Clear control signals when acked
918  if axilReadSlave.arready = '1' then
919  axilReadMaster.arvalid <= '0';
920  end if;
921 
922  -- Done. Check for errors
923  if (axilReadSlave.rresp = AXI_RESP_SLVERR_C) then
924  report "AxiLitePkg::axiLiteBusSimRead(): - RRESP = SLAVE_ERROR" severity warning;
925  elsif (axilReadSlave.rresp = AXI_RESP_DECERR_C) then
926  report "AxiLitePkg::axiLiteBusSimRead(): RRESP = DECODE_ERROR" severity warning;
927  else
928  dataTmp := axilReadSlave.rdata;
929  print(debug, "AxiLitePkg::axiLiteBusSimRead( addr:" & hstr(addr) & ", data: " & hstr(axilReadSlave.rdata) & ")");
930  end if;
931  axilReadMaster.rready <= '0';
932 
933  if (data'length > 32) then
934  addrTmp := slv(unsigned(addr) + 4);
935  data(data'low+31 downto data'low) := dataTmp;
936  axiLiteBusSimRead(axilClk, axilReadMaster, axilReadSlave, addrTmp, data(data'high downto 32), debug);
937  else
938  data := resize(dataTmp, data'length);
939  end if;
940 
941 
942  end procedure axiLiteBusSimRead;
943 
944  function ite (i : boolean; t : AxiLiteReadMasterType; e : AxiLiteReadMasterType) return AxiLiteReadMasterType is
945  begin
946  if (i) then return t; else return e; end if;
947  end function ite;
948 
949  function ite (i : boolean; t : AxiLiteReadSlaveType; e : AxiLiteReadSlaveType) return AxiLiteReadSlaveType is
950  begin
951  if (i) then return t; else return e; end if;
952  end function ite;
953 
954  function ite (i : boolean; t : AxiLiteWriteMasterType; e : AxiLiteWriteMasterType) return AxiLiteWriteMasterType is
955  begin
956  if (i) then return t; else return e; end if;
957  end function ite;
958 
959  function ite (i : boolean; t : AxiLiteWriteSlaveType; e : AxiLiteWriteSlaveType) return AxiLiteWriteSlaveType is
960  begin
961  if (i) then return t; else return e; end if;
962  end function ite;
963 
964 
965 end package body AxiLitePkg;
966 
slv( 1 downto 0) := "01" AXI_RESP_EXOKAY_C
Definition: AxiLitePkg.vhd:33
slv( 2 downto 0) arprot
Definition: AxiLitePkg.vhd:62
axiLiteBusSimWriteaxilClk,axilWriteMaster,axilWriteSlave,addr,data,debug,
Definition: AxiLitePkg.vhd:378
AxiLiteCrossbarMasterConfigArray( 0 to 3) :=( 0=>(baseAddr => X"00000000",addrBits => 16,connectivity => X"FFFF"), 1=>(baseAddr => X"00010000",addrBits => 16,connectivity => X"FFFF"), 2=>(baseAddr => X"00020000",addrBits => 16,connectivity => X"FFFF"), 3=>(baseAddr => X"00030000",addrBits => 16,connectivity => X"FFFF")) AXIL_XBAR_CFG_DEFAULT_C
Definition: AxiLitePkg.vhd:204
slv( 15 downto 0) connectivity
Definition: AxiLitePkg.vhd:199
slv( 1 downto 0) rresp
Definition: AxiLitePkg.vhd:90
array(natural range <> ) of AxiLiteWriteSlaveType AxiLiteWriteSlaveArray
Definition: AxiLitePkg.vhd:164
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
array(natural range <> ) of AxiLiteReadMasterType AxiLiteReadMasterArray
Definition: AxiLitePkg.vhd:77
AxiLiteCrossbarMasterConfigArray genAxiLiteConfignum,base,baseBot,addrBits,
Definition: AxiLitePkg.vhd:368
AxiLiteWriteMasterType axiWriteMaster
Definition: AxiLitePkg.vhd:181
slv( 31 downto 0) baseAddr
Definition: AxiLitePkg.vhd:197
AxiLiteWriteMasterArray axiWriteMasterInitconfig,
Definition: AxiLitePkg.vhd:221
AxiLiteStatusType :=(writeEnable => '0',readEnable => '0') AXI_LITE_STATUS_INIT_C
Definition: AxiLitePkg.vhd:171
AxiLiteReadSlaveType axiReadSlave
Definition: AxiLitePkg.vhd:180
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
AxiLiteCrossbarMasterConfigType
Definition: AxiLitePkg.vhd:196
AxiLiteStatusType axiStatus
Definition: AxiLitePkg.vhd:183
array(natural range <> ) of AxiLiteCrossbarMasterConfigType AxiLiteCrossbarMasterConfigArray
Definition: AxiLitePkg.vhd:202
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
Definition: AxiLitePkg.vhd:36
AxiLiteReadMasterType axiReadMaster
Definition: AxiLitePkg.vhd:179
AxiLiteWriteSlaveType axiWriteSlave
Definition: AxiLitePkg.vhd:182
slv( 1 downto 0) := "11" AXI_RESP_DECERR_C
Definition: AxiLitePkg.vhd:49
axiSlaveDefaultaxiWriteMaster,axiReadMaster,axiWriteSlave,axiReadSlave,axiStatus,axiResp,extTxn,
Definition: AxiLitePkg.vhd:299
axiSlaveRegisteraxiWriteMaster,axiReadMaster,axiWriteSlave,axiReadSlave,axiStatus,addr,offset,reg,constAssign,constVal,
Definition: AxiLitePkg.vhd:259
natural addrBits
Definition: AxiLitePkg.vhd:198
AxiLiteEndpointType :=(axiReadMaster => AXI_LITE_READ_MASTER_INIT_C,axiReadSlave => AXI_LITE_READ_SLAVE_INIT_C,axiWriteMaster => AXI_LITE_WRITE_MASTER_INIT_C,axiWriteSlave => AXI_LITE_WRITE_SLAVE_INIT_C,axiStatus => AXI_LITE_STATUS_INIT_C) AXI_LITE_ENDPOINT_INIT_C
Definition: AxiLitePkg.vhd:186
slv( 2 downto 0) awprot
Definition: AxiLitePkg.vhd:114
axiSlaveWaitTxnaxiWriteMaster,axiReadMaster,axiWriteSlave,axiReadSlave,axiStatus,
Definition: AxiLitePkg.vhd:241
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
slv( 31 downto 0) awaddr
Definition: AxiLitePkg.vhd:113
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:95
_library_ ieeeieee
slv( 1 downto 0) bresp
Definition: AxiLitePkg.vhd:150
AxiLiteReadMasterType :=(araddr =>( others => '0'),arprot =>( others => '0'),arvalid => '0',rready => '1') AXI_LITE_READ_MASTER_INIT_C
Definition: AxiLitePkg.vhd:69
axiSlaveWriteResponseaxiWriteSlave,axiResp,
Definition: AxiLitePkg.vhd:248
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
array(natural range <> ) of AxiLiteWriteMasterType AxiLiteWriteMasterArray
Definition: AxiLitePkg.vhd:136
axiLiteBusSimReadaxilClk,axilReadMaster,axilReadSlave,addr,data,debug,
Definition: AxiLitePkg.vhd:386
AxiLiteWriteMasterType :=(awaddr =>( others => '0'),awprot =>( others => '0'),awvalid => '0',wdata =>( others => '0'),wstrb =>( others => '1'),wvalid => '0',bready => '1') AXI_LITE_WRITE_MASTER_INIT_C
Definition: AxiLitePkg.vhd:125
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
axiSlaveWaitReadTxnaxiReadMaster,axiReadSlave,readEnable,
Definition: AxiLitePkg.vhd:236
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
AxiLiteReadMasterArray axiReadMasterInitconfig,
Definition: AxiLitePkg.vhd:223
array(natural range <> ) of AxiLiteReadSlaveType AxiLiteReadSlaveArray
Definition: AxiLitePkg.vhd:103
slv( 3 downto 0) wstrb
Definition: AxiLitePkg.vhd:118
AxiLiteReadMasterType itei,t,e,
Definition: AxiLitePkg.vhd:394
axiSlaveWaitWriteTxnaxiWriteMaster,axiWriteSlave,writeEnable,
Definition: AxiLitePkg.vhd:231
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:156
axiSlaveReadResponseaxiReadSlave,axiResp,
Definition: AxiLitePkg.vhd:252
axiSlaveRegisterRep,addr,offset,reg,
Definition: AxiLitePkg.vhd:326
std_logic_vector slv
Definition: StdRtlPkg.vhd:29