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

Subversion Repositories psg16

[/] [psg16/] [trunk/] [rtl/] [verilog/] [PSG32.v] - Blame information for rev 4

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

Line No. Rev Author Line
1 4 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2007-2017  Robert Finch, Waterloo
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch<remove>@finitron.ca
7
//       ||
8
//
9
// PSG32.v
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
//
25
//      Registers
26
//  00      -------- ffffffff ffffffff ffffffff     freq [23:0]
27
//  04      -------- -------- pppppppp pppppppp     pulse width
28
//      08          -------- -------- trsg--fo -vvvvv--         test, ringmod, sync, gate, filter, output, voice type
29
//  0C      aaaaaaaa aaaaaaaa dddddddd dddddddd     attack, decay
30
//  10      -------- ssssssss rrrrrrrr rrrrrrrr     sustain, release
31
//  14      -------- -------- --aaaaaa aaaaaaa-     wave table base address
32
//                                                                                      vvvvv
33
//                                                                                      wnpst
34
//  18-2C   Voice #2
35
//  30-44   Voice #3
36
//  48-5C   Voice #4
37
//
38
//      ...
39
//      B0      -------- -------- -------- vvvvvvvv   volume (0-255)
40
//      B4      nnnnnnnn nnnnnnnn nnnnnnnn nnnnnnnn   osc3 oscillator 3
41
//      B8      -------- -------- -------- nnnnnnnn   env3 envelope 3
42
//
43
//  C0-DC   -------- -------- s---kkkk kkkkkkkk   filter coefficients
44
//  E0-FC   -------- -------- -------- --------   reserved for more filter coefficients
45
//
46
//=============================================================================
47
 
48
module PSG32(rst_i, clk_i, cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o,
49
        m_adr_o, m_dat_i, o
50
);
51
parameter pClkDivide = 37;
52
 
53
// WISHBONE SYSCON
54
input rst_i;
55
input clk_i;                    // system clock
56
// NON-WISHBONE
57
input cs_i;             // circuit select
58
// WISHBONE SLAVE
59
input cyc_i;                    // cycle valid
60
input stb_i;                    // circuit select
61
output ack_o;
62
input we_i;                             // write
63
input [7:0] adr_i;               // address input
64
input [31:0] dat_i;              // data input
65
output [31:0] dat_o;     // data output
66
 
67
// WISHBONE MASTER
68
output [13:0] m_adr_o;   // wave table address
69
input  [11:0] m_dat_i;   // wave table data input
70
 
71
output [17:0] o;
72
 
73
// I/O registers
74
reg [31:0] dat_o;
75
reg [13:0] m_adr_o;
76
 
77
reg [3:0] test;                          // test (enable note generator)
78
reg [4:0] vt [3:0];                       // voice type
79
reg [23:0] freq0, freq1, freq2, freq3;   // frequency control
80
reg [15:0] pw0, pw1, pw2, pw3;                   // pulse width control
81
reg [3:0] gate;
82
reg [15:0] attack0, attack1, attack2, attack3;
83
reg [15:0] decay0, decay1, decay2, decay3;
84
reg [7:0] sustain0, sustain1, sustain2, sustain3;
85
reg [15:0] relese0, relese1, relese2, relese3;
86
reg [13:0] wtadr0, wtadr1, wtadr2, wtadr3;
87
reg [3:0] sync;
88
reg [3:0] ringmod;
89
reg [3:0] outctrl;
90
reg [3:0] filt;                // 1 = output goes to filter
91
wire [31:0] acc0, acc1, acc2, acc3;
92
reg [7:0] volume;        // master volume
93
wire [11:0] tg1_o,tg2_o,tg3_o,tg4_o;    // tone generator output
94
wire [7:0] env;          // envelope generator output
95
wire [7:0] env3;
96
wire [19:0] out0,out1,out2,out3;
97
wire [2:0] es0,es1,es2,es3;
98
wire [29:0] out4;
99
reg [21:0] sum,fsum;
100
reg [21:0] sum2;
101
wire [21:0] filtin1;     // FIR filter input
102
wire [37:0] filt_o;              // FIR filter output
103
reg [1:0] cnt;
104
reg [1:0] cnt1,cnt2,cnt3;
105
 
106
// channel select signal
107
wire [1:0] sel = cnt[1:0];
108
 
109
and(cs, cyc_i, stb_i, cs_i);
110
reg ack1,ack2;
111
always @(posedge clk_i)
112
        ack1 <= cs;
113
always @(posedge clk_i)
114
    ack2 <= ack1 & cs;
