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 ------------------------------------------------------------------------------- 19 use ieee.std_logic_1164.
all;
28 ------------------------------------------------------------------------------------------------- 29 -- AXI bus response codes 30 ------------------------------------------------------------------------------------------------- 34 -- Note: There are no "exclusive access" in AXI-Lite. This is just a placeholder constant. 37 -- Note: A SLVERR response is returned to the master if the AXI peripheral interface receives any 38 -- of the following unsupported accesses: 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. 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. 54 -------------------------------------------------------- 55 -- AXI bus, read master signal record 56 -------------------------------------------------------- 60 -- Read Address channel 68 -- Initialization constants 80 -------------------------------------------------------- 81 -- AXI bus, read slave signal record 82 -------------------------------------------------------- 86 -- Read Address channel 94 -- Initialization constants 97 rdata => (others => '0'), 98 rresp => (others => '0'), 106 -------------------------------------------------------- 107 -- AXI bus, write master signal record 108 -------------------------------------------------------- 112 -- Write address channel 116 -- Write data channel 124 -- Initialization constants 126 awaddr => (others => '0'), 127 awprot => (others => '0'), 129 wdata => (others => '0'), 130 wstrb => (others => '1'), 139 -------------------------------------------------------- 140 -- AXI bus, write slave signal record 141 -------------------------------------------------------- 145 -- Write address channel 147 -- Write data channel 155 -- Initialization constants 159 bresp => (others => '0'), 175 -------------------------------------------------------- 176 -- AXI bus, read/write endpoint record, RTH 1/27/2016 177 -------------------------------------------------------- 193 ------------------------------------------------------------------------------------------------- 194 -- Crossbar Config Generic Types 195 ------------------------------------------------------------------------------------------------- 218 ------------------------------------------------------------------------------------------------- 219 -- Initilize masters with uppder address bits already set to configuration base address 220 ------------------------------------------------------------------------------------------------- 227 ------------------------------------------------------------------------------------------------- 228 -- Slave AXI Processing procedures 229 ------------------------------------------------------------------------------------------------- 256 ------------------------------------------------------------------------------------------------- 257 -- Address decode procedures 258 ------------------------------------------------------------------------------------------------- 268 constAssign :
in := false;
269 constVal :
in slv := );
288 constAssign :
in := false;
289 constVal :
in sl := '0');
306 extTxn :
in sl := '0');
309 ------------------------------------------------------------------------------------------------- 310 -- Simplified Address decode procedures, RTH 1/27/2016 311 ------------------------------------------------------------------------------------------------- 324 constVal :
in slv := );
337 constVal :
in sl := 'X');
348 regs :
inout slv32Array);
353 regs :
in slv32Array);
360 extTxn :
in sl := '0');
363 ------------------------------------------------------------------------------------------------- 364 -- Slave AXI Processing functions 365 ------------------------------------------------------------------------------------------------- 367 -- Generate evenly distributed address map 369 base :
slv(
31 downto 0);
370 baseBot :
range 0 to 32;
375 ------------------------------------------------------------------------------------------------- 376 -- Simulation procedures 377 ------------------------------------------------------------------------------------------------- 379 signal axilClk :
in sl;
382 addr :
in slv(
31 downto 0);
384 debug :
in := false);
387 signal axilClk :
in sl;
390 addr :
in slv(
31 downto 0);
392 debug :
in := false);
409 end function axiReadMasterInit;
414 for i
in config'
range loop 415 ret
(i
) := axiReadMasterInit
(config
(i
));
418 end function axiReadMasterInit;
426 end function axiWriteMasterInit;
431 for i
in config'
range loop 432 ret
(i
) := axiWriteMasterInit
(config
(i
));
435 end function axiWriteMasterInit;
442 ---------------------------------------------------------------------------------------------- 444 ---------------------------------------------------------------------------------------------- 450 -- Incomming Write txn and last txn has concluded 466 ---------------------------------------------------------------------------------------------- 468 ---------------------------------------------------------------------------------------------- 473 -- Incomming read txn and last txn has concluded 478 -- Reset rvalid upon rready 482 end procedure axiSlaveWaitReadTxn;
484 procedure axiSlaveWaitTxn
( 514 ------------------------------------------------------------------------------------------------- 515 -- Procedures for simplified address decoding 516 ------------------------------------------------------------------------------------------------- 526 constAssign :
in := false;
527 constVal :
in slv := )
is 529 -- Read must come first so as not to overwrite the variable if read and write happen at once 539 if (constAssign
) then 575 constAssign :
in := false;
576 constVal :
in sl := '0')
578 variable tmpReg :
slv(0 downto 0);
579 variable tmpVal :
slv(0 downto 0);
582 tmpVal
(0) := constVal;
595 variable tmp :
slv(0 downto 0);
608 extTxn :
in sl := '0')
is 619 ------------------------------------------------------------------------------------------------- 620 -- Simplified Address decode procedures, RTH 1/27/2016 621 ------------------------------------------------------------------------------------------------- 649 constVal :
in slv := )
651 -- Need to remap addr range to be (length-1 downto 0) 652 constant ADDR_LEN_C : := 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 : := offset +
(to_integer
((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(((slv(ADDR_C
))) +
((ABS_OFFSET_C/
32)*
4)),
660 constant NORMAL_OFFSET_C : := ABS_OFFSET_C
mod 32;
661 -- Most significant register bit before wrapping to the next word address 662 constant REG_HIGH_BIT_C : := 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 : := minimum
(NORMAL_OFFSET_C+reg'
length-
1,
31);
666 variable strobeMask :
slv(3 downto 0) :=
(others => '-'
);
669 for i
in BUS_HIGH_BIT_C
downto NORMAL_OFFSET_C
loop 670 strobeMask
(i/
8) := '
1';
673 -- Read must come first so as not to overwrite the variable if read and write happen at once 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);
682 if (std_match
(ep.
axiWriteMaster.
awaddr(ADDR_LEN_C-
1 downto 2), NORMAL_ADDR_C
(ADDR_LEN_C-
1 downto 2)) and 684 if (constVal /=
"X") then 685 reg
(REG_HIGH_BIT_C
downto reg'
low) := constVal;
687 reg
(REG_HIGH_BIT_C
downto reg'
low) := ep.
axiWriteMaster.
wdata(BUS_HIGH_BIT_C
downto NORMAL_OFFSET_C
);
693 if (REG_HIGH_BIT_C < reg'
high) then 694 axiSlaveRegister
(ep,
slv((NORMAL_ADDR_C
)+
4),
0, reg
(reg'
high downto REG_HIGH_BIT_C+
1),
"X");
705 variable regTmp :
slv(reg'
length-
1 downto 0);
708 axiSlaveRegister
(ep, addr, offset, regTmp,
"X");
716 constVal :
in sl := 'X')
718 variable tmpReg :
slv(0 downto 0);
719 variable tmpVal :
slv(0 downto 0);
722 tmpVal
(0) := constVal;
723 axiSlaveRegister
(ep, addr, offset, tmpReg, tmpVal
);
733 variable tmp :
slv(0 downto 0);
736 axiSlaveRegisterR
(ep, addr, offset, tmp
);
742 regs :
inout slv32Array)
745 for i
in regs'
range loop 746 axiSlaveRegister
(ep,
slv((addr
) + to_unsigned
(i*
4, addr'
length)),
0, regs
(i
));
754 regs :
in slv32Array)
756 constant ADDR_BITS_C : := log2
(regs'
length);
757 variable addrLocal :
slv(addr'
length-
1 downto 0) := addr;
758 variable tmp :
slv(31 downto 0);
760 -- Select regs word based on araddr 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
);
775 extTxn :
in sl := '0')
is 789 ------------------------------------------------------------------------------------------------- 790 -- Slave AXI Processing functions 791 ------------------------------------------------------------------------------------------------- 793 -- Generate evenly distributed address map 795 base :
slv(
31 downto 0);
796 baseBot :
range 0 to 32;
800 variable addr :
slv(31 downto 0);
805 addr
(baseBot-
1 downto 0) :=
(others => '
0'
);
808 for i
in 0 to num-
1 loop 819 ------------------------------------------------------------------------------------------------- 820 -- Simulation procedures 821 ------------------------------------------------------------------------------------------------- 824 signal axilClk :
in sl;
827 addr :
in slv(
31 downto 0);
831 variable dataTmp :
slv(31 downto 0);
832 variable addrTmp :
slv(31 downto 0);
834 dataTmp := resize
(data,
32);
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';
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';
853 if axilWriteSlave.
wready = '
1'
then 854 axilWriteMaster.
wvalid <= '
0';
857 wait until axilClk = '
1';
860 -- Clear control signals if bvalid and ready arrive at the same time 861 if axilWriteSlave.
awready = '
1'
then 862 axilWriteMaster.
awvalid <= '
0';
864 if axilWriteSlave.
wready = '
1'
then 865 axilWriteMaster.
wvalid <= '
0';
868 -- Done. Check for errors 869 axilWriteMaster.
bready <= '
0';
871 print
(debug,
"AxiLitePkg::axiLiteBusSimWrite(addr:" & hstr
(addr
) &
", data: " & hstr
(dataTmp
) &
")");
873 report "AxiLitePkg::axiLiteBusSimWrite(): - BRESP = SLAVE_ERROR" severity warning;
875 report "AxiLitePkg::axiLiteBusSimWrite(): BRESP = DECODE_ERROR" severity warning;
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((addr
) +
4);
882 axiLiteBusSimWrite
(axilClk, axilWriteMaster, axilWriteSlave, addrTmp, data
(data'
high downto 32), debug
);
885 end procedure axiLiteBusSimWrite;
888 procedure axiLiteBusSimRead
( 889 signal axilClk :
in sl;
892 addr :
in slv(31 downto 0);
896 variable dataTmp :
slv(31 downto 0);
897 variable addrTmp :
slv(31 downto 0);
899 -- Put the write req on the bus 900 wait until axilClk = '
1';
901 axilReadMaster.
araddr <= addr;
902 axilReadMaster.
arprot <=
(others => '
0'
);
904 axilReadMaster.
rready <= '
1';
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 914 wait until axilClk = '
1';
917 -- Clear control signals when acked 918 if axilReadSlave.
arready = '
1'
then 922 -- Done. Check for errors 924 report "AxiLitePkg::axiLiteBusSimRead(): - RRESP = SLAVE_ERROR" severity warning;
926 report "AxiLitePkg::axiLiteBusSimRead(): RRESP = DECODE_ERROR" severity warning;
928 dataTmp := axilReadSlave.
rdata;
929 print
(debug,
"AxiLitePkg::axiLiteBusSimRead( addr:" & hstr
(addr
) &
", data: " & hstr
(axilReadSlave.
rdata) &
")");
931 axilReadMaster.
rready <= '
0';
933 if (data'
length >
32) then 934 addrTmp :=
slv((addr
) +
4);
935 data
(data'
low+
31 downto data'
low) := dataTmp;
936 axiLiteBusSimRead
(axilClk, axilReadMaster, axilReadSlave, addrTmp, data
(data'
high downto 32), debug
);
938 data := resize
(dataTmp, data'
length);
942 end procedure axiLiteBusSimRead;
946 if (i
) then return t;
else return e;
end if;
951 if (i
) then return t;
else return e;
end if;
956 if (i
) then return t;
else return e;
end if;
961 if (i
) then return t;
else return e;
end if;
965 end package body AxiLitePkg;
slv( 1 downto 0) := "01" AXI_RESP_EXOKAY_C
axiLiteBusSimWriteaxilClk,axilWriteMaster,axilWriteSlave,addr,data,debug,
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
slv( 15 downto 0) connectivity
array(natural range <> ) of AxiLiteWriteSlaveType AxiLiteWriteSlaveArray
array(natural range <> ) of AxiLiteReadMasterType AxiLiteReadMasterArray
AxiLiteCrossbarMasterConfigArray genAxiLiteConfignum,base,baseBot,addrBits,
AxiLiteWriteMasterType axiWriteMaster
slv( 31 downto 0) baseAddr
AxiLiteWriteMasterArray axiWriteMasterInitconfig,
AxiLiteStatusType :=(writeEnable => '0',readEnable => '0') AXI_LITE_STATUS_INIT_C
AxiLiteReadSlaveType axiReadSlave
AxiLiteCrossbarMasterConfigType
AxiLiteStatusType axiStatus
array(natural range <> ) of AxiLiteCrossbarMasterConfigType AxiLiteCrossbarMasterConfigArray
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
AxiLiteReadMasterType axiReadMaster
AxiLiteWriteSlaveType axiWriteSlave
slv( 1 downto 0) := "11" AXI_RESP_DECERR_C
axiSlaveDefaultaxiWriteMaster,axiReadMaster,axiWriteSlave,axiReadSlave,axiStatus,axiResp,extTxn,
axiSlaveRegisteraxiWriteMaster,axiReadMaster,axiWriteSlave,axiReadSlave,axiStatus,addr,offset,reg,constAssign,constVal,
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
axiSlaveWaitTxnaxiWriteMaster,axiReadMaster,axiWriteSlave,axiReadSlave,axiStatus,
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
AxiLiteReadMasterType :=(araddr =>( others => '0'),arprot =>( others => '0'),arvalid => '0',rready => '1') AXI_LITE_READ_MASTER_INIT_C
axiSlaveWriteResponseaxiWriteSlave,axiResp,
array(natural range <> ) of AxiLiteWriteMasterType AxiLiteWriteMasterArray
axiLiteBusSimReadaxilClk,axilReadMaster,axilReadSlave,addr,data,debug,
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
slv( 1 downto 0) := "00" AXI_RESP_OK_C
axiSlaveWaitReadTxnaxiReadMaster,axiReadSlave,readEnable,
AxiLiteReadMasterArray axiReadMasterInitconfig,
array(natural range <> ) of AxiLiteReadSlaveType AxiLiteReadSlaveArray
AxiLiteReadMasterType itei,t,e,
axiSlaveWaitWriteTxnaxiWriteMaster,axiWriteSlave,writeEnable,
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
axiSlaveReadResponseaxiReadSlave,axiResp,
axiSlaveRegisterRep,addr,offset,reg,