SURF  1.0
AxiAd9467Reg.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiAd9467Reg.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-09-23
5 -- Last update: 2014-09-24
6 -------------------------------------------------------------------------------
7 -- Description: AD9467 AXI-Lite Register Access Module
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_unsigned.all;
21 use ieee.std_logic_arith.all;
22 
23 use work.StdRtlPkg.all;
24 use work.AxiLitePkg.all;
25 use work.AxiAd9467Pkg.all;
26 
27 --! @see entity
28  --! @ingroup devices_AnalogDevices_ad9467
29 entity AxiAd9467Reg is
30  generic (
31  TPD_G : time := 1 ns;
32  DEMUX_INIT_G : sl := '0';
33  DELAY_INIT_G : Slv5Array(0 to 7) := (others => "00000");
34  STATUS_CNT_WIDTH_G : natural range 1 to 32 := 32;
36  port (
37  -- AXI-Lite Register Interface (axiClk domain)
38  axiClk : in sl;
39  axiRst : in sl;
44  -- Register Inputs/Outputs (axiClk domain)
46  config : out AxiAd9467ConfigType;
47  -- Global Signals
48  adcClk : in sl;
49  adcRst : in sl;
50  refClk200MHz : in sl);
51 end AxiAd9467Reg;
52 
53 architecture rtl of AxiAd9467Reg is
54 
55  function CompressAddressSpace (vec : slv(7 downto 0)) return slv is
56  variable retVar : slv(11 downto 0) := x"0FF";
57  begin
58  case (vec) is
59  -- chip_port_config register
60  when x"00" =>
61  retVar := x"000";
62  -- chip_id register
63  when x"01" =>
64  retVar := x"001";
65  -- chip_grade register
66  when x"02" =>
67  retVar := x"002";
68  -- device_update register
69  when x"03" =>
70  retVar := x"0FF";
71  -- modes register
72  when x"04" =>
73  retVar := x"008";
74  -- test_io register
75  when x"05" =>
76  retVar := x"00D";
77  -- adc_input register
78  when x"06" =>
79  retVar := x"00F";
80  -- offset register
81  when x"07" =>
82  retVar := x"010";
83  -- output_mode register
84  when x"08" =>
85  retVar := x"014";
86  -- output_adjust register
87  when x"09" =>
88  retVar := x"015";
89  -- output_phase register
90  when x"0A" =>
91  retVar := x"016";
92  -- vref register
93  when x"0B" =>
94  retVar := x"018";
95  -- analog_input register
96  when x"0C" =>
97  retVar := x"02C";
98  -- Buffer Current Select 1 register
99  when x"0D" =>
100  retVar := x"036";
101  -- Buffer Current Select 2 register
102  when x"0E" =>
103  retVar := x"107";
104  -- Unmapped
105  when others =>
106  retVar := x"0FF";
107  end case;
108  return retVar;
109  end function;
110 
111  type StateType is (
112  IDLE_S,
113  REQ_S,
114  ACK_S);
115 
116  type RegType is record
117  config : AxiAd9467ConfigType;
118  state : StateType;
121  end record RegType;
122 
123  constant REG_INIT_C : RegType := (
125  IDLE_S,
128 
129  signal r : RegType := REG_INIT_C;
130  signal rin : RegType;
131 
133 
134 begin
135 
136  -------------------------------
137  -- Configuration Register
138  -------------------------------
139  comb : process (axiReadMaster, axiRst, axiWriteMaster, r, syncIn) is
140  variable i : integer;
141  variable v : RegType;
142  variable axiStatus : AxiLiteStatusType;
143  variable axiWriteResp : slv(1 downto 0);
144  variable axiReadResp : slv(1 downto 0);
145  begin
146  -- Latch the current value
147  v := r;
148 
149  -- Determine the transaction type
151 
152  -- Reset strobe signals
153  v.config.delay.load := '0';
154  v.config.delay.rst := '0';
155 
156  if (axiStatus.writeEnable = '1') and (r.state = IDLE_S) then
157  -- Check for an out of 32 bit aligned address
158  axiWriteResp := ite(axiWriteMaster.awaddr(1 downto 0) = "00", AXI_RESP_OK_C, AXI_ERROR_RESP_G);
159  if (axiWriteMaster.awaddr(9 downto 2) < 15) then
160  v.config.spi.req := '1';
161  v.config.spi.RnW := '0';
162  v.config.spi.din := axiWriteMaster.wdata(7 downto 0);
163  v.config.spi.addr := CompressAddressSpace(axiWriteMaster.awaddr(9 downto 2));
164  v.state := REQ_S;
165  else
166  -- Decode address and perform write
167  case (axiWriteMaster.awaddr(9 downto 2)) is
168  when x"10" =>
169  v.config.delay.load := '1';
170  v.config.delay.rst := '1';
171  v.config.delay.data(0) := axiWriteMaster.wdata(4 downto 0);
172  when x"11" =>
173  v.config.delay.load := '1';
174  v.config.delay.rst := '1';
175  v.config.delay.data(1) := axiWriteMaster.wdata(4 downto 0);
176  when x"12" =>
177  v.config.delay.load := '1';
178  v.config.delay.rst := '1';
179  v.config.delay.data(2) := axiWriteMaster.wdata(4 downto 0);
180  when x"13" =>
181  v.config.delay.load := '1';
182  v.config.delay.rst := '1';
183  v.config.delay.data(3) := axiWriteMaster.wdata(4 downto 0);
184  when x"14" =>
185  v.config.delay.load := '1';
186  v.config.delay.rst := '1';
187  v.config.delay.data(4) := axiWriteMaster.wdata(4 downto 0);
188  when x"15" =>
189  v.config.delay.load := '1';
190  v.config.delay.rst := '1';
191  v.config.delay.data(5) := axiWriteMaster.wdata(4 downto 0);
192  when x"16" =>
193  v.config.delay.load := '1';
194  v.config.delay.rst := '1';
195  v.config.delay.data(6) := axiWriteMaster.wdata(4 downto 0);
196  when x"17" =>
197  v.config.delay.load := '1';
198  v.config.delay.rst := '1';
199  v.config.delay.data(7) := axiWriteMaster.wdata(4 downto 0);
200  when x"1F" =>
202  when others =>
203  axiWriteResp := AXI_ERROR_RESP_G;
204  end case;
205  -- Send AXI response
206  axiSlaveWriteResponse(v.axiWriteSlave, axiWriteResp);
207  end if;
208  elsif (axiStatus.readEnable = '1') and (r.state = IDLE_S) then
209  -- Check for an out of 32 bit aligned address
210  axiReadResp := ite(axiReadMaster.araddr(1 downto 0) = "00", AXI_RESP_OK_C, AXI_ERROR_RESP_G);
211  -- Reset the register
212  v.axiReadSlave.rdata := (others => '0');
213  if (axiReadMaster.araddr(9 downto 2) < 15) then
214  v.config.spi.req := '1';
215  v.config.spi.RnW := '1';
216  v.config.spi.din := (others => '0');
217  v.config.spi.addr := CompressAddressSpace(axiReadMaster.araddr(9 downto 2));
218  v.state := REQ_S;
219  else
220  -- Decode address and assign read data
221  case (axiReadMaster.araddr(9 downto 2)) is
222  when x"10" =>
223  v.axiReadSlave.rdata(4 downto 0) := syncIn.delay.data(0);
224  when x"11" =>
225  v.axiReadSlave.rdata(4 downto 0) := syncIn.delay.data(1);
226  when x"12" =>
227  v.axiReadSlave.rdata(4 downto 0) := syncIn.delay.data(2);
228  when x"13" =>
229  v.axiReadSlave.rdata(4 downto 0) := syncIn.delay.data(3);
230  when x"14" =>
231  v.axiReadSlave.rdata(4 downto 0) := syncIn.delay.data(4);
232  when x"15" =>
233  v.axiReadSlave.rdata(4 downto 0) := syncIn.delay.data(5);
234  when x"16" =>
235  v.axiReadSlave.rdata(4 downto 0) := syncIn.delay.data(6);
236  when x"17" =>
237  v.axiReadSlave.rdata(4 downto 0) := syncIn.delay.data(7);
238  when x"1D" =>
239  v.axiReadSlave.rdata(0) := syncIn.pllLocked;
240  when x"1E" =>
241  v.axiReadSlave.rdata(0) := syncIn.delay.rdy;
242  when x"1F" =>
243  v.axiReadSlave.rdata(0) := r.config.delay.dmux;
244  when x"20" =>
245  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(0);
246  when x"21" =>
247  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(1);
248  when x"22" =>
249  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(2);
250  when x"23" =>
251  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(3);
252  when x"24" =>
253  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(4);
254  when x"25" =>
255  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(5);
256  when x"26" =>
257  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(6);
258  when x"27" =>
259  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(7);
260  when x"28" =>
261  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(8);
262  when x"29" =>
263  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(9);
264  when x"2A" =>
265  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(10);
266  when x"2B" =>
267  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(11);
268  when x"2C" =>
269  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(12);
270  when x"2D" =>
271  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(13);
272  when x"2E" =>
273  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(14);
274  when x"2F" =>
275  v.axiReadSlave.rdata(15 downto 0) := syncIn.adcDataMon(15);
276  when others =>
277  axiReadResp := AXI_ERROR_RESP_G;
278  end case;
279  -- Send Axi Response
280  axiSlaveReadResponse(v.axiReadSlave, axiReadResp);
281  end if;
282  end if;
283 
284  -- State Machine
285  case (r.state) is
286  ----------------------------------------------------------------------
287  when IDLE_S =>
288  null;
289  ----------------------------------------------------------------------
290  when REQ_S =>
291  -- Assert the flag
292  v.config.spi.req := '1';
293  -- Next State
294  v.state := ACK_S;
295  ----------------------------------------------------------------------
296  when ACK_S =>
297  -- De-assert the flag
298  v.config.spi.req := '0';
299  -- Check for ack strobe
300  if syncIn.spi.ack = '1' then
301  -- Check if we need to perform a read or write response
302  if v.config.spi.RnW = '0' then
303  axiSlaveWriteResponse(v.axiWriteSlave);
304  else
305  v.axiReadSlave.rdata(7 downto 0) := syncIn.spi.dout;
306  axiSlaveReadResponse(v.axiReadSlave);
307  end if;
308  -- Next State
309  v.state := IDLE_S;
310  end if;
311  ----------------------------------------------------------------------
312  end case;
313 
314  -- Synchronous Reset
315  if axiRst = '1' then
316  v := REG_INIT_C;
317  v.config.delay.load := '1';
318  v.config.delay.rst := '1';
321  end if;
322 
323  -- Register the variable for next clock cycle
324  rin <= v;
325 
326  -- Outputs
329 
330  end process comb;
331 
332  seq : process (axiClk) is
333  begin
334  if rising_edge(axiClk) then
335  r <= rin after TPD_G;
336  end if;
337  end process seq;
338 
339  -------------------------------
340  -- Synchronization: Outputs
341  -------------------------------
342  config.spi <= r.config.spi;
343 
344  SyncIn_delay_dmux : entity work.Synchronizer
345  generic map (
346  TPD_G => TPD_G)
347  port map (
348  clk => refClk200MHz,
349  dataIn => r.config.delay.dmux,
350  dataOut => config.delay.dmux);
351 
352  SyncOut_delayIn_load : entity work.RstSync
353  generic map (
354  TPD_G => TPD_G,
355  RELEASE_DELAY_G => 32)
356  port map (
357  clk => refClk200MHz,
358  asyncRst => r.config.delay.load,
359  syncRst => config.delay.load);
360 
361  SyncOut_delayIn_rst : entity work.RstSync
362  generic map (
363  TPD_G => TPD_G,
364  RELEASE_DELAY_G => 16)
365  port map (
366  clk => refClk200MHz,
367  asyncRst => r.config.delay.rst,
368  syncRst => config.delay.rst);
369 
370  GEN_DAT_CONFIG :
371  for i in 0 to 7 generate
372  SyncOut_delayIn_data : entity work.SynchronizerFifo
373  generic map (
374  TPD_G => TPD_G,
375  DATA_WIDTH_G => 5)
376  port map (
377  wr_clk => axiClk,
378  din => r.config.delay.data(i),
379  rd_clk => refClk200MHz,
380  dout => config.delay.data(i));
381  end generate GEN_DAT_CONFIG;
382 
383  -------------------------------
384  -- Synchronization: Inputs
385  -------------------------------
386  syncIn.spi <= status.spi;
387 
388  SyncIn_pllLocked : entity work.Synchronizer
389  generic map (
390  TPD_G => TPD_G)
391  port map (
392  clk => axiClk,
393  dataIn => status.pllLocked,
394  dataOut => syncIn.pllLocked);
395 
396  GEN_ADC_MON :
397  for i in 0 to 15 generate
398  SyncIn_adcDataMon : entity work.SynchronizerFifo
399  generic map (
400  TPD_G => TPD_G,
401  DATA_WIDTH_G => 16)
402  port map (
403  wr_clk => adcClk,
404  din => status.adcDataMon(i),
405  rd_clk => axiClk,
406  dout => syncIn.adcDataMon(i));
407  end generate GEN_ADC_MON;
408 
409  SyncIn_delayOut_rdy : entity work.Synchronizer
410  generic map (
411  TPD_G => TPD_G)
412  port map (
413  clk => axiClk,
414  dataIn => status.delay.rdy,
415  dataOut => syncIn.delay.rdy);
416 
417  GEN_DAT_STATUS :
418  for i in 0 to 7 generate
419  SyncIn_delayOut_data : entity work.SynchronizerFifo
420  generic map (
421  TPD_G => TPD_G,
422  DATA_WIDTH_G => 5)
423  port map (
424  wr_clk => refClk200MHz,
425  din => status.delay.data(i),
426  rd_clk => axiClk,
427  dout => syncIn.delay.data(i));
428  end generate GEN_DAT_STATUS;
429 
430 end rtl;
in statusAxiAd9467StatusType
in refClk200MHzsl
slv( 7 downto 0) din
AxiAd9467ConfigType :=(spi => AXI_AD9467_SPI_IN_INIT_C,delay => AXI_AD9467_DELAY_IN_INIT_C) AXI_AD9467_CONFIG_INIT_C
out syncRstsl
Definition: RstSync.vhd:36
AxiAd9467DelayOutType delay
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
in dinslv( DATA_WIDTH_G- 1 downto 0)
Slv16Array( 0 to 15) adcDataMon
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
AxiAd9467SpiOutType spi
in asyncRstsl
Definition: RstSync.vhd:35
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
out dataOutsl
out doutslv( DATA_WIDTH_G- 1 downto 0)
in clksl
Definition: RstSync.vhd:34
AxiLiteStatusType axiStatus
Definition: AxiLitePkg.vhd:183
DELAY_INIT_GSlv5Array( 0 to 7) :=( others => "00000")
TPD_Gtime := 1 ns
out axiReadSlaveAxiLiteReadSlaveType
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
Definition: AxiLitePkg.vhd:36
RELEASE_DELAY_Ginteger range 3 to positive'high:= 3
Definition: RstSync.vhd:31
STATUS_CNT_WIDTH_Gnatural range 1 to 32:= 32
in axiReadMasterAxiLiteReadMasterType
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
_library_ ieeeieee
in axiWriteMasterAxiLiteWriteMasterType
slv( 31 downto 0) awaddr
Definition: AxiLitePkg.vhd:113
TPD_Gtime := 1 ns
Definition: RstSync.vhd:27
TPD_Gtime := 1 ns
Slv5Array( 0 to 7) data
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:95
slv( 7 downto 0) dout
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
AxiAd9467StatusType :=(pllLocked => '0',adcData => x"0000",adcDataMon =>( others => x"0000"),spi => AXI_AD9467_SPI_OUT_INIT_C,delay => AXI_AD9467_DELAY_OUT_INIT_C) AXI_AD9467_STATUS_INIT_C
array(natural range <> ) of slv( 4 downto 0) Slv5Array
Definition: StdRtlPkg.vhd:406
DEMUX_INIT_Gsl := '0'
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
out configAxiAd9467ConfigType
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:156
out axiWriteSlaveAxiLiteWriteSlaveType
slv( 11 downto 0) addr
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
std_logic_vector slv
Definition: StdRtlPkg.vhd:29