115
assign ack_o = cs ? (we_i ? 1'b1 : ack2) : 1'b0;
116
 
117
// Register shadow ram for register readback
118
reg [15:0] reg_shadow [63:0];
119
reg [8:0] radr;
120
always @(posedge clk_i)
121
    if (cs & we_i)  reg_shadow[adr_i[7:2]] <= dat_i[15:0];
122
always @(posedge clk_i)
123
    radr <= adr_i[7:2];
124
wire [15:0] reg_shadow_o = reg_shadow[radr];
125
 
126
// write to registers
127
always @(posedge clk_i)
128
begin
129
        if (rst_i) begin
130
                freq0 <= 0;
131
                freq1 <= 0;
132
                freq2 <= 0;
133
                freq3 <= 0;
134
                pw0 <= 0;
135
                pw1 <= 0;
136
                pw2 <= 0;
137
                pw3 <= 0;
138
                test <= 0;
139
                vt[0] <= 0;
140
                vt[1] <= 0;
141
                vt[2] <= 0;
142
                vt[3] <= 0;
143
                gate <= 0;
144
                outctrl <= 0;
145
                filt <= 0;
146
                attack0 <= 0;
147
                attack1 <= 0;
148
                attack2 <= 0;
149
                attack3 <= 0;
150
                decay0 <= 0;
151
                sustain0 <= 0;
152
                relese0 <= 0;
153
                decay1 <= 0;
154
                sustain1 <= 0;
155
                relese1 <= 0;
156
                decay2 <= 0;
157
                sustain2 <= 0;
158
                relese2 <= 0;
159
                decay3 <= 0;
160
                sustain3 <= 0;
161
                relese3 <= 0;
162
                sync <= 0;
163
                ringmod <= 0;
164
                volume <= 0;
165
        end
166
        else begin
167
                if (cs & we_i) begin
168
                        case(adr_i[7:2])
169
                        //---------------------------------------------------------
170
                        6'd00:  freq0 <= dat_i[23:0];
171
                        6'd01:  pw0 <= dat_i[15:0];
172
                        6'd02:  begin
173
                                                vt[0] <= dat_i[6:2];
174
                                                outctrl[0] <= dat_i[8];
175
                                                filt[0] <= dat_i[9];
176
                                                gate[0] <= dat_i[12];
177
                                                sync[0] <= dat_i[13];
178
                                                ringmod[0] <= dat_i[14];
179
                                                test[0] <= dat_i[15];
180
                                        end
181
                        6'd03:  begin
182
                                        attack0 <= dat_i[31:16];
183
                                        decay0 <= dat_i[15:0];
184
                                        end
185
                    6'd04:   begin
186
                                        relese0 <= dat_i[15:0];
187
                                        sustain0 <= dat_i[23:16];
188
                                        end
189
            6'd05:  wtadr0 <= {dat_i[13:1],1'b0};
190
 
191
                        //---------------------------------------------------------
192
                        6'd06:  freq1 <= dat_i[23:0];
193
                        6'd07:  pw1 <= dat_i[15:0];
194
                        6'd08:  begin
195
                                                vt[1] <= dat_i[6:2];
196
                                                outctrl[1] <= dat_i[8];
197
                                                filt[1] <= dat_i[9];
198
                                                gate[1] <= dat_i[12];
199
                                                sync[1] <= dat_i[13];
200
                                                ringmod[1] <= dat_i[14];
201
                                                test[1] <= dat_i[15];
202
                                        end
203
                        6'd09:  begin
204
                                        attack1 <= dat_i[31:16];
205
                                        decay1 <= dat_i[15:0];
206
                                        end
207
                    6'd10:
208
                                        begin
209
                                        relese1 <= dat_i[15:0];
210
                                        sustain1 <= dat_i[23:16];
211
                                        end
212
            6'd11:  wtadr1 <= {dat_i[13:1],1'b0};
213
 
214
                        //---------------------------------------------------------
215
                        6'd12:  freq2 <= dat_i[23:0];
216
                        6'd13:  pw2 <= dat_i[15:0];
217
                        6'd14:  begin
218
                                                vt[2] <= dat_i[6:2];
219
                                                outctrl[2] <= dat_i[8];
220
                                                filt[2] <= dat_i[9];
221
                                                gate[2] <= dat_i[12];
222
                                                sync[2] <= dat_i[5];
223
                                                outctrl[0] <= dat_i[13];
224
                                                ringmod[2] <= dat_i[14];
225
                                                test[2] <= dat_i[15];
226
                                        end
227
                        6'd15:  begin
228
                                        attack2 <= dat_i[31:16];
