SURF  1.0
AxiAd9467Spi.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiAd9467Spi.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2013-05-23
5 -- Last update: 2014-09-24
6 -------------------------------------------------------------------------------
7 -- Description: AD9467 SPI Interface 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.AxiAd9467Pkg.all;
25 
26 library unisim;
27 use unisim.vcomponents.all;
28 
29 --! @see entity
30  --! @ingroup devices_AnalogDevices_ad9467
31 entity AxiAd9467Spi is
32  generic (
33  TPD_G : time := 1 ns;
34  AXI_CLK_FREQ_G : real := 125.0E+6);
35  port (
36  --ADC SPI I/O ports
37  adcCs : out sl;
38  adcSck : out sl;
39  adcSdio : inout sl;
40  -- AXI-Lite Interface
41  axiClk : in sl;
42  axiRst : in sl;
45 end AxiAd9467Spi;
46 
47 architecture rtl of AxiAd9467Spi is
48 
49  constant MAX_CNT_C : natural := getTimeRatio(AXI_CLK_FREQ_G, 50.0E+6);
50 
51  type StateType is (
52  IDLE_S,
53  SCK_LOW_S,
54  SCK_HIGH_S,
55  HANDSHAKE_S);
56 
57  signal state : StateType := IDLE_S;
58  signal cs,
59  sck,
60  sdi,
61  sdo,
62  inEn : sl := '0';
63  signal r : AxiAd9467SpiOutType;
64  signal pntr : slv(7 downto 0) := (others => '0');
65  signal cnt : natural range 0 to MAX_CNT_C := 0;
66 
67 begin
68 
69  adcCs <= cs;
70  adcSck <= sck;
71  adcSpiOut <= r;
72 
73  IOBUF_inst : IOBUF
74  port map (
75  O => sdo, -- Buffer output
76  IO => adcSdio, -- Buffer inout port (connect directly to top-level port)
77  I => sdi, -- Buffer input
78  T => inEn); -- 3-state enable input, high=input, low=output
79 
80  process(axiClk)
81  begin
82  if rising_edge(axiClk) then
83  if axiRst = '1' then
84  cs <= '1' after TPD_G;
85  sck <= '0' after TPD_G;
86  sdi <= '0' after TPD_G;
87  inEn <= '0' after TPD_G;
88  cnt <= 0 after TPD_G;
89  pntr <= (others => '0') after TPD_G;
90  r.dout <= (others => '0') after TPD_G;
91  state <= IDLE_S;
92  else
93  case (state) is
94  ----------------------------------------------------------------------
95  when IDLE_S =>
96  if AdcSpiIn.req = '1' then
97  cs <= '0' after TPD_G;
98  r.dout <= (others => '0') after TPD_G;
99  state <= SCK_LOW_S after TPD_G;
100  end if;
101  ----------------------------------------------------------------------
102  when SCK_LOW_S =>
103  sck <= '0' after TPD_G;
104  if pntr > 15 then
105  inEn <= AdcSpiIn.RnW after TPD_G;
106  sdi <= AdcSpiIn.din(conv_integer(23-pntr)) after TPD_G;
107  elsif pntr > 3 then
108  sdi <= AdcSpiIn.addr(conv_integer(15-pntr)) after TPD_G;
109  elsif pntr = 0 then
110  sdi <= AdcSpiIn.RnW after TPD_G;
111  else
112  sdi <= '0' after TPD_G;
113  end if;
114  cnt <= cnt + 1 after TPD_G;
115  -- Min. 20 ns wait
116  if cnt = MAX_CNT_C then
117  cnt <= 0 after TPD_G;
118  if pntr > 15 then
119  r.dout(conv_integer(23-pntr)) <= sdo after TPD_G;
120  end if;
121  state <= SCK_HIGH_S after TPD_G;
122  end if;
123  ----------------------------------------------------------------------
124  when SCK_HIGH_S =>
125  sck <= '1' after TPD_G;
126  cnt <= cnt + 1 after TPD_G;
127  -- Min. 20 ns wait
128  if cnt = MAX_CNT_C then
129  cnt <= 0 after TPD_G;
130  pntr <= pntr + 1 after TPD_G;
131  if pntr = 23 then
132  cs <= '1' after TPD_G;
133  pntr <= (others => '0') after TPD_G;
134  inEn <= '0' after TPD_G;
135  r.ack <= '1' after TPD_G;
136  state <= HANDSHAKE_S after TPD_G;
137  else
138  state <= SCK_LOW_S after TPD_G;
139  end if;
140  end if;
141  ----------------------------------------------------------------------
142  when HANDSHAKE_S =>
143  r.ack <= '1' after TPD_G;
144  if AdcSpiIn.req = '0' then
145  r.ack <= '0' after TPD_G;
146  sck <= '0' after TPD_G;
147  state <= IDLE_S after TPD_G;
148  end if;
149  ----------------------------------------------------------------------
150  end case;
151  end if;
152  end if;
153  end process;
154 
155 end rtl;
slv( 7 downto 0) din
AXI_CLK_FREQ_Greal := 125.0E+6
std_logic sl
Definition: StdRtlPkg.vhd:28
TPD_Gtime := 1 ns
slv( 7 downto 0) dout
out adcSpiOutAxiAd9467SpiOutType
inout adcSdiosl
in adcSpiInAxiAd9467SpiInType
_library_ ieeeieee
slv( 11 downto 0) addr
std_logic_vector slv
Definition: StdRtlPkg.vhd:29