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

Subversion Repositories simpcon

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

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

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

powered by: WebSVN 2.1.0

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