1 ------------------------------------------------------------------------------- 2 -- File : AxiMemTester.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2015-07-28 5 -- Last update: 2017-05-09 6 ------------------------------------------------------------------------------- 7 -- Description: General Purpose AXI4 memory tester 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;
20 use ieee.std_logic_arith.
all;
21 use ieee.std_logic_unsigned.
all;
47 -- DDR Memory Interface 68 constant PRBS_TAPS_C : NaturalArray := (0 => 1023, 1 => 257, 2 => 113, 3 => 61, 4 => 29, 5 => 17, 6 => 7);
69 constant PRBS_SEED_C : slv(1023 downto 0) := x"AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55AA55";
81 type RegType is record 89 wTimer : slv(31 downto 0);
90 rTimer : slv(31 downto 0);
91 len : slv(7 downto 0);
92 address : slv(63 downto 0);
93 randomData : slv(1023 downto 0);
99 constant REG_INIT_C : RegType := ( 107 wTimer => (others => '0'), 108 rTimer => (others => '0'), 110 address => (others => '0'), 111 randomData => PRBS_SEED_C, 116 signal r : RegType := REG_INIT_C;
117 signal rin : RegType;
121 signal wTimer : slv(31 downto 0);
122 signal rTimer : slv(31 downto 0);
124 type RegLiteType is record 131 constant REG_LITE_INIT_C : RegLiteType := ( 137 signal rLite : RegLiteType := REG_LITE_INIT_C;
138 signal rinLite : RegLiteType;
140 -- attribute dont_touch : string; 141 -- attribute dont_touch of r : signal is "true"; 142 -- attribute dont_touch of rLite : signal is "true"; 147 variable v : RegType;
149 -- Latch the current value 152 -- Update output registers 165 if (r.wTimerEn = '1') and (r.wTimer /= x"FFFFFFFF") then 166 v.wTimer := r.wTimer + 1;
168 if (r.rTimerEn = '1') and (r.rTimer /= x"FFFFFFFF") then 169 v.rTimer := r.rTimer + 1;
175 ---------------------------------------------------------------------- 177 -- Check calibration to complete 182 -- Latch the generator seed 183 v.randomData := PRBS_SEED_C;
184 -- Set the start address 187 v.state := WRITE_ADDR_S;
189 ---------------------------------------------------------------------- 192 -- Write Address channel 196 v.state := WRITE_DATA_S;
198 ---------------------------------------------------------------------- 201 -- Write Data channel 204 -- Generate next random word 205 v.randomData := lfsrShift(r.randomData, PRBS_TAPS_C);
206 -- Increment the counter 208 -- Check that all txns are done 215 v.state := WRITE_RESP_S;
218 ---------------------------------------------------------------------- 220 -- Wait for the response 222 -- Check for "OKAY" response 224 -- Check for max. address 225 if r.address = STOP_ADDR_C then 226 -- Reset the start address 227 v.address := (others => '0');
232 -- Latch the generator seed 233 v.randomData := PRBS_SEED_C;
235 v.state := READ_ADDR_S;
237 -- Increment the counter 240 v.state := WRITE_ADDR_S;
249 ---------------------------------------------------------------------- 252 -- Write Address channel 256 v.state := READ_DATA_S;
258 ---------------------------------------------------------------------- 262 if r.randomData(DATA_BITS_C-1 downto 0) /= axiReadSlave.rdata(DATA_BITS_C-1 downto 0) then 268 -- Generate next random word 269 v.randomData := lfsrShift(r.randomData, PRBS_TAPS_C);
270 -- Check for last transfer 273 -- Check for max. address 274 if r.address = STOP_ADDR_C then 275 report "AxiMemTester: Passed Test!";
276 report "wTimer = " & 'image(conv_integer(v.wTimer));
277 report "rTimer = " & 'image(conv_integer(v.rTimer));
281 -- Increment the counter 284 v.state := READ_ADDR_S;
294 ---------------------------------------------------------------------- 300 ---------------------------------------------------------------------- 306 ---------------------------------------------------------------------- 314 -- Write Address Constants 326 -- Read Address Constants (copied from Write Constants) 337 -- Register the variable for next clock cycle 348 if rising_edge(axiClk) then 349 r <= rin after TPD_G;
374 -- Write Ports (wr_clk domain) 377 -- Read Ports (rd_clk domain) 386 -- Write Ports (wr_clk domain) 389 -- Read Ports (rd_clk domain) 394 variable v : RegLiteType;
395 variable regCon : AxiLiteEndPointType;
397 -- Latch the current value 400 -- Determine the transaction type 404 axiSlaveRegisterR(regCon, x"100", 0, rLite.memReady);
405 axiSlaveRegisterR(regCon, x"104", 0, rLite.memError);
406 axiSlaveRegisterR(regCon, x"108", 0, wTimer);
407 axiSlaveRegisterR(regCon, x"10C", 0, rTimer);
409 axiSlaveRegisterR(regCon, x"110", 0, START_C);
410 axiSlaveRegisterR(regCon, x"114", 0, x"00000000");
411 axiSlaveRegisterR(regCon, x"118", 0, STOP_C);
412 axiSlaveRegisterR(regCon, x"11C", 0, x"00000000");
414 axiSlaveRegisterR(regCon, x"110", 0, START_C(31 downto 0));
416 axiSlaveRegisterR(regCon, x"118", 0, STOP_C(31 downto 0));
423 -- Closeout the transaction 426 -- Latch the values from Synchronizers 432 v := REG_LITE_INIT_C;
435 -- Register the variable for next clock cycle 444 end process combLite;
449 rLite <= rinLite after TPD_G;
out axilReadSlaveAxiLiteReadSlaveType
in axilWriteMasterAxiLiteWriteMasterType
AxiReadMasterType :=(arvalid => '0',araddr =>( others => '0'),arid =>( others => '0'),arlen =>( others => '0'),arsize =>( others => '0'),arburst =>( others => '0'),arlock =>( others => '0'),arprot =>( others => '0'),arcache =>( others => '0'),arqos =>( others => '0'),arregion =>( others => '0'),rready => '0') AXI_READ_MASTER_INIT_C
out axiReadMasterAxiReadMasterType
in dinslv( DATA_WIDTH_G- 1 downto 0)
START_ADDR_Gslv := X"00000000"
STOP_ADDR_Gslv := X"FFFFFFFF"
in axiReadSlaveAxiReadSlaveType
out doutslv( DATA_WIDTH_G- 1 downto 0)
positive range 12 to 64 ADDR_WIDTH_C
slv( 1 downto 0) := "11" AXI_RESP_DECERR_C
array(natural range <> ) of natural NaturalArray
out axiWriteMasterAxiWriteMasterType
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
in axilReadMasterAxiLiteReadMasterType
AXI_CONFIG_GAxiConfigType := AXI_CONFIG_INIT_C
out axilWriteSlaveAxiLiteWriteSlaveType
positive range 1 to 128 DATA_BYTES_C
BURST_LEN_Gpositive range 1 to 4096:= 4096
AxiConfigType :=axiConfig(ADDR_WIDTH_C => 32,DATA_BYTES_C => 4,ID_BITS_C => 12,LEN_BITS_C => 4) AXI_CONFIG_INIT_C
positive range 1 to 32 ID_BITS_C
AxiWriteMasterType :=(awvalid => '0',awaddr =>( others => '0'),awid =>( others => '0'),awlen =>( others => '0'),awsize =>( others => '0'),awburst =>( others => '0'),awlock =>( others => '0'),awprot =>( others => '0'),awcache =>( others => '0'),awqos =>( others => '0'),awregion =>( others => '0'),wdata =>( others => '0'),wlast => '0',wvalid => '0',wid =>( others => '0'),wstrb =>( others => '0'),bready => '0') AXI_WRITE_MASTER_INIT_C
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_DECERR_C
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
in axiWriteSlaveAxiWriteSlaveType