SURF  1.0
AxiAds42lb69Reg.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiAds42lb69Reg.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2015-03-20
5 -- Last update: 2015-05-19
6 -------------------------------------------------------------------------------
7 -- Description: AXI-Lite Register Access
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.AxiAds42lb69Pkg.all;
26 
27 --! @see entity
28  --! @ingroup devices_Ti_ads42lb69
29 entity AxiAds42lb69Reg is
30  generic (
31  TPD_G : time := 1 ns;
32  SIM_SPEEDUP_G : boolean := false;
33  ADC_CLK_FREQ_G : real := 250.00E+6; -- units of Hz
34  DMODE_INIT_G : slv(1 downto 0) := "00";
36  port (
37  -- AXI-Lite Register Interface (axiClk domain)
42  -- Register Inputs/Outputs (Mixed domain)
44  config : out AxiAds42lb69ConfigType;
45  -- Global Signals
46  adcClk : in sl;
47  adcRst : in sl;
48  axiClk : in sl;
49  axiRst : in sl
50  );
51 end AxiAds42lb69Reg;
52 
53 architecture rtl of AxiAds42lb69Reg is
54 
55  constant TIMEOUT_1S_C : natural := ite(SIM_SPEEDUP_G, 1000, getTimeRatio(ADC_CLK_FREQ_G, 1.0E+00));
56 
57  type RegType is record
58  adcSmpl : Slv16VectorArray(1 downto 0, 7 downto 0);
59  regOut : AxiAds42lb69ConfigType;
62  end record RegType;
63 
64  constant REG_INIT_C : RegType := (
65  adcSmpl => (others => (others => (others => '0'))),
66  regOut => AXI_ADS42LB69_CONFIG_INIT_C,
69 
70  type AdcType is record
71  timer : natural range 0 to TIMEOUT_1S_C;
72  smplCnt : natural range 0 to 7;
73  armed : sl;
74  end record AdcType;
75 
76  constant ADC_INIT_C : AdcType := (
77  timer => 0,
78  smplCnt => 0,
79  armed => '0');
80 
81  signal r : RegType := REG_INIT_C;
82  signal rin : RegType;
83  signal ra : AdcType := ADC_INIT_C;
84  signal rain : AdcType;
85 
87 
88 begin
89 
90 
91 
92  -------------------------------
93  -- Configuration Register
94  -------------------------------
95  comb : process (axiRst, adcRst, axiReadMaster, axiWriteMaster, r, ra, regIn) is
96  variable v : RegType;
97  variable va : AdcType;
98  variable axiStatus : AxiLiteStatusType;
99  variable axiWriteResp : slv(1 downto 0);
100  variable axiReadResp : slv(1 downto 0);
101  begin
102  -- Latch the current value
103  v := r;
104  va := ra;
105 
106  -- Determine the transaction type
108 
109  -- Reset strobe signals
110  v.regOut.delayIn.load := (others=>(others=>'0'));
111  v.regOut.delayIn.rst := '0';
112 
113  -- Increment the counter (ADC clock domain)
114  va.timer := ra.timer + 1;
115  -- Check the timer for 1 second timeout
116  if ra.timer = TIMEOUT_1S_C then
117  -- Reset the counters
118  va.timer := 0;
119  va.smplCnt := 0;
120  -- Set the flag
121  va.armed := '1';
122  end if;
123  -- Count ADC samples (ADC clock domain)
124  if ra.armed = '1' then
125  va.smplCnt := ra.smplCnt + 1;
126  if ra.smplCnt = 7 then
127  va.armed := '0';
128  end if;
129  end if;
130 
131  -- Store last 8 samples read from ADCs
132  for ch in 1 downto 0 loop
133  if (regIn.adcValid(ch) = '1') then
134  v.adcSmpl(ch, 0) := regIn.adcData(ch);
135  v.adcSmpl(ch, 1) := r.adcSmpl(ch, 0);
136  v.adcSmpl(ch, 2) := r.adcSmpl(ch, 1);
137  v.adcSmpl(ch, 3) := r.adcSmpl(ch, 2);
138  v.adcSmpl(ch, 4) := r.adcSmpl(ch, 3);
139  v.adcSmpl(ch, 5) := r.adcSmpl(ch, 4);
140  v.adcSmpl(ch, 6) := r.adcSmpl(ch, 5);
141  v.adcSmpl(ch, 7) := r.adcSmpl(ch, 6);
142  end if;
143  end loop;
144 
145  if (axiStatus.writeEnable = '1') then
146  -- Check for an out of 32 bit aligned address
147  axiWriteResp := ite(axiWriteMaster.awaddr(1 downto 0) = "00", AXI_RESP_OK_C, AXI_ERROR_RESP_G);
148  -- Decode address and perform write
149  case (axiWriteMaster.awaddr(9 downto 2)) is
150  when x"80" =>
151  v.regOut.delayIn.load(0)(0) := '1';
152  v.regOut.delayIn.rst := '1';
153  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
154  when x"81" =>
155  v.regOut.delayIn.load(0)(1) := '1';
156  v.regOut.delayIn.rst := '1';
157  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
158  when x"82" =>
159  v.regOut.delayIn.load(0)(2) := '1';
160  v.regOut.delayIn.rst := '1';
161  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
162  when x"83" =>
163  v.regOut.delayIn.load(0)(3) := '1';
164  v.regOut.delayIn.rst := '1';
165  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
166  when x"84" =>
167  v.regOut.delayIn.load(0)(4) := '1';
168  v.regOut.delayIn.rst := '1';
169  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
170  when x"85" =>
171  v.regOut.delayIn.load(0)(5) := '1';
172  v.regOut.delayIn.rst := '1';
173  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
174  when x"86" =>
175  v.regOut.delayIn.load(0)(6) := '1';
176  v.regOut.delayIn.rst := '1';
177  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
178  when x"87" =>
179  v.regOut.delayIn.load(0)(7) := '1';
180  v.regOut.delayIn.rst := '1';
181  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
182  when x"88" =>
183  v.regOut.delayIn.load(1)(0) := '1';
184  v.regOut.delayIn.rst := '1';
185  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
186  when x"89" =>
187  v.regOut.delayIn.load(1)(1) := '1';
188  v.regOut.delayIn.rst := '1';
189  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
190  when x"8A" =>
191  v.regOut.delayIn.load(1)(2) := '1';
192  v.regOut.delayIn.rst := '1';
193  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
194  when x"8B" =>
195  v.regOut.delayIn.load(1)(3) := '1';
196  v.regOut.delayIn.rst := '1';
197  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
198  when x"8C" =>
199  v.regOut.delayIn.load(1)(4) := '1';
200  v.regOut.delayIn.rst := '1';
201  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
202  when x"8D" =>
203  v.regOut.delayIn.load(1)(5) := '1';
204  v.regOut.delayIn.rst := '1';
205  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
206  when x"8E" =>
207  v.regOut.delayIn.load(1)(6) := '1';
208  v.regOut.delayIn.rst := '1';
209  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
210  when x"8F" =>
211  v.regOut.delayIn.load(1)(7) := '1';
212  v.regOut.delayIn.rst := '1';
213  v.regOut.delayIn.data := axiWriteMaster.wdata(8 downto 0);
214  when x"90" =>
215  v.regOut.dmode := axiWriteMaster.wdata(1 downto 0);
216  when others =>
217  axiWriteResp := AXI_ERROR_RESP_G;
218  end case;
219  -- Send AXI response
220  axiSlaveWriteResponse(v.axiWriteSlave, axiWriteResp);
221  elsif (axiStatus.readEnable = '1') then
222  -- Check for an out of 32 bit aligned address
223  axiReadResp := ite(axiReadMaster.araddr(1 downto 0) = "00", AXI_RESP_OK_C, AXI_ERROR_RESP_G);
224  -- Reset the register
225  v.axiReadSlave.rdata := (others => '0');
226  -- Decode address and assign read data
227  case (axiReadMaster.araddr(9 downto 2)) is
228  when x"60" =>
229  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(0, 0);
230  when x"61" =>
231  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(0, 1);
232  when x"62" =>
233  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(0, 2);
234  when x"63" =>
235  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(0, 3);
236  when x"64" =>
237  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(0, 4);
238  when x"65" =>
239  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(0, 5);
240  when x"66" =>
241  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(0, 6);
242  when x"67" =>
243  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(0, 7);
244  when x"68" =>
245  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(1, 0);
246  when x"69" =>
247  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(1, 1);
248  when x"6A" =>
249  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(1, 2);
250  when x"6B" =>
251  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(1, 3);
252  when x"6C" =>
253  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(1, 4);
254  when x"6D" =>
255  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(1, 5);
256  when x"6E" =>
257  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(1, 6);
258  when x"6F" =>
259  v.axiReadSlave.rdata(15 downto 0) := r.adcSmpl(1, 7);
260  when x"7F" =>
261  v.axiReadSlave.rdata(0) := regIn.delayOut.rdy;
262  when x"80" =>
263  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(0, 0);
264  when x"81" =>
265  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(0, 1);
266  when x"82" =>
267  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(0, 2);
268  when x"83" =>
269  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(0, 3);
270  when x"84" =>
271  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(0, 4);
272  when x"85" =>
273  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(0, 5);
274  when x"86" =>
275  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(0, 6);
276  when x"87" =>
277  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(0, 7);
278  when x"88" =>
279  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(1, 0);
280  when x"89" =>
281  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(1, 1);
282  when x"8A" =>
283  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(1, 2);
284  when x"8B" =>
285  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(1, 3);
286  when x"8C" =>
287  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(1, 4);
288  when x"8D" =>
289  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(1, 5);
290  when x"8E" =>
291  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(1, 6);
292  when x"8F" =>
293  v.axiReadSlave.rdata(9 downto 0) := regIn.delayOut.data(1, 7);
294  when x"90" =>
295  v.axiReadSlave.rdata(1 downto 0) := r.regOut.dmode;
296  when others =>
297  axiReadResp := AXI_ERROR_RESP_G;
298  end case;
299  -- Send Axi Response
300  axiSlaveReadResponse(v.axiReadSlave, axiReadResp);
301  end if;
302 
303  -- Synchronous Reset
304  if axiRst = '1' then
305  v := REG_INIT_C;
306  v.regOut.dmode := DMODE_INIT_G;
307  end if;
308  -- Synchronous Reset
309  if adcRst = '1' then
310  va := ADC_INIT_C;
311  end if;
312 
313  -- Register the variable for next clock cycle
314  rin <= v;
315  rain <= va;
316 
317  -- Outputs
320  config <= r.regOut;
321 
322  end process comb;
323 
324  seq : process (axiClk) is
325  begin
326  if rising_edge(axiClk) then
327  r <= rin after TPD_G;
328  end if;
329  end process seq;
330 
331  seqa : process (adcClk) is
332  begin
333  if rising_edge(adcClk) then
334  ra <= rain after TPD_G;
335  end if;
336  end process seqa;
337 
338  -------------------------------
339  -- Synchronization
340  -------------------------------
341 
342  GEN_ADC_SMPL :
343  for ch in 0 to 1 generate
344  SyncOut_delayIn_data : entity work.SynchronizerFifo
345  generic map (
346  TPD_G => TPD_G,
347  DATA_WIDTH_G => 16)
348  port map (
349  wr_clk => adcClk,
350  wr_en => ra.armed,
351  din => status.adcData(ch),
352  rd_clk => axiClk,
353  rd_en => regIn.adcValid(ch),
354  valid => regIn.adcValid(ch),
355  dout => regIn.adcData(ch)
356  );
357  end generate;
358 
359  regIn.delayOut <= status.delayOut;
360 
361 end rtl;
slv( 8 downto 0) data
AxiAds42lb69DelayOutType delayOut
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
Slv8Array( 1 downto 0) load
out axiReadSlaveAxiLiteReadSlaveType
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
slv( 1 downto 0) adcValid
in dinslv( DATA_WIDTH_G- 1 downto 0)
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
out axiWriteSlaveAxiLiteWriteSlaveType
in axiWriteMasterAxiLiteWriteMasterType
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
out doutslv( DATA_WIDTH_G- 1 downto 0)
AxiLiteStatusType axiStatus
Definition: AxiLitePkg.vhd:183
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
Definition: AxiLitePkg.vhd:36
DMODE_INIT_Gslv( 1 downto 0) := "00"
SIM_SPEEDUP_Gboolean := false
slv( 1 downto 0) dmode
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
slv( 31 downto 0) awaddr
Definition: AxiLitePkg.vhd:113
in statusAxiAds42lb69StatusType
ADC_CLK_FREQ_Greal := 250.00E+6
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:95
TPD_Gtime := 1 ns
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
_library_ ieeeieee
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
AxiAds42lb69StatusType :=(adcValid =>( others => '0'),adcData =>( others => x"0000"),delayOut => AXI_ADS42LB69_DELAY_OUT_INIT_C) AXI_ADS42LB69_STATUS_INIT_C
AxiAds42lb69DelayInType delayIn
Slv16Array( 1 downto 0) adcData
in axiReadMasterAxiLiteReadMasterType
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:156
array(natural range <> ,natural range <> ) of slv( 15 downto 0) Slv16VectorArray
Definition: StdRtlPkg.vhd:653
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
std_logic_vector slv
Definition: StdRtlPkg.vhd:29