229
                                        decay2 <= dat_i[15:0];
230
                                        end
231
                    6'd16:      begin
232
                                        relese2 <= dat_i[15:0];
233
                                        sustain2 <= dat_i[23:16];
234
                                        end
235
            6'd17:  wtadr1 <= {dat_i[13:1],1'b0};
236
 
237
                        //---------------------------------------------------------
238
                        6'd18:  freq3 <= dat_i[23:0];
239
                        6'd19:  pw3 <= dat_i[15:0];
240
                        6'd20:  begin
241
                                                vt[3] <= dat_i[6:2];
242
                                                outctrl[3] <= dat_i[8];
243
                                                filt[3] <= dat_i[9];
244
                                                gate[3] <= dat_i[12];
245
                                                sync[3] <= dat_i[13];
246
                                                ringmod[3] <= dat_i[14];
247
                                                test[3] <= dat_i[15];
248
                                        end
249
                        6'd21:  begin
250
                                        attack3 <= dat_i[31:16];
251
                                        decay3 <= dat_i[15:0];
252
                                        relese3 <= dat_i[15:0];
253
                                        sustain3 <= dat_i[23:16];
254
                                        end
255
            6'd22:  wtadr1 <= {dat_i[13:1],1'b0};
256
 
257
                        //---------------------------------------------------------
258
                        6'd44:  volume <= dat_i[7:0];
259
 
260
                        default:        ;
261
                        endcase
262
                end
263
        end
264
end
265
 
266
 
267
always @(posedge clk_i)
268
    case(adr_i[7:2])
269
    6'd45:      begin
270
            dat_o <= acc3;
271
            end
272
    6'd45:      begin
