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

Subversion Repositories simpcon

[/] [simpcon/] [trunk/] [vhdl/] [sc_sigdel.vhd] - Blame information for rev 29

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 martin
--
2 29 martin
--
3
--  This file is a part of JOP, the Java Optimized Processor
4
--
5
--  Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com)
6
--
7
--  This program is free software: you can redistribute it and/or modify
8
--  it under the terms of the GNU General Public License as published by
9
--  the Free Software Foundation, either version 3 of the License, or
10
--  (at your option) any later version.
11
--
12
--  This program is distributed in the hope that it will be useful,
13
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
--  GNU General Public License for more details.
16
--
17
--  You should have received a copy of the GNU General Public License
18
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
 
21
 
22
--
23 18 martin
--      sc_sigdel.vhd
24
--
25
--      A simple sigma-delta ADC and PWM DAC for the SimpCon interface
26
--      
27
--      Author: Martin Schoeberl        martin@jopdesign.com
28
--
29
--
30
--      resources on Cyclone
31
--
32
--              xx LCs, max xx MHz
33
--
34
--
35
--      2006-04-16      first version
36
--
37
--      todo:
38
--
39
--
40
 
41
 
42
library ieee;
43
use ieee.std_logic_1164.all;
44
use ieee.numeric_std.all;
45
 
46
use work.jop_config.all;
47
 
48
entity sc_sigdel is
49
generic (addr_bits : integer; fsamp : integer);
50
 
51
port (
52
        clk             : in std_logic;
53
        reset   : in std_logic;
54
 
55
-- SimpCon interface
56
 
57
        address         : in std_logic_vector(addr_bits-1 downto 0);
58
        wr_data         : in std_logic_vector(31 downto 0);
59
        rd, wr          : in std_logic;
60
        rd_data         : out std_logic_vector(31 downto 0);
61
        rdy_cnt         : out unsigned(1 downto 0);
62
 
63
-- io ports
64
        sdi                     : in std_logic;         -- input of the sigma-delta ADC
65
        sdo                     : out std_logic;        -- output of the sigma-delta ADC
66
        dac                     : out std_logic         -- output of the PWM DAC
67
);
68
end sc_sigdel;
69
 
70
architecture rtl of sc_sigdel is
71
 
72
        -- we use a 10MHz sigma-delta clock
73
        constant SDF            : integer := 10000000;
74
        constant SDTICK         : integer := (clk_freq+SDF/2)/SDF;
75
        signal clksd            : integer range 0 to SDTICK;
76
        constant CNT_MAX        : integer := (SDF+fsamp/2)/fsamp;
77
        signal cnt                      : integer range 0 to CNT_MAX;
78
        signal dac_cnt          : integer range 0 to CNT_MAX;
79
 
80
        signal rx_d                     : std_logic;
81
        signal serdata          : std_logic;
82
        signal spike            : std_logic_vector(2 downto 0);  -- sync in, filter
83
        signal sum                      : unsigned(15 downto 0);
84
        signal delta            : unsigned(15 downto 0);
85
 
86
        signal audio_in         : std_logic_vector(15 downto 0);
87
        signal audio_out        : std_logic_vector(15 downto 0);
88
 
89
        signal sample_rdy       : std_logic;
90
        signal sample_rd        : std_logic;
91
        signal sample_wr        : std_logic;
92
 
93
begin
94
 
95
        rdy_cnt <= "00";        -- no wait states
96
        -- we use only 16 bits
97
        -- bit 31 is the ready bit
98
        rd_data(30 downto 16) <= (others => '0');
99
 
100
--
101
--      The registered MUX is all we need for a SimpCon read.
102
--      The read data is stored in registered rd_data.
103
--
104
process(clk, reset)
105
begin
106
 
107
        if (reset='1') then
108
                rd_data(15 downto 0) <= (others => '0');
109
                rd_data(31) <= '0';
110
                sample_rd <= '0';
111
        elsif rising_edge(clk) then
112
 
113
                sample_rd <= '0';
114
                if rd='1' then
115
                        rd_data(15 downto 0) <= audio_in;
116
                        rd_data(31) <= sample_rdy;
117
                        sample_rd <= '1';
118
                end if;
119
        end if;
120
 
121
end process;
122
 
123
 
124
--
125
--      SimpCon write is very simple
126
--
127
process(clk, reset)
128
 
129
begin
130
 
131
        if (reset='1') then
132
                audio_out <= (others => '0');
133
                sample_wr <= '0';
134
        elsif rising_edge(clk) then
135
                sample_wr <= '0';
136
                if wr='1' then
137
                        audio_out <= wr_data(15 downto 0);
138
                        sample_wr <= '1';
139
                end if;
140
        end if;
141
end process;
142
 
143
 
144
--
145
--      Here we go with the simple sigma-delta converter:
146
--
147
process(clk, reset)
148
 
149
begin
150
 
151
        if reset='1' then
152
 
153
                spike <= "000";
154
                clksd <= 0;
155
                cnt <= 0;
156
                sum <= (others => '0');
157
                sample_rdy <= '0';
158
 
159
        elsif rising_edge(clk) then
160
 
161
                if clksd=0 then
162
                        clksd <= SDTICK-1;
163
                        spike(0) <= sdi;
164
                        spike(2 downto 1) <= spike(1 downto 0);
165
                        sdo <= not rx_d;
166
                        serdata <= rx_d;
167
 
168
                        if cnt=0 then
169
                                cnt <= CNT_MAX-1;
170
                                audio_in <= std_logic_vector(sum);
171
                                sample_rdy <= '1';
172
                                sum <= (others => '0');
173
                                -- BTW: we miss one sigma-delta sample here...
174
                        else
175
                                cnt <= cnt-1;
176
                                if serdata='1' then
177
                                        sum <= sum+1;
178
                                end if;
179
                        end if;
180
                else
181
                        clksd <= clksd-1;
182
                end if;
183
 
184
                -- reset ready flag after read
185
                if sample_rd='1' then
186
                        sample_rdy <= '0';
187
                end if;
188
 
189
        end if;
190
 
191
end process;
192
 
193
--
194
--      filter input (majority voting)
195
--
196
        with spike select
197
                rx_d <= '0' when "000",
198
                                '0' when "001",
199
                                '0' when "010",
200
                                '1' when "011",
201
                                '0' when "100",
202
                                '1' when "101",
203
                                '1' when "110",
204
                                '1' when "111",
205
                                'X' when others;
206
 
207
--
208
--      and here comes the primitive version of the
209
--      digital delta part - not really delta...
210
--              it's just a simple PWM...
211
--      now do it with the main clock...
212
--
213
process(clk, reset)
214
 
215
begin
216
        if reset='1' then
217
                delta <= (others => '0');
218
                dac <= '0';
219
                dac_cnt <= 0;
220
        elsif rising_edge(clk) then
221
 
222
                if dac_cnt=0 then
223
                        dac_cnt <= CNT_MAX-1;
224
                        delta <= unsigned(audio_out);
225
                else
226
                        dac_cnt <= dac_cnt-1;
227
                        dac <= '0';
228
                        if delta /= 0 then
229
                                delta <= delta-1;
230
                                dac <= '1';
231
                        end if;
232
                end if;
233
 
234
        end if;
235
end process;
236
 
237
end rtl;

powered by: WebSVN 2.1.0

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