SURF  1.0
AxiAd5780Ser.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiAd5780Ser.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-04-18
5 -- Last update: 2014-04-25
6 -------------------------------------------------------------------------------
7 -- Description: AD5780 DAC Module's serializer
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.AxiAd5780Pkg.all;
25 
26 --! @see entity
27  --! @ingroup devices_AnalogDevices_ad5780
28 entity AxiAd5780Ser is
29  generic (
30  TPD_G : time := 1 ns;
31  AXI_CLK_FREQ_G : real := 200.0E+6); -- units of Hz
32  port (
33  -- DAC Ports
36  -- DAC Data Interface (axiClk domain)
37  halfSckPeriod : in slv(31 downto 0);
38  sdoDisable : in sl;
41  opGnd : in sl;
42  rbuf : in sl;
43  dacData : in slv(17 downto 0); -- 2's complement by default
44  dacUpdated : out sl;
45  -- Clocks and Resets
46  axiClk : in sl;
47  axiRst : in sl;
48  dacRst : in sl);
49 end AxiAd5780Ser;
50 
51 architecture rtl of AxiAd5780Ser is
52 
53  constant CS_WAIT_C : natural := (getTimeRatio(AXI_CLK_FREQ_G, 20.0E+6)); -- 50 ns wait min.
54 
55  type StateType is (
56  RST_S,
57  RST_WAIT_S,
58  SCK_HIGH_S,
59  SCK_LOW_S,
60  CS_HI_S);
61  type RegType is record
62  rstL : sl;
63  csL : sl;
64  sck : sl;
65  sdi : sl;
66  dacUpdated : sl;
67  cnt : slv(7 downto 0);
68  cntSck : slv(31 downto 0);
69  csWait : natural range 0 to CS_WAIT_C;
70  reg : slv(23 downto 0);
71  state : StateType;
72  end record;
73  constant REG_INIT_C : RegType := (
74  '0',
75  '1',
76  '1',
77  '1',
78  '0',
79  (others => '0'),
80  (others => '0'),
81  0,
82  (others => '0'),
83  RST_S);
84  signal r : RegType := REG_INIT_C;
85  signal rin : RegType;
86 
87 begin
88 
90  sdoDisable) is
91  variable v : RegType;
92  begin
93  -- Latch the current value
94  v := r;
95 
96  -- Reset strobe signals
97  v.dacUpdated := '0';
98 
99  -- State Machine
100  case (r.state) is
101  ----------------------------------------------------------------------
102  when RST_S =>
103  -- Increment counter
104  v.cntSck := r.cntSck + 1;
105  if r.cntSck = 255 then
106  -- Reset the counter
107  v.cntSck := (others => '0');
108  -- Increment counter
109  v.cnt := r.cnt + 1;
110  if r.cnt = 255 then
111  -- Reset the counter
112  v.cnt := (others => '0');
113  -- Release the Reset
114  v.rstL := '1';
115  -- Next state
116  v.state := RST_WAIT_S;
117  end if;
118  end if;
119  ----------------------------------------------------------------------
120  when RST_WAIT_S =>
121  -- Preset the serial bit
122  v.sdi := '0';
123  -- Increment counter
124  v.cntSck := r.cntSck + 1;
125  if r.cntSck = 255 then
126  -- Reset the counter
127  v.cntSck := (others => '0');
128  -- Increment counter
129  v.cnt := r.cnt + 1;
130  if r.cnt = 255 then
131  -- Reset the counter
132  v.cnt := (others => '0');
133  -- Configure the DAC
134  v.reg(23 downto 20) := "0010"; -- CTRL_REG: write to control register
135  v.reg(19 downto 6) := (others => '0'); -- Reserved: reserved should be set to zero
136  -- Configuration bits
137  v.reg(5) := sdoDisable; -- SDODIS: disable SDO
138  v.reg(4) := binaryOffset; -- BIN/2sC: use 2's complement
139  v.reg(3) := dacTriState; -- DACTRI: put DAC into normal operating mode
140  v.reg(2) := opGnd; -- OPGND: put DAC into normal operating mode
141  v.reg(1) := rbuf; -- RBUF: Unity-Gain Configuration
142  v.reg(0) := '0'; -- Reserved: reserved should be set to zero
143  -- Set the chip select flag
144  v.csL := '0';
145  -- Preset the counter
146  v.cntSck := halfSckPeriod;
147  -- Next state
148  v.state := SCK_HIGH_S;
149  end if;
150  end if;
151  ----------------------------------------------------------------------
152  when SCK_HIGH_S =>
153  -- High phase of SCK
154  v.sck := '1';
155  -- Set the serial bit
156  v.sdi := r.reg(23);
157  -- Increment counter
158  v.cntSck := r.cntSck + 1;
159  if r.cntSck = halfSckPeriod then
160  if r.cnt = 23 then
161  -- Preset the counter
162  v.cntSck := halfSckPeriod;
163  else
164  -- Reset the counter
165  v.cntSck := (others => '0');
166  end if;
167  -- Next state
168  v.state := SCK_LOW_S;
169  end if;
170  ----------------------------------------------------------------------
171  when SCK_LOW_S =>
172  -- Low phase of SCK
173  v.sck := '0';
174  -- Increment counter
175  v.cntSck := r.cntSck + 1;
176  if r.cntSck = halfSckPeriod then
177  -- Reset the counter
178  v.cntSck := (others => '0');
179  -- Shift Register
180  v.reg(23 downto 1) := r.reg(22 downto 0);
181  v.reg(0) := '0';
182  -- Increment counter
183  v.cnt := r.cnt + 1;
184  if r.cnt = 23 then
185  -- Reset the counter
186  v.cnt := (others => '0');
187  -- Next state
188  v.state := CS_HI_S;
189  else
190  -- Next state
191  v.state := SCK_HIGH_S;
192  end if;
193  end if;
194  ----------------------------------------------------------------------
195  when CS_HI_S =>
196  -- High phase of SCK
197  v.sck := '1';
198  -- Release the chip select
199  v.csL := '1';
200  -- Preset the serial bit
201  v.sdi := '0';
202  -- Increment counter
203  v.csWait := r.csWait + 1;
204  if r.csWait = CS_WAIT_C then
205  -- Reset the counter
206  v.csWait := 0;
207  -- Latch the DAC data
208  v.reg := "0001" & dacData & "00";
209  -- Set the chip select flag
210  v.csL := '0';
211  -- Preset the counter
212  v.cntSck := halfSckPeriod;
213  -- Strobe the refresh flag
214  v.dacUpdated := '1';
215  -- Next state
216  v.state := SCK_HIGH_S;
217  end if;
218  ----------------------------------------------------------------------
219  end case;
220 
221  -- Synchronous Reset
222  if dacRst = '1' then
223  v := REG_INIT_C;
224  end if;
225 
226  -- Register the variable for next clock cycle
227  rin <= v;
228 
229  -- Outputs
230  dacUpdated <= r.dacUpdated;
231 
232  dacOut.dacSync <= r.csL;
233  dacOut.dacSclk <= r.sck;
234  dacOut.dacSdi <= r.sdi;
235  dacOut.dacLdac <= '0';
236  dacOut.dacClr <= '1';
237  dacOut.dacRst <= r.rstL;
238 
239  end process comb;
240 
241  seq : process (axiClk) is
242  begin
243  if rising_edge(axiClk) then
244  r <= rin after TPD_G;
245  end if;
246  end process seq;
247 
248 end rtl;
in dacTriStatesl
out dacUpdatedsl
_library_ ieeeieee
std_logic sl
Definition: StdRtlPkg.vhd:28
in sdoDisablesl
in dacInAxiAd5780InType
in dacDataslv( 17 downto 0)
in binaryOffsetsl
in halfSckPeriodslv( 31 downto 0)
AXI_CLK_FREQ_Greal := 200.0E+6
out dacOutAxiAd5780OutType
TPD_Gtime := 1 ns
std_logic_vector slv
Definition: StdRtlPkg.vhd:29