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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [VHDL/] [o8_ltc2355_2p.vhd] - Blame information for rev 191

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

Line No. Rev Author Line
1 191 jshamlet
-- VHDL units : ltc2355_2p
2
-- Description: Reads out a pair of LTC2355 14-bit ADCs which are wired with
3
--            :  common clock and CONVERT START inputs. Because they are
4
--            :  synchronized, this entity provides simultaneously updated
5
--            :  parallel data buses.
6
--
7
-- Notes      : Depends on the fact that the two LTC2355 converters are wired
8
--            :  with their SCLK and CONV lines tied together, and DATA1 and
9
--            :  DATA2 independently routed to separate I/O pins.
10
 
11
library ieee;
12
use ieee.std_logic_1164.all;
13
use ieee.std_logic_unsigned.all;
14
use ieee.std_logic_arith.all;
15
use ieee.std_logic_misc.all;
16
 
17
library work;
18
  use work.open8_pkg.all;
19
 
20
entity o8_ltc2355_2p is
21
generic(
22
  Address                    : ADDRESS_TYPE;
23
  Reset_Level                : std_logic;
24
  Sys_Freq                   : real
25
);
26
port(
27
  Clock                      : in  std_logic; -- 96MHz MAX for proper operation
28
  Reset                      : in  std_logic;
29
  uSec_Tick                  : in  std_logic;
30
  -- Client IF
31
  Bus_Address                : in  ADDRESS_TYPE;
32
  Wr_Enable                  : in  std_logic;
33
  Wr_Data                    : in  DATA_TYPE;
34
  Rd_Enable                  : in  std_logic;
35
  Rd_Data                    : out DATA_TYPE;
36
  Interrupt                  : out std_logic;
37
  -- ADC IF
38
  ADC_SCLK                   : out std_logic;
39
  ADC_CONV                   : out std_logic;
40
  ADC_DATA1                  : in  std_logic;
41
  ADC_DATA2                  : in  std_logic
42
);
43
end entity;
44
 
45
architecture behave of o8_ltc2355_2p is
46
 
47
  constant Divide_SCLK_by_2  : boolean := (Sys_Freq > 96000000.0);
48
 
49
  constant User_Addr         : std_logic_vector(15 downto 3) := Address(15 downto 3);
50
  alias  Comp_Addr           is Bus_Address(15 downto 3);
51
  alias  Reg_Sel             is Bus_Address(2 downto 0);
52
  signal Reg_Sel_q           : std_logic_vector(2 downto 0);
53
  signal Wr_Data_q           : DATA_TYPE;
54
  signal Addr_Match          : std_logic;
55
  signal Wr_En               : std_logic;
56
  signal Rd_En               : std_logic;
57
  signal User_In             : DATA_TYPE;
58
 
59
  signal User_Trig           : std_logic;
60
 
61
  signal Timer_Int           : DATA_TYPE;
62
  signal Timer_Cnt           : DATA_TYPE;
63
  signal Timer_Trig          : std_logic;
64
 
65
  type ADC_STATES is ( IDLE, START, CLK_HIGH, CLK_HIGH2, CLK_LOW, CLK_LOW2, UPDATE );
66
  signal ad_state            : ADC_STATES;
67
 
68
  signal rx_buffer1          : std_logic_vector(16 downto 0);
69
  signal rx_buffer2          : std_logic_vector(16 downto 0);
70
  signal bit_cntr            : std_logic_vector(4 downto 0);
71
  constant BIT_COUNT         : std_logic_vector(4 downto 0) :=
72
                                conv_std_logic_vector(16,5);
73
 
74
  signal ADC1_Data           : std_logic_vector(13 downto 0);
75
  signal ADC2_Data           : std_logic_vector(13 downto 0);
76
  signal ADC_Ready           : std_logic;
77
begin
78
 
79
  Addr_Match                 <= '1' when Comp_Addr = User_Addr else '0';
80
 
81
  io_reg: process( Clock, Reset )
82
  begin
83
    if( Reset = Reset_Level )then
84
      Reg_Sel_q              <= (others => '0');
85
      Wr_Data_q              <= x"00";
86
      Wr_En                  <= '0';
87
      Rd_En                  <= '0';
88
      Rd_Data                <= OPEN8_NULLBUS;
89
      User_Trig              <= '0';
90
      Timer_Int              <= x"00";
91
    elsif( rising_edge( Clock ) )then
92
      Reg_Sel_q              <= Reg_Sel;
93
      Wr_Data_q              <= Wr_Data;
94
      Wr_En                  <= Wr_Enable and Addr_Match;
95
      User_Trig              <= '0';
96
      if( Wr_En = '1' )then
97
        if( Reg_Sel_q = "110" )then
98
          Timer_Int          <= Wr_Data_q;
99
        end if;
100
        if( Reg_Sel_q = "111" )then
101
          User_Trig          <= '1';
102
        end if;
103
      end if;
104
 
105
      Rd_En                  <= Rd_Enable and Addr_Match;
