OpenCores
URL https://opencores.org/ocsvn/modular_oscilloscope/modular_oscilloscope/trunk

Subversion Repositories modular_oscilloscope

[/] [modular_oscilloscope/] [trunk/] [hdl/] [daq/] [daq.vhd] - Blame information for rev 53

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 23 budinero
----------------------------------------------------------------------------------------------------
2
--| Modular Oscilloscope
3
--| UNSL - Argentina
4
--|
5 30 budinero
--| File: daq.vhd
6 31 budinero
--| Version: 0.40
7 23 budinero
--| Tested in: Actel A3PE1500
8 31 budinero
--|   Board: RVI Prototype Board + LP Data Conversion Daughter Board
9 23 budinero
--|-------------------------------------------------------------------------------------------------
10
--| Description:
11 30 budinero
--|   Acquisition control module. 
12
--|   It drives the ADC chip.
13 23 budinero
--|-------------------------------------------------------------------------------------------------
14
--| File history:
15
--|   0.01   | apr-2008 | First testing
16
--|   0.10   | apr-2009 | First release
17 31 budinero
--|   0.40   | jul-2009 | Added a read flag for each channel and adc_clk_I input
18 23 budinero
----------------------------------------------------------------------------------------------------
19 39 budinero
--| Copyright Š 2009, Facundo Aguilera.
20 23 budinero
--|
21
--| This VHDL design file is an open design; you can redistribute it and/or
22
--| modify it and/or implement it after contacting the author.
23
 
24
--| Wishbone Rev. B.3 compatible
25
----------------------------------------------------------------------------------------------------
26
 
27 31 budinero
--==================================================================================================
28
-- TODO
29
-- ˇ Access to both channels in consecutive reads  
30
--==================================================================================================
31 23 budinero
 
32
 
33
 
34
 
35
-- Esta primera versión está realizada específicamente para controlar el ADC AD9201. Otras
36 31 budinero
-- versiones podrán ser más genéricas. 
37 23 budinero
 
38
 
39
-- ADR    configuración (seńal config)
40
-- ADR+1  datos canal 1
41
-- ADR+2  datos canal 2
42
-- ADR+3  sin usar
43
 
44
library IEEE;
45
use IEEE.STD_LOGIC_1164.all;
46
use IEEE.STD_LOGIC_UNSIGNED.ALL;
47
--use IEEE.STD_LOGIC_ARITH.all;
48
use IEEE.NUMERIC_STD.ALL;
49
--use work.adq_pgk.all;
50
 
51 30 budinero
entity daq is
52 23 budinero
  generic (
53
    DEFALT_CONFIG : std_logic_vector := "0000100000000000"
54
                                      -- bits 8 a 0       clk_pre_scaler
55
                                      -- bits 9           clk_pre_scaler_ena
56 31 budinero
                                      -- bit 10           adc sleep
57 23 budinero
                                      -- bit 11           adc_chip_sel
58
                                      -- bits 12 a 15     sin usar
59
 
60
                                      -- si clk_pre_scaler_ena = 1
61
                                      -- frecuencia_adc = frecuencia_wbn / ((clk_pre_scaler+1)*2)
62
                                      -- sino frecuencia_adc = frecuencia_wbn
63
  );
64
  port(
65
    -- Externo
66 31 budinero
    adc_data_I:     in    std_logic_vector (9 downto 0);
67
    adc_sel_O:      out   std_logic;
68
    adc_clk_O:      out   std_logic;
69
    adc_sleep_O:    out   std_logic;
70
    adc_chip_sel_O: out   std_logic;
71 23 budinero
 
72
 
73
    --  Interno
74
    RST_I:  in  std_logic;
75
    CLK_I:  in  std_logic;
76
    DAT_I:  in  std_logic_vector (15 downto 0);
77
    ADR_I:  in  std_logic_vector (1 downto 0);
78
    CYC_I:  in  std_logic;
79
    STB_I:  in  std_logic;
80
    WE_I:   in  std_logic;
81
    DAT_O:  out std_logic_vector (15 downto 0);
82 31 budinero
    ACK_O:  out std_logic;
83
 
84
    adc_clk_I: std_logic
85 23 budinero
  );
86 30 budinero
end daq;
87 23 budinero
 
88
 
89 31 budinero
architecture archdaq2 of daq is
90 23 budinero
  -- Tipos
