SURF  1.0
adc32rf45.vhd
Go to the documentation of this file.
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 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_arith.all;
21 use ieee.std_logic_unsigned.all;
22 
23 use work.StdRtlPkg.all;
24 use work.AxiLitePkg.all;
25 
26 --! @see entity
27  --! @ingroup devices_Ti_adc32rf45
28 entity adc32rf45 is
29  generic (
30  TPD_G : time := 1 ns;
32  CLK_PERIOD_G : real := (1.0/156.25E+6);
33  SPI_SCLK_PERIOD_G : real := (1.0/10.0E+6));
34  port (
35  -- Clock and Reset
36  axiClk : in sl;
37  axiRst : in sl;
38  -- AXI-Lite Interface
43  -- SPI Interface
44  coreRst : out sl;
45  coreSclk : out sl;
46  coreSDin : in sl;
47  coreSDout : out sl;
48  coreCsb : out sl);
49 end entity adc32rf45;
50 
51 architecture rtl of adc32rf45 is
52 
53  constant DLY_C : natural := integer(1.0E-6/CLK_PERIOD_G); -- min. 1us delay between SPI cycles
54 
55  type StateType is (
56  IDLE_S,
57  INIT_S,
58  REQ_S,
59  ACK_S);
60 
61  type RegType is record
62  rst : sl;
63  axiRd : sl;
64  wrEn : sl;
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 : natural range 0 to DLY_C;
70  cnt : natural range 0 to 5;
71  size : natural range 0 to 5;
72  wrArray : Slv24Array(4 downto 0);
75  state : StateType;
76  end record RegType;
77 
78  constant REG_INIT_C : RegType := (
79  rst => '0',
80  axiRd => '0',
81  wrEn => '0',
82  wrData => (others => '0'),
83  data => (others => '0'),
84  addr => (others => '0'),
85  xferType => (others => '0'),
86  timer => 0,
87  cnt => 0,
88  size => 0,
89  wrArray => (others => (others => '0')),
92  state => IDLE_S);
93 
94  signal r : RegType := REG_INIT_C;
95  signal rin : RegType;
96 
97  signal rdEn : sl;
98  signal rdData : slv(23 downto 0);
99 
100 begin
101 
102  comb : process (axiReadMaster, axiRst, axiWriteMaster, r, rdData, rdEn) is
103  variable v : RegType;
104  variable axiStatus : AxiLiteStatusType;
105  begin
106  -- Latch the current value
107  v := r;
108 
109  -- Reset strobes
110  v.wrEn := '0';
111 
112  -- Increment the timer
113  if (r.timer /= DLY_C) then
114  v.timer := r.timer + 1;
115  end if;
116 
117  -- Get the AXI-Lite status
119 
120  -- State Machine
121  case r.state is
122  ----------------------------------------------------------------------
123  when IDLE_S =>
124  -- Check if write transaction
125  if (axiStatus.writeEnable = '1') then
126  -- Set the flag
127  v.axiRd := '0';
128  -- Save the data/address
129  v.data := axiWriteMaster.wdata(7 downto 0);
130  v.addr := axiWriteMaster.awaddr(13 downto 2);
131  v.xferType := axiWriteMaster.awaddr(17 downto 14);
132  -- Next State
133  v.state := INIT_S;
134  -- Check if read transaction
135  elsif (axiStatus.readEnable = '1') then
136  -- Set the flag
137  v.axiRd := '1';
138  -- Save the data/address
139  v.data := x"FF";
140  v.addr := axiReadMaster.araddr(13 downto 2);
141  v.xferType := axiReadMaster.araddr(17 downto 14);
142  -- Next State
143  v.state := INIT_S;
144  end if;
145  ----------------------------------------------------------------------
146  when INIT_S =>
147  -- Next State
148  v.state := REQ_S;
149  -- Reset the counter
150  v.cnt := 0;
151  -- Check the transfer type
152  -- Note: Refer to https://docs.google.com/a/stanford.edu/spreadsheets/d/1FF_dsCxRgwguseu1B2kBMGiVdTbknMDl8cHdPX8geNY/edit?usp=sharing
153  case r.xferType is
154  -- General Registers: (XFER_Type = 0x0)
155  when x"0" =>
156  v.size := 1;
157  v.wrArray(0) := (r.axiRd & "000" & r.addr & r.data);
158  -- Offset corrector page channel A: (XFER_Type = 0x1)
159  when x"1" =>
160  v.size := 5;
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)
167  when x"2" =>
168  v.size := 5;
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)
175  when x"3" =>
176  v.size := 5;
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)
183  when x"4" =>
184  v.size := 5;
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)
191  when x"5" =>
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)
195  when x"6" =>
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)
199  when x"7" =>
200  v.size := 3;
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)
205  when x"8" =>
206  v.size := 3;
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)
211  when x"9" =>
212  v.size := 5;
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)
219  when x"A" =>
220  v.size := 5;
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)
227  when x"B" =>
228  v.size := 5;
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)
235  when x"C" =>
236  v.size := 5;
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)
243  when x"D" =>
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)
247  when x"E" =>
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)
251  when others =>
252  -- Check if transaction type
253  if (r.axiRd = '0') then
254  -- Write the bit
255  v.rst := axiWriteMaster.wdata(0);
256  -- Send the write response
257  axiSlaveWriteResponse(v.axiWriteSlave);
258  else
259  -- Reade the bit
260  v.axiReadSlave.rdata(7 downto 0) := ("0000000" & r.rst);
261  -- Send the response
262  axiSlaveReadResponse(v.axiReadSlave);
263  end if;
264  --- Next state
265  v.state := IDLE_S;
266  end case;
267  ----------------------------------------------------------------------
268  when REQ_S =>
269  -- Check for min. chip select gap
270  if (r.timer = DLY_C) then
271  -- Start the transaction
272  v.wrEn := '1';
273  v.wrData := r.wrArray(r.cnt);
274  -- Increment the counter
275  v.cnt := r.cnt + 1;
276  --- Next state
277  v.state := ACK_S;
278  end if;
279  ----------------------------------------------------------------------
280  when ACK_S =>
281  -- Wait for the transaction to complete
282  if (rdEn = '1') and (r.wrEn = '0') then
283  -- Reset the timer
284  v.timer := 0;
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
290  axiSlaveWriteResponse(v.axiWriteSlave);
291  else
292  -- Latch the read byte
293  v.axiReadSlave.rdata(7 downto 0) := rdData(7 downto 0);
294  -- Send the response
295  axiSlaveReadResponse(v.axiReadSlave);
296  end if;
297  --- Next state
298  v.state := IDLE_S;
299  else
300  --- Next state
301  v.state := REQ_S;
302  end if;
303  end if;
304  ----------------------------------------------------------------------
305  end case;
306 
307  -- Reset
308  if (axiRst = '1') then
309  v := REG_INIT_C;
310  end if;
311 
312  -- Register the variable for next clock cycle
313  rin <= v;
314 
315  -- Outputs
318  coreRst <= (r.rst or axiRst);
319 
320  end process comb;
321 
322  seq : process (axiClk) is
323  begin
324  if (rising_edge(axiClk)) then
325  r <= rin after TPD_G;
326  end if;
327  end process seq;
328 
329  U_SpiMaster : entity work.SpiMaster
330  generic map (
331  TPD_G => TPD_G,
332  NUM_CHIPS_G => 1,
333  DATA_SIZE_G => 24,
334  CPHA_G => '0',
335  CPOL_G => '0',
338  port map (
339  clk => axiClk,
340  sRst => axiRst,
341  chipSel => "0",
342  wrEn => r.wrEn,
343  wrData => r.wrData,
344  rdEn => rdEn,
345  rdData => rdData,
346  spiCsL(0) => coreCsb,
347  spiSclk => coreSclk,
348  spiSdi => coreSDout,
349  spiSdo => coreSDin);
350 
351 end architecture rtl;
in wrDataslv( DATA_SIZE_G- 1 downto 0)
Definition: SpiMaster.vhd:43
_library_ ieeeieee
out axiWriteSlaveAxiLiteWriteSlaveType
Definition: adc32rf45.vhd:42
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
out rdDataslv( DATA_SIZE_G- 1 downto 0)
Definition: SpiMaster.vhd:46
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
out coreRstsl
Definition: adc32rf45.vhd:44
in wrEnsl
Definition: SpiMaster.vhd:42
SPI_SCLK_PERIOD_Greal := 1.0E-6
Definition: SpiMaster.vhd:35
out coreSDoutsl
Definition: adc32rf45.vhd:47
array(natural range <> ) of slv( 23 downto 0) Slv24Array
Definition: StdRtlPkg.vhd:387
in coreSDinsl
Definition: adc32rf45.vhd:46
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
AxiLiteStatusType axiStatus
Definition: AxiLitePkg.vhd:183
out axiReadSlaveAxiLiteReadSlaveType
Definition: adc32rf45.vhd:40
out rdEnsl
Definition: SpiMaster.vhd:45
in chipSelslv( log2(NUM_CHIPS_G )- 1 downto 0)
Definition: SpiMaster.vhd:41
CPHA_Gsl := '0'
Definition: SpiMaster.vhd:32
in spiSdosl
Definition: SpiMaster.vhd:52
CPOL_Gsl := '0'
Definition: SpiMaster.vhd:33
slv( 1 downto 0) := "11" AXI_RESP_DECERR_C
Definition: AxiLitePkg.vhd:49
TPD_Gtime := 1 ns
Definition: SpiMaster.vhd:29
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
out coreCsbsl
Definition: adc32rf45.vhd:48
out coreSclksl
Definition: adc32rf45.vhd:45
NUM_CHIPS_Gpositive range 1 to 8:= 4
Definition: SpiMaster.vhd:30
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
CLK_PERIOD_Greal :=( 1.0/ 156.25E+6)
Definition: adc32rf45.vhd:32
in axiWriteMasterAxiLiteWriteMasterType
Definition: adc32rf45.vhd:41
in axiClksl
Definition: adc32rf45.vhd:36
TPD_Gtime := 1 ns
Definition: adc32rf45.vhd:30
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
out spiSclksl
Definition: SpiMaster.vhd:50
DATA_SIZE_Gnatural := 16
Definition: SpiMaster.vhd:31
out spiSdisl
Definition: SpiMaster.vhd:51
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
in clksl
Definition: SpiMaster.vhd:38
in sRstsl
Definition: SpiMaster.vhd:39
in axiReadMasterAxiLiteReadMasterType
Definition: adc32rf45.vhd:39
CLK_PERIOD_Greal := 8.0E-9
Definition: SpiMaster.vhd:34
SPI_SCLK_PERIOD_Greal :=( 1.0/ 10.0E+6)
Definition: adc32rf45.vhd:33
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_DECERR_C
Definition: adc32rf45.vhd:31
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:156
in axiRstsl
Definition: adc32rf45.vhd:37
std_logic_vector slv
Definition: StdRtlPkg.vhd:29