SURF  1.0
Ad9249ConfigNoPullup.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : Ad9249ConfigNoPullup.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2013-09-23
5 -- Last update: 2016-12-12
6 -------------------------------------------------------------------------------
7 -- Description: AD9249 Configuration/Status Module (no pullup version)
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 
20 use ieee.std_logic_1164.all;
21 use ieee.std_logic_arith.all;
22 use ieee.std_logic_unsigned.all;
23 
24 use work.StdRtlPkg.all;
25 use work.AxiLitePkg.all;
26 
27 --! @see entity
28  --! @ingroup devices_AnalogDevices_ad9249
30  generic (
31  TPD_G : time := 1 ns;
32  DEN_POLARITY_G : sl := '1';
33  CLK_PERIOD_G : real := 8.0e-9;
34  CLK_EN_PERIOD_G : real := 16.0e-9;
35  NUM_CHIPS_G : positive := 1;
36  AXIL_ERR_RESP_G : slv(1 downto 0) := AXI_RESP_DECERR_C
37  );
38  port (
39 
40  axilClk : in sl;
41  axilRst : in sl;
42 
47 
48  -- Interface To ADC
49  adcSClk : out std_logic;
50  adcSDin : in std_logic;
51  adcSDout : out std_logic;
52  adcSDEn : out std_logic;
53  adcCsb : out std_logic_vector(NUM_CHIPS_G*2-1 downto 0);
54  adcPdwn : out std_logic_vector(NUM_CHIPS_G-1 downto 0)
55  );
56 end Ad9249ConfigNoPullup;
57 
58 
59 -- Define architecture
60 architecture rtl of Ad9249ConfigNoPullup is
61 
62  constant SPI_CLK_PERIOD_DIV2_CYCLES_C : integer := integer(CLK_EN_PERIOD_G / CLK_PERIOD_G) / 2;
63  constant SCLK_COUNTER_SIZE_C : integer := bitSize(SPI_CLK_PERIOD_DIV2_CYCLES_C);
64 
65  -- Local Signals
66  signal intShift : std_logic_vector(23 downto 0);
67  signal nextClk : std_logic;
68  signal nextAck : std_logic;
69  signal shiftCnt : std_logic_vector(12 downto 0);
70  signal shiftCntEn : std_logic;
71  signal shiftEn : std_logic;
72  signal locSDout : std_logic;
73  signal adcSDir : std_logic;
74 
75  signal axilClkEn : std_logic;
76  signal sclkCounter : std_logic_vector(SCLK_COUNTER_SIZE_C-1 downto 0);
77 
78  -- State Machine
79  constant ST_IDLE : std_logic_vector(1 downto 0) := "01";
80  constant ST_SHIFT : std_logic_vector(1 downto 0) := "10";
81  constant ST_DONE : std_logic_vector(1 downto 0) := "11";
82  signal curState : std_logic_vector(1 downto 0);
83  signal nxtState : std_logic_vector(1 downto 0);
84 
85  signal adcWrData : std_logic_vector(7 downto 0);
86  signal adcRdData : std_logic_vector(7 downto 0);
87  signal adcAddr : std_logic_vector(12 downto 0);
88  signal adcWrReq : std_logic;
89  signal adcRdReq : std_logic;
90  signal adcAck : std_logic;
91 
92  constant CHIP_SEL_WIDTH_C : integer := log2(NUM_CHIPS_G*2);
93  constant PWDN_ADDR_BIT_C : integer := 11 + CHIP_SEL_WIDTH_C;
94  constant PWDN_ADDR_C : slv(PWDN_ADDR_BIT_C downto 0) := toSlv(2**PWDN_ADDR_BIT_C, PWDN_ADDR_BIT_C+1);
95 
96  type StateType is (ADC_IDLE_S, ADC_READ_S, ADC_WRITE_S);
97 
98  -- Registers
99  type RegType is record
100  state : StateType;
103  -- Adc Core Inputs
104  chipSel : slv(CHIP_SEL_WIDTH_C-1 downto 0);
105  wrData : slv(23 downto 0);
106  adcWrReq : sl;
107  adcRdReq : sl;
108  pdwn : slv(NUM_CHIPS_G-1 downto 0);
109  end record RegType;
110 
111  constant REG_INIT_C : RegType := (
112  state => ADC_IDLE_S,
115  chipSel => (others => '0'),
116  wrData => (others => '0'),
117  adcWrReq => '0',
118  adcRdReq => '0',
119  pdwn => (others => '0'));
120 
121  signal r : RegType := REG_INIT_C;
122  signal rin : RegType;
123 
124 begin
125 
126 
127  comb : process (adcAck, adcRdData, axilReadMaster, axilRst, axilWriteMaster, r) is
128  variable v : RegType;
129  variable axilStatus : AxiLiteStatusType;
130  begin
131  v := r;
132 
133  v.axilReadSlave.rdata := (others => '0');
134  axiSlaveWaitTxn(axilWriteMaster, axilReadMaster, v.axilWriteSlave, v.axilReadSlave, axilStatus);
135 
136  -- Any other address is forwarded to the chip via SPI
137  if (axilStatus.writeEnable = '1') then
138  if (axilWriteMaster.awaddr(PWDN_ADDR_BIT_C) = '0') then
139  v.wrData(23) := '0'; -- Write bit
140  v.wrData(22 downto 21) := "00"; -- Number of bytes (1)
141  v.wrData(20 downto 17) := "0000"; -- Unused address bits
142  v.wrData(16 downto 8) := axilWriteMaster.awaddr(10 downto 2); -- Address
143  v.wrData(7 downto 0) := axilWriteMaster.wdata(7 downto 0); -- Data
144  v.chipSel := axilWriteMaster.awaddr(11+CHIP_SEL_WIDTH_C-1 downto 11); -- Bank select
145  v.adcWrReq := '1';
146  elsif (axilWriteMaster.awaddr(PWDN_ADDR_BIT_C downto 0) = PWDN_ADDR_C) then
147  v.pdwn := axilWriteMaster.wdata(NUM_CHIPS_G-1 downto 0);
148  axiSlaveWriteResponse(v.axilWriteSlave, AXI_RESP_OK_C);
149  else
150  axiSlaveDefault(axilWriteMaster, axilReadMaster, v.axilWriteSlave, v.axilReadSlave, axilStatus, AXIL_ERR_RESP_G);
151  end if;
152  end if;
153 
154  if (axilStatus.readEnable = '1') then
155  if (axilReadMaster.araddr(PWDN_ADDR_BIT_C) = '0') then
156  v.wrData(23) := '1'; -- read bit
157  v.wrData(22 downto 21) := "00"; -- Number of bytes (1)
158  v.wrData(20 downto 17) := "0000"; -- Unused address bits
159  v.wrData(16 downto 8) := axilReadMaster.araddr(10 downto 2); -- Address
160  v.wrData(7 downto 0) := (others => '0');
161  v.chipSel := axilReadMaster.araddr(11+CHIP_SEL_WIDTH_C-1 downto 11); -- Bank Select
162  v.adcRdReq := '1';
163 
164  elsif (axilReadMaster.araddr(PWDN_ADDR_BIT_C downto 0) = PWDN_ADDR_C) then
165  v.axilReadSlave.rdata(NUM_CHIPS_G-1 downto 0) := r.pdwn;
166  axiSlaveReadResponse(v.axilReadSlave, AXI_RESP_OK_C);
167  else
168  axiSlaveDefault(axilWriteMaster, axilReadMaster, v.axilWriteSlave, v.axilReadSlave, axilStatus, AXIL_ERR_RESP_G);
169  end if;
170  end if;
171 
172 
173  case (r.state) is
174  when ADC_IDLE_S =>
175  if r.adcWrReq = '1' then
176  v.state := ADC_WRITE_S;
177  elsif r.adcRdReq = '1' then
178  v.state := ADC_READ_S;
179  end if;
180 
181  when ADC_WRITE_S =>
182  v.adcWrReq := '1';
183  if adcAck = '1' then
184  v.adcWrReq := '0';
185  v.state := ADC_IDLE_S;
186  axiSlaveWriteResponse(v.axilWriteSlave, AXI_RESP_OK_C);
187  end if;
188 
189  when ADC_READ_S =>
190  if adcAck = '1' then
191  v.adcRdReq := '0';
192  v.axilReadSlave.rdata(7 downto 0) := adcRdData(7 downto 0);
193  v.state := ADC_IDLE_S;
194  axiSlaveReadResponse(v.axilReadSlave, AXI_RESP_OK_C);
195  end if;
196 
197  when others => null;
198  end case;
199 
200  if (axilRst = '1') then
201  v := REG_INIT_C;
202  end if;
203 
204  rin <= v;
205 
208  adcPdwn <= r.pdwn;
209 
210  adcWrReq <= r.adcWrReq;
211  adcRdReq <= r.adcRdReq;
212  adcWrData <= r.wrData(7 downto 0);
213  adcAddr <= r.wrData(20 downto 8);
214 
215 
216  end process comb;
217 
218  seq : process (axilClk) is
219  begin
220  if (rising_edge(axilClk)) then
221  r <= rin after TPD_G;
222  end if;
223  end process seq;
224 
225 
226 
227  -- Generate clock enable for state machine
228  process(axilClk)
229  begin
230  if rising_edge(axilClk) then
231  if axilRst = '1' then
232  sclkCounter <= (others => '0');
233  axilClkEn <= '0';
234  else
235  if (sclkCounter = SPI_CLK_PERIOD_DIV2_CYCLES_C) then
236  sclkCounter <= (others => '0');
237  axilClkEn <= '1';
238  else
239  sclkCounter <= sclkCounter + 1;
240  axilClkEn <= '0';
241  end if;
242  end if;
243  end if;
244  end process;
245 
246  -- Output Data
247  adcRdData <= intShift(7 downto 0);
248 
249  -- ADC data
250  adcSDout <= locSDout when adcSDir = '0' else '1';
251  -- Enable for the top level tri-state
252  adcSDEn <= ite(DEN_POLARITY_G = '1', not adcSDir, adcSDir);
253 
254  -- Control shift memory register
255  process (axilClk)
256  begin
257  if rising_edge(axilClk) then
258  if axilRst = '1' then
259  adcAck <= '0' after TPD_G;
260  adcSDir <= '0' after TPD_G;
261  locSDout <= '0' after TPD_G;
262  adcSClk <= '0' after TPD_G;
263  adcCsb <= (others => '1') after TPD_G;
264  nextClk <= '1' after TPD_G;
265  shiftCnt <= (others => '0') after TPD_G;
266  shiftCntEn <= '0' after TPD_G;
267  intShift <= (others => '0') after TPD_G;
268  curState <= ST_IDLE after TPD_G;
269  elsif axilClkEn = '1' then
270 
271  -- Next state
272  curState <= nxtState after TPD_G;
273  adcAck <= nextAck after TPD_G;
274 
275  -- Shift count is not enabled
276  if shiftCntEn = '0' then
277  adcSClk <= '0' after TPD_G;
278  locSDout <= '0' after TPD_G;
279  adcSDir <= '0' after TPD_G;
280  adcCsb <= (others => '1') after TPD_G;
281  nextClk <= '1' after TPD_G;
282 
283  -- Wait for shift request
284  if shiftEn = '1' then
285  shiftCntEn <= '1' after TPD_G;
286  shiftCnt <= (others => '0') after TPD_G;
287  intShift(23) <= adcRdReq after TPD_G;
288  intShift(22 downto 21) <= "00" after TPD_G;
289  intShift(20 downto 8) <= adcAddr after TPD_G;
290  intShift(7 downto 0) <= adcWrData after TPD_G;
291  end if;
292  else
293  shiftCnt <= shiftCnt + 1 after TPD_G;
294 
295  -- Clock 0, setup output
296  if shiftCnt(7 downto 0) = 0 then
297 
298  -- Clock goes back to zero
299  adcSClk <= '0' after TPD_G;
300 
301  -- Shift Count 0-23, output and shift data
302  if shiftCnt(12 downto 8) < 24 then
303  locSDout <= intShift(23) after TPD_G;
304  intShift <= intShift(22 downto 0) & adcSDin after TPD_G;
305  adcCsb <= not (decode(r.chipSel)(NUM_CHIPS_G*2-1 downto 0)) after TPD_G;
306  nextClk <= '1' after TPD_G;
307 
308  -- Done, Sample last value
309  else
310  intShift <= intShift(22 downto 0) & adcSDin after TPD_G;
311  locSDout <= '0' after TPD_G;
312  adcCsb <= (others => '1') after TPD_G;
313  nextClk <= '0' after TPD_G;
314  end if;
315 
316  -- Clock 3, clock output
317  elsif shiftCnt(7 downto 0) = 8 then
318  adcSClk <= nextClk after TPD_G;
319 
320  -- Tristate after 16 bits if read
321  if shiftCnt(12 downto 8) = 15 and adcRdReq = '1' then
322  adcSDir <= '1' after TPD_G;
323  end if;
324 
325  -- Stop counter
326  if shiftCnt(12 downto 8) = 24 then
327  shiftCntEn <= '0' after TPD_G;
328  end if;
329  end if;
330  end if;
331  end if;
332  end if;
333  end process;
334 
335 
336  -- State machine control
337  process (curState, adcWrReq, adcRdReq, shiftCntEn)
338  begin
339  case curState is
340 
341  -- IDLE, wait for request
342  when ST_IDLE =>
343  nextAck <= '0';
344 
345  -- Shift Request
346  if adcWrReq = '1' or adcRdReq = '1' then
347  shiftEn <= '1';
348  nxtState <= ST_SHIFT;
349  else
350  shiftEn <= '0';
351  nxtState <= curState;
352  end if;
353 
354  -- Shifting Data
355  when ST_SHIFT =>
356  nextAck <= '0';
357  shiftEn <= '0';
358 
359  -- Wait for shift to be done
360  if shiftCntEn = '0' then
361  nxtState <= ST_DONE;
362  else
363  nxtState <= curState;
364  end if;
365 
366  -- Done
367  when ST_DONE =>
368  nextAck <= '1';
369  shiftEn <= '0';
370 
371  -- Wait for request to go away
372  if adcRdReq = '0' and adcWrReq = '0' then
373  nxtState <= ST_IDLE;
374  else
375  nxtState <= curState;
376  end if;
377 
378  when others =>
379  nextAck <= '0';
380  shiftEn <= '0';
381  nxtState <= ST_IDLE;
382  end case;
383  end process;
384 
385 end architecture rtl;
386 
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
in axilReadMasterAxiLiteReadMasterType
in axilWriteMasterAxiLiteWriteMasterType
AXIL_ERR_RESP_Gslv( 1 downto 0) := AXI_RESP_DECERR_C
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
out axilReadSlaveAxiLiteReadSlaveType
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
slv( 1 downto 0) := "11" AXI_RESP_DECERR_C
Definition: AxiLitePkg.vhd:49
out adcCsbstd_logic_vector( NUM_CHIPS_G* 2- 1 downto 0)
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
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
out adcPdwnstd_logic_vector( NUM_CHIPS_G- 1 downto 0)
CLK_EN_PERIOD_Greal := 16.0e-9
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
_library_ ieeeieee
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:156
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
out axilWriteSlaveAxiLiteWriteSlaveType