91 31 budinero
  type config_array is array(0 to 2) of std_logic_vector(15 downto 0);
92 23 budinero
 
93
 
94
                --   type arr is array(0 to 3) of std_logic_vector(15 downto 0);
95
                -- 
96
                -- signal arr_a : arr;
97
                -- signal vec_0, vec_1, vec_2, vec_3 : std_logic vector(15 downto 0);
98
                -- ....
99
                -- arr_a(0) <= vec_0;
100
                -- arr_a(1) <= vec_1;
101
                -- ....
102 31 budinero
 
103
  type data_array is array(0 to 1) of std_logic_vector(adc_data_I'length - 1 downto 0);
104
 
105 23 budinero
 
106 31 budinero
 
107
  -- Registers
108 23 budinero
  signal config:   std_logic_vector (15 downto 0);
109 31 budinero
  signal count: std_logic_vector (8 downto 0);
110
  signal channel_data: data_array;
111
  signal read_flag_adc: std_logic_vector (1 downto 0);
112
  signal read_flag_wb: std_logic_vector (1 downto 0);
113
  -- The biggest limit must be the channels number (-1)
114
  -- There are two clocks becouse there are two clocks
115
 
116
  -- Signals
117
  signal selector: config_array;
118 23 budinero
 
119 31 budinero
  signal s_adc_clk, s_adc_sleep, s_adc_chip_sel: std_logic; -- previous to outputs
120
  signal reduced_clk, same_clk: std_logic;
121 23 budinero
  signal data_ack_ready:      std_logic; -- habilita confirmación de datos
122
  signal conf_ack_ready:      std_logic; -- habilita confirmación de escritura de configuración
123
  signal clk_pre_scaler:      std_logic_vector (8 downto 0);
124
  signal clk_pre_scaler_ena:  std_logic;
125 31 budinero
  signal channel_sel:         std_logic_vector(0 downto 0); -- max limit must be the number of channels
126
  signal count_reset:          std_logic;
127
  signal count_max:           std_logic;
128 23 budinero
  --signal clk_enable: std_logic_vector (9 downto 0);
129
 
130
begin
131
  --------------------------------------------------------------------------------------------------
132
  -- Asignaciones
133 31 budinero
  ---- Internal 
134
  selector(0) <= (config'length - 1 downto adc_data_I'length => '0' ) &
135
                 channel_data(conv_integer(channel_sel));
136
  selector(1) <= (config'length - 1 downto adc_data_I'length => '0' ) &
137
                 channel_data(conv_integer(channel_sel));
138
  selector(2) <= config;
139
  --selector(3) <= (others => '0' ); -- Unassigned
140
 
141
 
142 23 budinero
 
143 31 budinero
  ---- Config register
144 23 budinero
  clk_pre_scaler <= config(8 downto 0);
145
  clk_pre_scaler_ena <= config(9);
146
  s_adc_sleep <= config(10);
147
  s_adc_chip_sel <= config(11);
148 31 budinero
  -- Unassigned <= config(13); 
149
  -- Unassigned <= config(14);
150
  -- Unassigned <= config(15);
151 23 budinero
 
152 31 budinero
  ---- External communication (AD)
153
  adc_sleep_O <= s_adc_sleep;
154
  adc_chip_sel_O <= s_adc_chip_sel;
155
 
156 23 budinero
 
157
 
158
 
159
  --------------------------------------------------------------------------------------------------
160 31 budinero
  -- Generación de adc_clk_O
161
  count_max <= '1' when count >= clk_pre_scaler else '0';
162
  count_reset <=  RST_I or count_max or not(clk_pre_scaler_ena);
163
 
164
  P_count: process (adc_clk_I, count, count_reset)
165 23 budinero
  begin
166 31 budinero
    if adc_clk_I'event and adc_clk_I = '1'  then
167
      if count_reset = '1' then
168
        count <= (others => '0');
169
      else
170 23 budinero
        count <= count + 1;
171
      end if;
172
    end if;
173
  end process;
174
 
175 31 budinero
  P_adcclk: process (adc_clk_I, RST_I, clk_pre_scaler_ena)
176
  begin
177
    if adc_clk_I'event and adc_clk_I = '1'  then
178
      if RST_I = '1' or clk_pre_scaler_ena = '0' then
179
        reduced_clk <= '0';
180
      elsif count_max = '1' then
181
        reduced_clk <= not(reduced_clk);
182
      end if;
183
    end if;
184
    -- OLD     
185
    --     if RST_I = '1' then
186
    --       count <= (others => '0');
187
    --       s_adc_clk <= '0';
188
    --     elsif clk_pre_scaler_ena = '1' then
189
    --       if CLK_I'event and CLK_I = '1' then
190
    --         count <= count + 1;
191
    --         if count = clk_pre_scaler  then
192
    --           s_adc_clk <= not(s_adc_clk);
193
    --           count <= (others => '0');
194
    --         end if;        
195
    --       end if;
196
    --     else  
197
    --       count <= (others => '0');
198
    --       s_adc_clk <= CLK_I;
199
    --     end if;
200
  end process;
201
  same_clk <= adc_clk_I;
202
 
203
  with clk_pre_scaler_ena select
204
    s_adc_clk <= reduced_clk  when '1',
205
                 same_clk      when others;
206
 
207
  adc_clk_O <= s_adc_clk;
208
 
209 23 budinero
  --------------------------------------------------------------------------------------------------
210
  -- Generación ack
211 31 budinero
 
212
  -- When ADR_I(1) = '1', master will be accessing to confing register.
213
 
214 23 budinero
  ACK_O <= CYC_I and STB_I and (data_ack_ready or conf_ack_ready);
215
 
216 31 budinero
  data_ack_ready  <=  (read_flag_wb(conv_integer(channel_sel)) xnor read_flag_adc(conv_integer(channel_sel))) and not(WE_I);
217 23 budinero
 
218 31 budinero
  conf_ack_ready  <=  ADR_I(1);
219
 
220 23 budinero
  --------------------------------------------------------------------------------------------------
221 31 budinero
  -- Channel selection
222 23 budinero
 
223 31 budinero
  -- channel_data(0) --> Q channel
224
  -- channel_data(1) --> I channel (of ADC AD9201)
225 23 budinero
 
226 31 budinero
  channel_sel(0) <= ADR_I(0);
227
 
228
  P_dataread: process (s_adc_clk, adc_data_I)
229
  begin
230
    if s_adc_clk'event and s_adc_clk = '1' then
231
      channel_data(0) <= adc_data_I;
232
    end if;
233
    if s_adc_clk'event and s_adc_clk = '0' then
234
      channel_data(1) <= adc_data_I;
235
    end if;
236
  end process;
237
 
238
  P_flags: process (s_adc_clk, CLK_I, CYC_I, STB_I, ADR_I, read_flag_adc, read_flag_wb,channel_sel)
239
  begin
240
 
241
    if s_adc_clk'event and s_adc_clk = '1' then
242
      read_flag_adc(0) <= read_flag_wb(0);
243
    end if;
244
 
245
    if s_adc_clk'event and s_adc_clk = '0' then
246
      read_flag_adc(1) <= read_flag_wb(1);
247
    end if;
248
 
249
    if CLK_I'event and CLK_I = '1' then
250
      if RST_I = '1' then
251
        read_flag_wb <= (others => '0');
252
        --read_flag_adc <= (others => '1');
253
      elsif CYC_I = '1' and STB_I = '1' and ADR_I(1) = '0' then  -- read_flag(conv_integer(channel_sel)) = '0' and  
254
        read_flag_wb(conv_integer(channel_sel)) <= not(read_flag_adc(conv_integer(channel_sel)));
255
      end if;
256
    end if;
257
 
258
 
259
 
260
  end process;
261
 
262
  adc_sel_O <= s_adc_clk;
263
 
264 23 budinero
  --------------------------------------------------------------------------------------------------
265
  -- Lectura y escritura de datos
266
  ---- Generación de DAT_O
267
  DAT_O   <=  selector(conv_integer(ADR_I));
268
 
269
  ---- Almacenado de registro de configuración
270 31 budinero
  P_output: process (CLK_I, ADR_I, RST_I, DAT_I)
271 23 budinero
  begin
272
 
273
    if CLK_I'event and CLK_I = '1' then
274
      if RST_I = '1' then
275
        config <= DEFALT_CONFIG;
276
      elsif WE_I = '1' and  CYC_I = '1' and STB_I = '1' then
277 31 budinero
        if unsigned(ADR_I) = 2 then
278 23 budinero
          config <= DAT_I;
279
        end if;
280
      end if;
281
    end if;
282
 
283
  end process;
284
 
285
 
286 31 budinero
end architecture archdaq2;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.