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

Subversion Repositories wbpwmaudio

[/] [wbpwmaudio/] [trunk/] [demo-rtl/] [traditionalpwm.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    traditionalpwm.v
4
//
5
// Project:     A Wishbone Controlled PWM (audio) controller
6
//
7
// Purpose:
8
//
9
// Creator:     Dan Gisselquist, Ph.D.
10
//              Gisselquist Technology, LLC
11
//
12
////////////////////////////////////////////////////////////////////////////////
13
//
14
// Copyright (C) 2015, Gisselquist Technology, LLC
15
//
16
// This program is free software (firmware): you can redistribute it and/or
17
// modify it under the terms of the GNU General Public License as published
18
// by the Free Software Foundation, either version 3 of the License, or (at
19
// your option) any later version.
20
//
21
// This program is distributed in the hope that it will be useful, but WITHOUT
22
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
23
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
// for more details.
25
//
26
// You should have received a copy of the GNU General Public License along
27
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
28
// target there if the PDF file isn't present.)  If not, see
29
// <http://www.gnu.org/licenses/> for a copy.
30
//
31
// License:     GPL, v3, as defined and found on www.gnu.org,
32
//              http://www.gnu.org/licenses/gpl.html
33
//
34
//
35
////////////////////////////////////////////////////////////////////////////////
36
//
37
//
38
`default_nettype        none
39
//
40
module  traditionalpwm(i_clk, i_reset,
41
                // Wishbone interface
42
                i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data,
43
                        o_wb_ack, o_wb_stall, o_wb_data,
44
                o_pwm, o_aux, o_int);
45
        parameter       DEFAULT_RELOAD = 16'd1814, // about 44.1 kHz @  80MHz
46
                        //DEFAULT_RELOAD = 16'd2268,//about 44.1 kHz @ 100MHz
47
                        NAUX=2, // Dev control values
48
                        VARIABLE_RATE=0,
49
                        TIMING_BITS=16;
50
        input   wire            i_clk, i_reset;
51
        input   wire            i_wb_cyc, i_wb_stb, i_wb_we;
52
        input   wire            i_wb_addr;
53
        input   wire    [31:0]   i_wb_data;
54
        output  reg             o_wb_ack;
55
        output  wire            o_wb_stall;
56
        output  wire    [31:0]   o_wb_data;
57
        output  reg             o_pwm;
58
        output  reg     [(NAUX-1):0]     o_aux;
59
        output  wire            o_int;
60
 
61
 
62
        // How often shall we create an interrupt?  Every reload_value clocks!
63
        // If VARIABLE_RATE==0, this value will never change and will be kept
64
        // at the default reload rate (defined up top)
65
        wire    [(TIMING_BITS-1):0]      w_reload_value;
66
        generate
67
        if (VARIABLE_RATE != 0)
68
        begin
69
                reg     [(TIMING_BITS-1):0]      r_reload_value;
70
                initial r_reload_value = DEFAULT_RELOAD;
71
                always @(posedge i_clk) // Data write
72
                        if ((i_wb_stb)&&(i_wb_addr)&&(i_wb_we))
73
                                r_reload_value <= i_wb_data[(TIMING_BITS-1):0]-1'b1;
74
                assign  w_reload_value = r_reload_value;
75
        end else begin
76
                assign  w_reload_value = DEFAULT_RELOAD;
77
        end endgenerate
78
 
79
        //
80
        // The next value timer
81
        //
82
        // We'll want a new sample every w_reload_value clocks.  When the
83
        // timer hits zero, the signal ztimer (zero timer) will also be
84
        // set--allowing following logic to depend upon it.
85
        //
86
        reg                             ztimer;
87
        reg     [(TIMING_BITS-1):0]      timer;
88
        initial timer = DEFAULT_RELOAD;
89
        initial ztimer= 1'b0;
90
        always @(posedge i_clk)
91
                if (i_reset)
92
                        ztimer <= 1'b0;
93
                else
94
                        ztimer <= (timer == { {(TIMING_BITS-1){1'b0}}, 1'b1 });
95
 
96
        always @(posedge i_clk)
97
                if ((ztimer)||(i_reset))
98
                        timer <= w_reload_value;
99
                else
100
                        timer <= timer - {{(TIMING_BITS-1){1'b0}},1'b1};
101
 
102
        //
103
        // Whenever the timer runs out, accept the next value from the single
104
        // sample buffer.
105
        //
106
        reg     [15:0]   sample_out;
107
        always @(posedge i_clk)
108
                if (ztimer)
109
                        sample_out <= next_sample;
110
 
111
 
112
        //
113
        // Control what's in the single sample buffer, next_sample, as well as
114
        // whether or not it's a valid sample.  Specifically, if next_valid is
115
        // false, then the sample buffer needs a new value.  Once the buffer
116
        // has a value within it, further writes will just quietly overwrite
117
        // this value.
118
        reg     [15:0]   next_sample;
119
        reg             next_valid;
120
        initial next_valid = 1'b1;
121
        initial next_sample = 16'h8000;
122
        always @(posedge i_clk) // Data write
123
                if ((i_wb_stb)&&(i_wb_we)
124
                                &&((!i_wb_addr)||(VARIABLE_RATE==0)))
125
                begin
126
                        // We get a two's complement data from the bus.
127
                        // Convert it here to an unsigned binary offset
128
                        // representation
129
                        next_sample <= i_wb_data[15:0] + { 1'b0, w_reload_value[15:1] } + 1'b1;
130
                        next_valid <= 1'b1;
131
                        if (i_wb_data[16])
132
                                o_aux <= i_wb_data[(NAUX+20-1):20];
133
                end else if (ztimer)
134
                        next_valid <= 1'b0;
135
 
136
        assign  o_int = (!next_valid);
137
 
138
        reg     [15:0]   pwm_counter;
139
        initial pwm_counter = 16'h00;
140
        always @(posedge i_clk)
141
                if (ztimer)
142
                        pwm_counter <= 0;
143
                else
144
                        pwm_counter <= pwm_counter + 1'b1;
145
 
146
        always @(posedge i_clk)
147
                o_pwm <= (sample_out >= pwm_counter);
148
 
149
        //
150
        // Handle the bus return traffic.
151
        generate
152
        if (VARIABLE_RATE == 0)
153
        begin
154
                // If we are running off of a fixed rate, then just return
155
                // the current setting of the aux registers, the current
156
                // interrupt value, and the current sample we are outputting.
157
                assign o_wb_data = { {(12-NAUX){1'b0}}, o_aux,
158
                                        3'h0, o_int, sample_out };
159
        end else begin
160
                // On the other hand, if we have been built to support a
161
                // variable sample rate, then return the reload value for
162
                // address one but otherwise the data value (above) for address
163
                // zero.
164
                reg     [31:0]   r_wb_data;
165
                always @(posedge i_clk)
166
                        if (i_wb_addr)
167
                                r_wb_data <= { (32-TIMING_BITS),w_reload_value};
168
                        else
169
                                r_wb_data <= { {(12-NAUX){1'b0}}, o_aux,
170
                                                3'h0, o_int, sample_out };
171
                assign  o_wb_data = r_wb_data;
172
        end endgenerate
173
 
174
        // Always ack on the clock following any request
175
        initial o_wb_ack = 1'b0;
176
        always @(posedge i_clk)
177
                o_wb_ack <= (i_wb_stb);
178
 
179
        // Never stall
180
        assign  o_wb_stall = 1'b0;
181
 
182
        // Make Verilator happy.  Since we aren't using all of the bits from
183
        // the bus, Verilator -Wall will complain.  This just informs
184
        // V*rilator that we already know these bits aren't being used.
185
        //
186
        // verilator lint_off UNUSED
187
        wire    [14:0]   unused;
188
        assign  unused = { i_wb_cyc, i_wb_data[31:21], i_wb_data[19:17] };
189
        // verilator lint_on  UNUSED
190
 
191
endmodule

powered by: WebSVN 2.1.0

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