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

Subversion Repositories psg16

[/] [psg16/] [trunk/] [rtl/] [verilog/] [PSGNoteGen.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 robfinch
`timescale 1ns / 1ps
2
//=============================================================================
3
//      (C) 2007,2012  Robert Finch
4
//  robfinch<remove>@opencores.org
5
//      All rights reserved.
6
//
7
//      PSGNoteGen.v
8
//      Version 1.1
9
//
10
// This source file is free software: you can redistribute it and/or modify 
11
// it under the terms of the GNU Lesser General Public License as published 
12
// by the Free Software Foundation, either version 3 of the License, or     
13
// (at your option) any later version.                                      
14
//                                                                          
15
// This source file is distributed in the hope that it will be useful,      
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
18
// GNU General Public License for more details.                             
19
//                                                                          
20
// You should have received a copy of the GNU General Public License        
21
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
22
//
23
//
24
//      Note generator. 4/8 channels
25
//
26
//      Spartan3
27
//      Webpack 9.1i xc3s1000-4ft256
28
//      337 LUTs / 224 slices / 98.445 MHz
29
//=============================================================================
30
 
31
module PSGNoteGen(rst, clk, cnt, br, bg, bgn, ack, test,
32
        vt0, vt1, vt2, vt3,
33
        freq0, freq1, freq2, freq3,
34
        pw0, pw1, pw2, pw3,
35
        acc0, acc1, acc2, acc3,
36
        wave, sync, ringmod, o
37
);
38
input rst;
39
input clk;
40
input [7:0] cnt;
41
input ack;
42
input [11:0] wave;
43
input [2:0] bgn;         // bus grant number
44
output [3:0] br;
45
input [3:0] bg;
46
input [3:0] test;
47
input [4:0] vt0, vt1, vt2, vt3;
48
input [15:0] freq0, freq1, freq2, freq3;
49
input [11:0] pw0, pw1, pw2, pw3;
50
input [3:0] sync;
51
input [3:0] ringmod;
52
//      input pxacc25;
53
output [23:0] acc0, acc1, acc2, acc3;    // 1.023MHz / 2^ 24 = 0.06Hz resolution
54
output [11:0] o;
55
 
56
wire [15:0] freqx;
57
wire [11:0] pwx;
58
reg [23:0] pxacc;
59
reg [23:0] acc;
60
reg [11:0] outputT;
61
reg [7:0] pxacc23x;
62
reg [7:0] ibr;
63
 
64
integer n;
65
 
66
reg [23:0] accx [3:0];
67
reg [11:0] pacc [3:0];
68
wire [1:0] sel = cnt[1:0];
69
reg [11:0] outputW [3:0];
70
reg [22:0] lfsr [3:0];
71
 
72
assign br[0] =   ibr[0] & ~bg[0];
73
assign br[1] =  ibr[1] & ~bg[1];
74
assign br[2] =  ibr[2] & ~bg[2];
75
assign br[3] =  ibr[3] & ~bg[3];
76
 
77
wire [4:0] vtx;
78
 
79
always @(sel)
80
        acc <= accx[sel];
81
 
82
 
83
mux4to1 #(16) u1 (.e(1'b1), .s(sel), .i0(freq0), .i1(freq1), .i2(freq2), .i3(freq3), .z(freqx) );
84
mux4to1 #(12) u2 (.e(1'b1), .s(sel), .i0(pw0), .i1(pw1), .i2(pw2), .i3(pw3), .z(pwx) );
85
mux4to1 #( 5) u3 (.e(1'b1), .s(sel), .i0(vt0), .i1(vt1), .i2(vt2), .i3(vt3), .z(vtx) );
86
 
87
 
88
wire [22:0] lfsrx = lfsr[sel];
89
wire [7:0] paccx = pacc[sel];
90
 
91
always @(sel)
92
        pxacc <= accx[sel-1];
93
wire pxacc23 = pxacc[23];
94
 
95
 
96
// for sync'ing
97
always @(posedge clk)
98
        if (cnt < 8'd4)
99
                pxacc23x[sel] <= pxacc23;
100
 
101
wire synca = ~pxacc23x[sel]&pxacc23&sync[sel];
102
 
103
 
104
// detect a transition on the wavetable address
105
// previous address not equal to current address
106
wire accTran = pacc[sel]!=acc[23:12];
107
 
108
// for wave table DMA
109
// capture the previous address
110
always @(posedge clk)
111
        if (rst) begin
112
                for (n = 0; n < 4; n = n + 1)
113
                        pacc[n] <= 0;
114
        end
115
        else if (cnt < 8'd4)
116
                pacc[sel] <= acc[23:12];
117
 
118
 
119
// capture wave input
120
// must be to who was granted the bus
121
always @(posedge clk)
122
        if (rst) begin
123
                for (n = 0; n < 8'd4; n = n + 1)
124
                        outputW[n] <= 0;
125
        end
126
        else if (ack)
127
                outputW[bgn] <= wave;
128
 
129
 
130
// bus request control
131
always @(posedge clk)
132
        if (rst) begin
133
                ibr <= 0;
134
        end
135
        else if (cnt < 8'd4) begin
136
                // check for an address transition and wave enabled
137
                // if so, request bus
138
                if (accTran & vtx[4])
139
                        ibr[sel] <= 1;
140
                // otherwise
141
                // turn off bus request for whoever it was granted
142
                else
143
                        ibr[bgn] <= 0;
144
        end
145
 
146
 
147
// Noise generator
148
always @(posedge clk)
149
        if (cnt < 8'd4 && paccx[2] != acc[18])
150
                lfsr[sel] <= {lfsrx[21:0],~(lfsrx[22]^lfsrx[17])};
151
 
152
 
153
// Harmonic synthesizer
154
always @(posedge clk)
155
        if (rst) begin
156
                for (n = 0; n < 4; n = n + 1)
157
                        accx[n] <= 0;
158
        end
159
        else if (cnt < 8'd4) begin
160
                if (~test[sel]) begin
161
                        if (synca)
162
                                accx[sel] <= 0;
163
                        else
164
                                accx[sel] <= acc + freqx;
165
                end
166
                else
167
                        accx[sel] <= 0;
168
        end
169
 
170
 
171
// Triangle wave, ring modulation
172
wire msb = ringmod[sel] ? acc[23]^pxacc23 : acc[23];
173
always @(acc or msb)
174
        outputT <= msb ? ~acc[22:11] : acc[22:11];
175
 
176
// Other waveforms, ho-hum
177
wire [11:0] outputP = {12{acc[23:12] < pwx}};
178
wire [11:0] outputS = acc[23:12];
179
wire [11:0] outputN = lfsrx[11:0];
180
 
181
wire [11:0] out;
182
PSGNoteOutMux #(12) u4 (.s(vtx), .a(outputT), .b(outputS), .c(outputP), .d(outputN), .e(outputW[sel]), .o(out) );
183
assign o = out;
184
 
185
assign acc0 = accx[0];
186
assign acc1 = accx[1];
187
assign acc2 = accx[2];
188
assign acc3 = accx[3];
189
 
190
endmodule
191
 

powered by: WebSVN 2.1.0

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