273
            dat_o <= {24'h0,env3};
274
            end
275
    6'd46:  dat_o <= {17'h0,es3,1'b0,es2,1'b0,es1,1'b0,es0};
276
    default: begin
277
            dat_o <= reg_shadow_o;
278
            end
279
    endcase
280
 
281
wire [13:0] madr;
282
mux4to1 #(12) u11
283
(
284
        .e(1'b1),
285
        .s(cnt),
286
        .i0(wtadr0 + {acc0[27:17],1'b0}),
287
        .i1(wtadr1 + {acc1[27:17],1'b0}),
288
        .i2(wtadr2 + {acc2[27:17],1'b0}),
289
        .i3(wtadr3 + {acc3[27:17],1'b0}),
290
        .z(madr)
291
);
292
always @(posedge clk_i)
293
    m_adr_o <= madr;
294
 
295
// This counter controls channel multiplexing for the wave table
296
always @(posedge clk_i)
297
if (rst_i)
298
    cnt <= 2'd0;
299
else
300
    cnt <= cnt + 2'd1;
301
 
302
// note generator - multi-channel
303
PSGToneGenerator u1a
304
(
305
    .rst(rst_i),
306
    .clk(clk_i),
307
    .ack(cnt==2'b11),
308
    .test(test[0]),
309
    .vt(vt[0]),
310
    .freq(freq0),
311
    .pw(pw0),
312
    .acc(acc0),
313
    .prev_acc(acc3),
314
    .wave(wave_i),
315
    .sync(sync[0]),
316
    .ringmod(ringmod[0]),
317
    .o(tg1_o)
318
);
319
 
320
PSGToneGenerator u1b
321
(
322
    .rst(rst_i),
323
    .clk(clk_i),
324
    .ack(cnt==2'b00),
325
    .test(test[1]),
326
    .vt(vt[1]),
327
    .freq(freq1),
328
    .pw(pw1),
329
    .acc(acc1),
330
    .prev_acc(acc0),
331
    .wave(wave_i),
332
    .sync(sync[1]),
333
    .ringmod(ringmod[1]),
334
    .o(tg2_o)
335
);
336
 
337
PSGToneGenerator u1c
338
(
339
    .rst(rst_i),
340
    .clk(clk_i),
341
    .ack(cnt==2'b01),
342
    .test(test[2]),
343
    .vt(vt[2]),
344
    .freq(freq2),
345
    .pw(pw2),
346
    .acc(acc2),
347
    .prev_acc(acc1),
348
    .wave(wave_i),
349
    .sync(sync[2]),
350
    .ringmod(ringmod[2]),
351
    .o(tg3_o)
352
);
353
 
354
PSGToneGenerator u1d
355
(
356
    .rst(rst_i),
357
    .clk(clk_i),
358
    .ack(cnt==2'b10),
359
    .test(test[3]),
360
    .vt(vt[3]),
361
    .freq(freq3),
362
    .pw(pw3),
363
    .acc(acc3),
364
    .prev_acc(acc2),
365
    .wave(wave_i),
366
    .sync(sync[3]),
367
    .ringmod(ringmod[3]),
368
    .o(tg4_o)
369
);
370
 
371
PSGEnvelopeGenerator u2a
372
(
373
    .rst(rst_i),
374
    .clk(clk_i),
375
    .gate(gate[0]),
376
    .attack(attack0),
377
    .decay(decay0),
378
    .sustain(sustain0),
379
    .relese(relese0),
380
    .o(env0),
381
    .envState(es0)
382
);
383
 
384
PSGEnvelopeGenerator u2b
385
(
386
    .rst(rst_i),
387
    .clk(clk_i),
388
    .gate(gate[1]),
389
    .attack(attack1),
390
    .decay(decay1),
391
    .sustain(sustain1),
392
    .relese(relese1),
393
    .o(env1),
394
    .envState(es1)
395
);
396
 
397
PSGEnvelopeGenerator u2c
398
(
399
    .rst(rst_i),
400
    .clk(clk_i),
401
    .gate(gate[2]),
402
    .attack(attack2),
403
    .decay(decay2),
404
    .sustain(sustain2),
405
    .relese(relese2),
406
    .o(env2),
407
    .envState(es2)
408
);
409
 
410
PSGEnvelopeGenerator u2d
411
(
412
    .rst(rst_i),
413
    .clk(clk_i),
414
    .gate(gate[3]),
415
    .attack(attack3),
416
    .decay(decay3),
417
    .sustain(sustain3),
418
    .relese(relese3),
419
    .o(env3),
420
    .envState(es3)
421
);
422
 
423
// shape output according to envelope
424
PSGShaper u5a
425
(
426
        .clk_i(clk_i),
427
        .ce(1'b1),
428
        .tgi(tg1_o),
429
        .env(env0),
430
        .o(out0)
431
);
432
 
433
PSGShaper u5b
434
(
435
        .clk_i(clk_i),
436
        .ce(1'b1),
437
        .tgi(tg2_o),
438
        .env(env1),
439
        .o(out1)
440
);
441
 
442
PSGShaper u5c
443
(
444
        .clk_i(clk_i),
445
        .ce(1'b1),
446
        .tgi(tg3_o),
447
        .env(env2),
448
        .o(out2)
449
);
450
 
451
PSGShaper u5d
452
(
453
        .clk_i(clk_i),
454
        .ce(1'b1),
455
        .tgi(tg4_o),
456
        .env(env3),
457
        .o(out3)
458
);
459
 
460
always @(posedge clk_i)
461
        cnt1 <= cnt;
462
always @(posedge clk_i)
463
        cnt2 <= cnt1;
464
always @(posedge clk_i)
465
        cnt3 <= cnt2;
466
 
467
// Sum the channels not going to the filter
468
always @(posedge clk_i)
469
sum <=
470
    {2'd0,(out0 & {20{outctrl[0]}})} +
471
    {2'd0,(out1 & {20{outctrl[1]}})} +
472
    {2'd0,(out2 & {20{outctrl[2]}})} +
473
    {2'd0,(out3 & {20{outctrl[3]}})};
474
 
475
// Sum the channels going to the filter
476
always @(posedge clk_i)
477
fsum <=
478
    {2'd0,(out0 & {20{filt[0]}})} +
479
    {2'd0,(out1 & {20{filt[1]}})} +
480
    {2'd0,(out2 & {20{filt[2]}})} +
481
    {2'd0,(out3 & {20{filt[3]}})};
482
 
483
// The FIR filter
484
PSGFilter2 u8
485
(
486
        .rst(rst_i),
487
        .clk(clk_i),
488
        .cnt(cnt2),
489
        .wr(we_i && stb_i && adr_i[7:6]==3'b11),
490
    .adr(adr_i[5:2]),
491
    .din({dat_i[15],dat_i[11:0]}),
492
    .i(fsum),
493
    .o(filt_o)
494
);
495
 
496
// Sum the filtered and unfiltered output
497
always @(posedge clk_i)
498
        sum2 <= sum + filt_o[37:16];
499
 
500
// Last stage:
501
// Adjust output according to master volume
502
PSGVolumeControl u10
503
(
504
        .rst_i(rst_i),
505
        .clk_i(clk_i),
506
        .i(sum2),
507
        .volume(volume),
508
        .o(out4)
509
);
510
 
511
assign o = out4[29:12];
512
 
513
endmodule

powered by: WebSVN 2.1.0

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