SURF  1.0
Ad9249Config.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : Ad9249Config.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
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 library UNISIM;
24 use UNISIM.VCOMPONENTS.all;
25 
26 use work.StdRtlPkg.all;
27 use work.AxiLitePkg.all;
28 
29 --! @see entity
30  --! @ingroup devices_AnalogDevices_ad9249
31 entity Ad9249Config is
32 
33  generic (
34  TPD_G : time := 1 ns;
35  NUM_CHIPS_G : positive := 1;
36  SCLK_PERIOD_G : real := 1.0e-6;
37  AXIL_CLK_PERIOD_G : real := 8.0e-9;
39  port (
40  axilClk : in sl;
41  axilRst : in sl;
42 
47 
48  adcPdwn : out slv(NUM_CHIPS_G-1 downto 0);
49  adcSclk : out sl;
50  adcSdio : inout sl;
51  adcCsb : out slv(NUM_CHIPS_G*2-1 downto 0)
52 
53  );
54 
55 end entity Ad9249Config;
56 
57 architecture rtl of Ad9249Config is
58 
59  -- AdcCore Outputs
60  signal rdData : slv(23 downto 0);
61  signal rdEn : sl;
62 
63  -- Adc Core Chip IO
64  signal coreSclk : sl;
65  signal coreSDin : sl;
66  signal coreSDout : sl;
67  signal coreCsb : slv(NUM_CHIPS_G*2-1 downto 0);
68  signal sdioDir : sl;
69  signal shiftCount : slv(bitSize(24)-1 downto 0);
70 
71 
72  constant CHIP_SEL_WIDTH_C : integer := log2(NUM_CHIPS_G*2);
73  constant PWDN_ADDR_BIT_C : integer := 11 + CHIP_SEL_WIDTH_C;
74  constant PWDN_ADDR_C : slv(PWDN_ADDR_BIT_C downto 0) := toSlv(2**PWDN_ADDR_BIT_C, PWDN_ADDR_BIT_C+1);
75 
76  type StateType is (WAIT_AXI_TXN_S, WAIT_CYCLE_S, WAIT_SPI_TXN_DONE_S);
77 
78  -- Registers
79  type RegType is record
80  state : StateType;
83  -- Adc Core Inputs
84  chipSel : slv(CHIP_SEL_WIDTH_C-1 downto 0);
85  wrData : slv(23 downto 0);
86  wrEn : sl;
87  pdwn : slv(NUM_CHIPS_G-1 downto 0);
88  end record RegType;
89 
90  constant REG_INIT_C : RegType := (
91  state => WAIT_AXI_TXN_S,
94  chipSel => (others => '0'),
95  wrData => (others => '0'),
96  wrEn => '0',
97  pdwn => (others => '0'));
98 
99  signal r : RegType := REG_INIT_C;
100  signal rin : RegType;
101 
102 begin
103 
104  comb : process (axilRst, axilReadMaster, axilWriteMaster, r, rdData, rdEn) is
105  variable v : RegType;
106  variable axilEp : AxiLiteEndpointType;
107  begin
108  v := r;
109 
110  axiSlaveWaitTxn(axilEp, axilWriteMaster, axilReadMaster, v.axilWriteSlave, v.axilReadSlave);
111 
112 
113  case (r.state) is
114  when WAIT_AXI_TXN_S =>
115 
116  -- Chip powerdown signal is local registers
117  for i in 0 to NUM_CHIPS_G-1 loop
118  axiSlaveRegister(axilEp, PWDN_ADDR_C + i*4, 0, v.pdwn(i));
119  end loop;
120 
121  -- Any other address is forwarded to the chip via SPI
122  if (axilEp.axiStatus.writeEnable = '1' and axilWriteMaster.awaddr(PWDN_ADDR_BIT_C) = '0') then
123  v.wrData(23) := '0'; -- Write bit
124  v.wrData(22 downto 21) := "00"; -- Number of bytes (1)
125  v.wrData(20 downto 17) := "0000"; -- Unused address bits
126  v.wrData(16 downto 8) := axilWriteMaster.awaddr(10 downto 2); -- Address
127  v.wrData(7 downto 0) := axilWriteMaster.wdata(7 downto 0); -- Data
128  v.chipSel := axilWriteMaster.awaddr(11+CHIP_SEL_WIDTH_C-1 downto 11); -- Bank select
129  v.wrEn := '1';
130  v.state := WAIT_CYCLE_S;
131  end if;
132 
133  if (axilEp.axiStatus.readEnable = '1' and axilReadMaster.araddr(PWDN_ADDR_BIT_C) = '0') then
134  v.wrData(23) := '1'; -- read bit
135  v.wrData(22 downto 21) := "00"; -- Number of bytes (1)
136  v.wrData(20 downto 17) := "0000"; -- Unused address bits
137  v.wrData(16 downto 8) := axilReadMaster.araddr(10 downto 2); -- Address
138  v.wrData(7 downto 0) := (others => '1'); -- Make bus float to Z so slave can
139  -- drive during data segment
140  v.chipSel := axilReadMaster.araddr(11+CHIP_SEL_WIDTH_C-1 downto 11); -- Bank Select
141  v.wrEn := '1';
142  v.state := WAIT_CYCLE_S;
143  end if;
144 
145  axiSlaveDefault(axilEp, v.axilWriteSlave, v.axilReadSlave, AXIL_ERR_RESP_G, v.wrEn);
146 
147  when WAIT_CYCLE_S =>
148  -- Wait 1 cycle for rdEn to drop
149  v.wrEn := '0';
150  v.state := WAIT_SPI_TXN_DONE_S;
151 
152  when WAIT_SPI_TXN_DONE_S =>
153 
154  if (rdEn = '1') then
155  v.state := WAIT_AXI_TXN_S;
156  if (r.wrData(23) = '0') then
157  -- Finish write
158  axiSlaveWriteResponse(axilEp.axiWriteSlave);
159  v.axilWriteSlave := axilEp.axiWriteSlave;
160  else
161  -- Finish read
162  axilEp.axiReadSlave.rdata := (others => '0');
163  axilEp.axiReadSlave.rdata(7 downto 0) := rdData(7 downto 0);
164  axiSlaveReadResponse(axilEp.axiReadSlave);
165  v.axilReadSlave := axilEp.axiReadSlave;
166  end if;
167  end if;
168 
169  when others => null;
170  end case;
171 
172 
173 
174  if (axilRst = '1') then
175  v := REG_INIT_C;
176  end if;
177 
178  rin <= v;
179 
182  adcPdwn <= r.pdwn;
183 
184 
185  end process comb;
186 
187  seq : process (axilClk) is
188  begin
189  if (rising_edge(axilClk)) then
190  r <= rin after TPD_G;
191  end if;
192  end process seq;
193 
194  SpiMaster_1 : entity work.SpiMaster
195  generic map (
196  TPD_G => TPD_G,
197  NUM_CHIPS_G => NUM_CHIPS_G*2,
198  DATA_SIZE_G => 24,
199  CPHA_G => '0', -- Sample on leading edge
200  CPOL_G => '0', -- Sample on rising edge
203  port map (
204  clk => axilClk,
205  sRst => axilRst,
206  chipSel => r.chipSel,
207  wrEn => r.wrEn,
208  wrData => r.wrData,
209  rdEn => rdEn,
210  rdData => rdData,
211  shiftCount => shiftCount,
212  spiCsL => coreCsb,
213  spiSclk => coreSclk,
214  spiSdi => coreSDout,
215  spiSdo => coreSDin);
216 
217  -- Bus lines float to Z when not being driven to '0'.
218  -- Lines should all have resistor pullups off chip
219 -- SCLK_OBUFT : OBUFT
220 -- port map (
221 -- I => '0',
222 -- O => adcSclk,
223 -- T => coreSclk);
224  adcSclk <= coreSclk;
225 
226  -- Allow input when doing a read and in the data segment of the shift operation
227  sdioDir <= '1' when shiftCount >= 16 and r.wrData(23)='1' else '0';
228  SDIO_IOBUFT : IOBUF
229  port map (
230  I => coreSDout,
231  O => coreSDin,
232  IO => adcSdio,
233  T => sdioDir);
234 
235 -- CSB_OBUFT : for i in NUM_CHIPS_G*2-1 downto 0 generate
236 -- CSB0_OBUFT : OBUFT
237 -- port map (
238 -- I => '0',
239 -- O => adcCsb(i),
240 -- T => coreCsb(i));
241 -- end generate;
242  adcCsb <= coreCsb;
243 
244 end architecture rtl;
AXIL_ERR_RESP_Gslv( 1 downto 0) := AXI_RESP_DECERR_C
out spiCsLslv( NUM_CHIPS_G- 1 downto 0)
Definition: SpiMaster.vhd:49
out adcPdwnslv( NUM_CHIPS_G- 1 downto 0)
in wrDataslv( DATA_SIZE_G- 1 downto 0)
Definition: SpiMaster.vhd:43
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
AXIL_CLK_PERIOD_Greal := 8.0e-9
in wrEnsl
Definition: SpiMaster.vhd:42
SPI_SCLK_PERIOD_Greal := 1.0E-6
Definition: SpiMaster.vhd:35
AxiLiteReadSlaveType axiReadSlave
Definition: AxiLitePkg.vhd:180
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
AxiLiteStatusType axiStatus
Definition: AxiLitePkg.vhd:183
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
out axilWriteSlaveAxiLiteWriteSlaveType
CPOL_Gsl := '0'
Definition: SpiMaster.vhd:33
_library_ ieeeieee
AxiLiteWriteSlaveType axiWriteSlave
Definition: AxiLitePkg.vhd:182
slv( 1 downto 0) := "11" AXI_RESP_DECERR_C
Definition: AxiLitePkg.vhd:49
out adcSclksl
TPD_Gtime := 1 ns
Definition: SpiMaster.vhd:29
SCLK_PERIOD_Greal := 1.0e-6
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
NUM_CHIPS_Gpositive range 1 to 8:= 4
Definition: SpiMaster.vhd:30
slv( 31 downto 0) awaddr
Definition: AxiLitePkg.vhd:113
inout adcSdiosl
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:95
out shiftCountslv( bitSize(DATA_SIZE_G )- 1 downto 0)
Definition: SpiMaster.vhd:47
TPD_Gtime := 1 ns
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
out spiSclksl
Definition: SpiMaster.vhd:50
DATA_SIZE_Gnatural := 16
Definition: SpiMaster.vhd:31
out adcCsbslv( NUM_CHIPS_G* 2- 1 downto 0)
out spiSdisl
Definition: SpiMaster.vhd:51
in axilWriteMasterAxiLiteWriteMasterType
NUM_CHIPS_Gpositive := 1
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
out axilReadSlaveAxiLiteReadSlaveType
in axilReadMasterAxiLiteReadMasterType
in clksl
Definition: SpiMaster.vhd:38
in sRstsl
Definition: SpiMaster.vhd:39
CLK_PERIOD_Greal := 8.0E-9
Definition: SpiMaster.vhd:34
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