1 ------------------------------------------------------------------------------- 2 -- File : adc32rf45.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2017-05-26 5 -- Last update: 2017-06-07 6 ------------------------------------------------------------------------------- 7 -- Description: SPI Master Wrapper that includes a state machine for SPI paging 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;
27 --! @ingroup devices_Ti_adc32rf45 53 constant DLY_C : := (1.0E-6
/CLK_PERIOD_G);
-- min. 1us delay between SPI cycles 61 type RegType is record 65 wrData : slv(23 downto 0);
66 data : slv(7 downto 0);
67 addr : slv(11 downto 0);
68 xferType : slv(3 downto 0);
69 timer : range 0 to DLY_C;
78 constant REG_INIT_C : RegType := ( 82 wrData => (others => '0'), 83 data => (others => '0'), 84 addr => (others => '0'), 85 xferType => (others => '0'), 89 wrArray => (others => (others => '0')), 94 signal r : RegType := REG_INIT_C;
98 signal rdData : slv(23 downto 0);
103 variable v : RegType;
106 -- Latch the current value 112 -- Increment the timer 113 if (r.timer /= DLY_C) then 114 v.timer := r.timer + 1;
117 -- Get the AXI-Lite status 122 ---------------------------------------------------------------------- 124 -- Check if write transaction 128 -- Save the data/address 134 -- Check if read transaction 138 -- Save the data/address 145 ---------------------------------------------------------------------- 151 -- Check the transfer type 152 -- Note: Refer to https://docs.google.com/a/stanford.edu/spreadsheets/d/1FF_dsCxRgwguseu1B2kBMGiVdTbknMDl8cHdPX8geNY/edit?usp=sharing 154 -- General Registers: (XFER_Type = 0x0) 157 v.wrArray(0) := (r.axiRd & "000" & r.addr & r.data);
158 -- Offset corrector page channel A: (XFER_Type = 0x1) 161 v.wrArray(0) := (x"4001" & x"00");
162 v.wrArray(1) := (x"4002" & x"00");
163 v.wrArray(2) := (x"4003" & x"00");
164 v.wrArray(3) := (x"4004" & x"61");
165 v.wrArray(4) := (r.axiRd & "110" & r.addr & r.data);
166 -- Digital gain page channel A: (XFER_Type = 0x2) 169 v.wrArray(0) := (x"4001" & x"00");
170 v.wrArray(1) := (x"4002" & x"05");
171 v.wrArray(2) := (x"4003" & x"00");
172 v.wrArray(3) := (x"4004" & x"61");
173 v.wrArray(4) := (r.axiRd & "110" & r.addr & r.data);
174 -- Main digital page channel A: (XFER_Type = 0x3) 177 v.wrArray(0) := (x"4001" & x"00");
178 v.wrArray(1) := (x"4002" & x"00");
179 v.wrArray(2) := (x"4003" & x"00");
180 v.wrArray(3) := (x"4004" & x"68");
181 v.wrArray(4) := (r.axiRd & "110" & r.addr & r.data);
182 -- JESD digital page channel A: (XFER_Type = 0x04) 185 v.wrArray(0) := (x"4001" & x"00");
186 v.wrArray(1) := (x"4002" & x"00");
187 v.wrArray(2) := (x"4003" & x"00");
188 v.wrArray(3) := (x"4004" & x"69");
189 v.wrArray(4) := (r.axiRd & "111" & r.addr & r.data);
-- JESD digital page: use the CH bit to select channel B (CH = 0) or channel A (CH = 1). 190 -- Decimation Filter Page channel A: (XFER_Type = 0x5) 192 v.size := 1;
-- Address bit A[11] selects channel A (A[11] = 0) or channel B (A[11] = 1). 193 v.wrArray(0) := (r.axiRd & "101" & "0000" & r.addr(7 downto 0) & r.data);
-- Address bit A[10] selects the decimation filter page (A[10] = 0) or the power detector page (A[10] = 1) 194 -- Power Detector Page channel A: (XFER_Type = 0x6) 196 v.size := 1;
-- Address bit A[11] selects channel A (A[11] = 0) or channel B (A[11] = 1). 197 v.wrArray(0) := (r.axiRd & "101" & "0100" & r.addr(7 downto 0) & r.data);
-- Address bit A[10] selects the decimation filter page (A[10] = 0) or the power detector page (A[10] = 1) 198 -- Master Bank: (XFER_Type = 0x7) 201 v.wrArray(0) := (x"0011" & x"00");
202 v.wrArray(1) := (x"0012" & x"04");
203 v.wrArray(2) := (r.axiRd & "000" & r.addr & r.data);
204 -- Analog Bank: (XFER_Type = 0x8) 207 v.wrArray(0) := (x"0012" & x"00");
208 v.wrArray(1) := (x"0011" & x"FF");
209 v.wrArray(2) := (r.axiRd & "000" & r.addr & r.data);
210 -- Offset corrector page channel B: (XFER_Type = 0x9) 213 v.wrArray(0) := (x"4001" & x"00");
214 v.wrArray(1) := (x"4002" & x"00");
215 v.wrArray(2) := (x"4003" & x"01");
216 v.wrArray(3) := (x"4004" & x"61");
217 v.wrArray(4) := (r.axiRd & "110" & r.addr & r.data);
218 -- Digital gain page channel B: (XFER_Type = 0xA) 221 v.wrArray(0) := (x"4001" & x"00");
222 v.wrArray(1) := (x"4002" & x"05");
223 v.wrArray(2) := (x"4003" & x"01");
224 v.wrArray(3) := (x"4004" & x"61");
225 v.wrArray(4) := (r.axiRd & "110" & r.addr & r.data);
226 -- Main digital page channel B: (XFER_Type = 0xB) 229 v.wrArray(0) := (x"4001" & x"00");
230 v.wrArray(1) := (x"4002" & x"00");
231 v.wrArray(2) := (x"4003" & x"01");
232 v.wrArray(3) := (x"4004" & x"68");
233 v.wrArray(4) := (r.axiRd & "110" & r.addr & r.data);
234 -- JESD digital page channel B: (XFER_Type = 0x0C) 237 v.wrArray(0) := (x"4001" & x"00");
238 v.wrArray(1) := (x"4002" & x"00");
239 v.wrArray(2) := (x"4003" & x"00");
240 v.wrArray(3) := (x"4004" & x"69");
241 v.wrArray(4) := (r.axiRd & "110" & r.addr & r.data);
-- JESD digital page: use the CH bit to select channel B (CH = 0) or channel A (CH = 1). 242 -- Decimation Filter Page channel B: (XFER_Type = 0xD) 244 v.size := 1;
-- Address bit A[11] selects channel A (A[11] = 0) or channel B (A[11] = 1). 245 v.wrArray(0) := (r.axiRd & "101" & "1000" & r.addr(7 downto 0) & r.data);
-- Address bit A[10] selects the decimation filter page (A[10] = 0) or the power detector page (A[10] = 1) 246 -- Power Detector Page channel B: (XFER_Type = 0xE) 248 v.size := 1;
-- Address bit A[11] selects channel A (A[11] = 0) or channel B (A[11] = 1). 249 v.wrArray(0) := (r.axiRd & "101" & "1100" & r.addr(7 downto 0) & r.data);
-- Address bit A[10] selects the decimation filter page (A[10] = 0) or the power detector page (A[10] = 1) 250 -- Hardware Reset (XFER_Type = 0xF) 252 -- Check if transaction type 253 if (r.axiRd = '0') then 256 -- Send the write response 267 ---------------------------------------------------------------------- 269 -- Check for min. chip select gap 270 if (r.timer = DLY_C) then 271 -- Start the transaction 273 v.wrData := r.wrArray(r.cnt);
274 -- Increment the counter 279 ---------------------------------------------------------------------- 281 -- Wait for the transaction to complete 282 if (rdEn = '1') and (r.wrEn = '0') then 285 -- Check for last transaction 286 if (r.size = r.cnt) then 287 -- Check if transaction type 288 if (r.axiRd = '0') then 289 -- Send the write response 292 -- Latch the read byte 304 ---------------------------------------------------------------------- 312 -- Register the variable for next clock cycle 324 if (rising_edge(axiClk)) then 325 r <= rin after TPD_G;
351 end architecture rtl;
in wrDataslv( DATA_SIZE_G- 1 downto 0)
out axiWriteSlaveAxiLiteWriteSlaveType
out rdDataslv( DATA_SIZE_G- 1 downto 0)
SPI_SCLK_PERIOD_Greal := 1.0E-6
array(natural range <> ) of slv( 23 downto 0) Slv24Array
AxiLiteStatusType axiStatus
out axiReadSlaveAxiLiteReadSlaveType
in chipSelslv( log2(NUM_CHIPS_G )- 1 downto 0)
slv( 1 downto 0) := "11" AXI_RESP_DECERR_C
NUM_CHIPS_Gpositive range 1 to 8:= 4
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
CLK_PERIOD_Greal :=( 1.0/ 156.25E+6)
in axiWriteMasterAxiLiteWriteMasterType
in axiReadMasterAxiLiteReadMasterType
CLK_PERIOD_Greal := 8.0E-9
SPI_SCLK_PERIOD_Greal :=( 1.0/ 10.0E+6)
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_DECERR_C
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C