106
      Rd_Data                <= OPEN8_NULLBUS;
107
 
108
      if( Rd_En = '1' )then
109
        case( Reg_Sel_q )is
110
          -- Channel 1, Full resolution, lower byte
111
          when "000" =>
112
            Rd_Data          <= ADC1_Data(7 downto 0);
113
          -- Channel 1, Full resolution, upper byte
114
          when "001" =>
115
            Rd_Data          <= "00" & ADC1_Data(13 downto 8);
116
          -- Channel 2, Full resolution, lower byte
117
          when "010" =>
118
            Rd_Data          <= ADC2_Data(7 downto 0);
119
          -- Channel 2, Full resolution, upper byte
120
          when "011" =>
121
            Rd_Data          <= "00" & ADC2_Data(13 downto 8);
122
          -- Channel 1, 8-bit resolution
123
          when "100" =>
124
            Rd_Data          <= ADC1_Data(13 downto 6);
125
          -- Channel 2, 8-bit resolution
126
          when "101" =>
127
            Rd_Data          <= ADC2_Data(13 downto 6);
128
          -- Self-update rate
129
          when "110" =>
130
            Rd_Data          <= Timer_Int;
131
          -- Interface status
132
          when "111" =>
133
            Rd_Data(7)       <= ADC_Ready;
134
          when others =>
135
            null;
136
        end case;
137
      end if;
138
    end if;
139
  end process;
140
 
141
  Interval_proc: process( Clock, Reset )
142
  begin
143
    if( Reset = Reset_Level )then
144
      Timer_Cnt              <= x"00";
145
      Timer_Trig             <= '0';
146
    elsif( rising_edge(Clock) )then
147
      Timer_Trig             <= '0';
148
      Timer_Cnt              <= Timer_Cnt - uSec_Tick;
149
      if( or_reduce(Timer_Cnt) = '0' )then
150
        Timer_Cnt            <= Timer_Int;
151
        Timer_Trig           <= or_reduce(Timer_Int); -- Only issue output on Int > 0
152
      end if;
153
    end if;
154
  end process;
155
 
156
  ADC_IO_FSM: process( Clock, Reset )
157
  begin
158
    if( Reset = Reset_Level )then
159
      ad_state               <= IDLE;
160
      ADC_Ready              <= '0';
161
 
162
      rx_buffer1             <= (others => '0');
163
      rx_buffer2             <= (others => '0');
164
 
165
      bit_cntr               <= (others => '0');
166
 
167
      ADC1_Data              <= (others => '0');
168
      ADC2_Data              <= (others => '0');
169
 
170
      ADC_SCLK               <= '1';
171
      ADC_CONV               <= '0';
172
 
173
      Interrupt              <= '0';
174
    elsif( rising_edge(Clock) )then
175
      ADC_Ready              <= '0';
176
      ADC_SCLK               <= '1';
177
      ADC_CONV               <= '0';
178
 
179
      Interrupt              <= '0';
180
 
181
      case( ad_state )is
182
        when IDLE =>
183
          ADC_Ready          <= '1';
184
          if( (User_Trig or Timer_Trig) = '1' )then
185
            ad_state         <= START;
186
          end if;
187
 
188
        when START =>
189
          ADC_SCLK           <= '0';
190
          ADC_CONV           <= '1';
191
          bit_cntr           <= BIT_COUNT;
192
          ad_state           <= CLK_HIGH;
193
 
194
        when CLK_HIGH =>
195
          ad_state           <= CLK_LOW;
196
          if( Divide_SCLK_by_2 )then
197
            ad_state         <= CLK_HIGH2;
198
          end if;
199
 
200
        when CLK_HIGH2 =>
201
          ad_state           <= CLK_LOW;
202
 
203
        when CLK_LOW =>
204
          ADC_SCLK           <= '0';
205
          rx_buffer1(conv_integer(bit_cntr)) <= ADC_DATA1;
206
          rx_buffer2(conv_integer(bit_cntr)) <= ADC_DATA2;
207
          bit_cntr           <= bit_cntr - 1;
208
          ad_state           <= CLK_HIGH;
209
          if( bit_cntr = 0 )then
210
            ad_state         <= UPDATE;
211
          elsif( Divide_SCLK_by_2 )then
212
            ad_state         <= CLK_LOW2;
213
          end if;
214
 
215
        when CLK_LOW2 =>
216
          ADC_SCLK           <= '0';
217
          ad_state           <= CLK_HIGH;
218
 
219
        when UPDATE =>
220
          ADC_SCLK           <= '0';
221
          ad_state           <= IDLE;
222
          ADC1_Data          <= rx_buffer1(14 downto 1);
223
          ADC2_Data          <= rx_buffer2(14 downto 1);
224
          Interrupt          <= '1';
225
 
226
        when others =>
227
          null;
228
      end case;
229
 
230
    end if;
231
  end process;
232
 
233
end architecture;

powered by: WebSVN 2.1.0

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