1 ------------------------------------------------------------------------------- 2 -- File : AxiMicronP30Reg.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2014-10-21 5 -- Last update: 2017-07-11 6 ------------------------------------------------------------------------------- 7 -- Description: This controller is designed around the Micron PC28F FLASH IC. 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_unsigned.
all;
21 use ieee.std_logic_arith.
all;
27 use unisim.vcomponents.
all;
30 --! @ingroup devices_Micron_p30 49 -- AXI-Lite Register Interface 61 constant HALF_CYCLE_PERIOD_C : := 128.0E-9;
-- units of seconds 63 constant HALF_CYCLE_FREQ_C : := (1.
0 / HALF_CYCLE_PERIOD_C);
-- units of Hz 65 constant MAX_CNT_C : := getTimeRatio(AXI_CLK_FREQ_G, HALF_CYCLE_FREQ_C);
78 type RegType is record 79 -- PROM Control Signals 85 cnt : range 0 to (MAX_CNT_C+1);
86 din : slv(15 downto 0);
87 dataReg : slv(15 downto 0);
88 addr : slv(30 downto 0);
89 wrCmd : slv(15 downto 0);
90 wrData : slv(15 downto 0);
91 test : slv(31 downto 0);
92 -- Block Transfer signals 96 blockCnt : slv(7 downto 0);
97 xferSize : slv(7 downto 0);
99 ramRd : slv(1 downto 0);
101 ramDin : slv(15 downto 0);
102 waddr : slv(7 downto 0);
103 raddr : slv(7 downto 0);
111 constant REG_INIT_C : RegType := ( 112 -- PROM Control Signals 121 addr => (others => '0'), 122 wrCmd => (others => '0'), 123 wrData => (others => '0'), 124 test => (others => '0'), 125 -- Block Transfer signals 129 blockCnt => (others => '0'), 130 xferSize => (others => '0'), 131 -- RAM Buffer Signals 132 ramRd => (others => '0'), 134 ramDin => (others => '0'), 135 waddr => (others => '0'), 136 raddr => (others => '0'), 143 signal r : RegType := REG_INIT_C;
144 signal rin : RegType;
146 signal ramDout : slv(15 downto 0);
148 -- attribute dont_touch : string; 149 -- attribute dont_touch of r : signal is "true"; 150 -- attribute dont_touch of ramDout : signal is "true"; 156 variable v : RegType;
158 variable axiWriteResp : slv(1 downto 0);
159 variable axiReadResp : slv(1 downto 0);
162 -- Latch the current value 165 -- Reset the strobing signals 175 v.ramRd(1) := r.ramRd(0);
178 -- Determine the transaction type 183 ---------------------------------------------------------------------- 191 ------------------------------------------------------------------- 192 -- Check for a read request 193 ------------------------------------------------------------------- 195 -- Reset the register 197 -- Check for RAM access 203 v.state := RAM_READ_S;
206 ------------------------- 207 -- Non-buffered Interface 208 ------------------------- 210 -- Get the opCode bus 212 -- Get the input data bus 217 -- Get the address bus 220 -- Get the output data bus 224 ------------------------- 225 -- Buffered Interface 226 ------------------------- 228 -- Get the address bus 233 -- Get the address bus 238 -- Send AXI-Lite Response 241 ------------------------------------------------------------------- 242 -- Check for a write request 243 ------------------------------------------------------------------- 245 -- Check for RAM access 247 -- Write the data to RAM 253 ------------------------- 254 -- Non-buffered Interface 255 ------------------------- 257 -- Set the opCode bus 259 -- Set the input data bus 264 -- Set the address bus 267 v.state := CMD_LOW_S;
270 ------------------------- 271 -- Buffered Interface 272 ------------------------- 274 -- Set the block transfer size 279 -- Set the address bus 285 -- Set the opCode bus 287 -- Set the input data bus 290 v.state := CMD_LOW_S;
295 v.state := BLOCK_WR_S;
301 -- Send AXI-Lite response 304 ---------------------------------------------------------------------- 306 -- Check if the RAM data is updated 307 if r.ramRd = "00" then 310 -- Send AXI-Lite Response 315 ---------------------------------------------------------------------- 317 -- Write the data to RAM 318 v.waddr := r.blockCnt;
319 v.ramDin := r.dataReg;
322 if (r.blockCnt = r.xferSize) then 326 -- Increment the counters 327 v.blockCnt := r.blockCnt + 1;
328 v.addr := r.addr + 1;
330 v.state := CMD_LOW_S;
332 ---------------------------------------------------------------------- 334 -- Increment the counter 335 v.blockCnt := r.blockCnt + 1;
339 -- Send the "unlock the block" command 344 -- Send the "reset the status register" command 349 -- Send the "program" command 352 v.wrData := ramDout;
-- Send the BRAM data 353 -- Get the status register 359 -- Check if FLASH is still busy 360 if r.dataReg(7) = '0' then 363 -- Get the status register 367 -- Check for programming failure 368 elsif r.dataReg(4) = '1' then 371 -- Send the "unlock the block" command 376 -- Send the "lock the block" command 383 -- Check the Block RAM address 384 if (r.raddr = r.xferSize) then 388 -- Increment the counter 389 v.raddr := r.raddr + 1;
394 v.state := CMD_LOW_S;
395 ---------------------------------------------------------------------- 402 -- Increment the counter 405 if (r.cnt = MAX_CNT_C) then 409 v.state := CMD_HIGH_S;
411 ---------------------------------------------------------------------- 418 -- Increment the counter 421 if (r.cnt = MAX_CNT_C) then 427 ---------------------------------------------------------------------- 434 -- Increment the counter 437 if (r.cnt = MAX_CNT_C) then 441 v.state := DATA_LOW_S;
443 ---------------------------------------------------------------------- 450 -- Increment the counter 453 if (r.cnt = MAX_CNT_C) then 456 --latch the data bus value 459 v.state := DATA_HIGH_S;
461 ---------------------------------------------------------------------- 468 -- Increment the counter 471 if (r.cnt = MAX_CNT_C) then 474 -- Check for block read 475 if (r.blockRd = '1') then 477 v.state := BLOCK_RD_S;
478 -- Check for block write 479 elsif (r.blockWr = '1') then 480 -- Check for the lock CMD 481 if (r.lockCmd = '1') then 484 -- Increment the counter 485 v.addr := r.addr + 1;
488 v.state := BLOCK_WR_S;
494 ---------------------------------------------------------------------- 502 -- Register the variable for next clock cycle 506 for i in 0 to 30 loop 524 if rising_edge(axiClk) then 525 r <= rin after TPD_G;
out flashDinslv( 15 downto 0)
in addrbslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
out doutbslv( DATA_WIDTH_G- 1 downto 0)
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
MEM_ADDR_MASK_Gslv( 31 downto 0) := x"00000000"
in flashDoutslv( 15 downto 0)
AxiLiteStatusType axiStatus
out flashAddrslv( 30 downto 0)
AXI_CLK_FREQ_Greal := 200.0E+6
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
ADDR_WIDTH_Ginteger range 1 to ( 2** 24):= 4
in axiReadMasterAxiLiteReadMasterType
in addraslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
out axiReadSlaveAxiLiteReadSlaveType
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
out axiWriteSlaveAxiLiteWriteSlaveType
slv( 1 downto 0) := "00" AXI_RESP_OK_C
in axiWriteMasterAxiLiteWriteMasterType
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
in dinaslv( DATA_WIDTH_G- 1 downto 0) :=( others => '0')