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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [soc/] [sound/] [sound_opl2_channel.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
module sound_opl2_channel(
28
    input                   clk,
29
    input                   rst_n,
30
 
31
    input                   write_20h_35h_op1,
32
    input                   write_40h_55h_op1,
33
    input                   write_60h_75h_op1,
34
    input                   write_80h_95h_op1,
35
    input                   write_E0h_F5h_op1,
36
 
37
    input                   write_20h_35h_op2,
38
    input                   write_40h_55h_op2,
39
    input                   write_60h_75h_op2,
40
    input                   write_80h_95h_op2,
41
    input                   write_E0h_F5h_op2,
42
 
43
    input                   write_A0h_A8h,
44
    input                   write_B0h_B8h,
45
    input                   write_C0h_C8h,
46
 
47
    input           [7:0]   writedata,
48
 
49
    input                   vibrato_depth,
50
    input                   tremolo_depth,
51
    input                   waveform_select_enable,
52
    input                   keyboard_split,
53
 
54
    input           [6:0]   prepare_cnt,
55
 
56
    input                   rythm_enable,
57
    input                   rythm_write,
58
    input                   rythm_bass_drum,
59
    input                   rythm_snare_drum,
60
    input                   rythm_tom_tom,
61
    input                   rythm_cymbal,
62
    input                   rythm_hi_hat,
63
 
64
    input                   channel_6,
65
    input                   channel_7,
66
    input                   channel_8,
67
 
68
    output                  rythm_c1,
69
    output                  rythm_c3,
70
    input                   rythm_phasebit,
71
    input                   rythm_noisebit,
72
 
73
    output reg      [15:0]  chanval
74
);
75
 
76
//------------------------------------------------------------------------------
77
 
78
reg [9:0] await_f_number;
79
always @(posedge clk or negedge rst_n) begin
80
    if(rst_n == 1'b0)       await_f_number <= 10'd0;
81
    else if(write_A0h_A8h)  await_f_number <= { f_number[9:8], writedata };
82
    else if(write_B0h_B8h)  await_f_number <= { writedata[1:0], f_number[7:0] };
83
end
84
 
85
//reg await_key_on; write_B0h_B8h; writedata[5]
86
 
87
reg [2:0] await_octave;
88
always @(posedge clk or negedge rst_n) begin
89
    if(rst_n == 1'b0)       await_octave <= 3'd0;
90
    else if(write_B0h_B8h)  await_octave <= writedata[4:2];
91
end
92
 
93
reg [2:0] await_feedback;
94
always @(posedge clk or negedge rst_n) begin
95
    if(rst_n == 1'b0)       await_feedback <= 3'd0;
96
    else if(write_C0h_C8h)  await_feedback <= writedata[3:1];
97
end
98
 
99
reg await_no_modulation;
100
always @(posedge clk or negedge rst_n) begin
101
    if(rst_n == 1'b0)       await_no_modulation <= 1'b0;
102
    else if(write_C0h_C8h)  await_no_modulation <= writedata[0];
103
end
104
 
105
//------------------------------------------------------------------------------
106
 
107
wire prepare_cnt_load_regs = prepare_cnt == 7'd2;
108
 
109
reg [9:0] f_number;
110
always @(posedge clk or negedge rst_n) begin
111
    if(rst_n == 1'b0)               f_number <= 10'd0;
112
    else if(prepare_cnt_load_regs)  f_number <= await_f_number;
113
end
114
 
115
//reg key_on;
116
 
117
reg [2:0] octave;
118
always @(posedge clk or negedge rst_n) begin
119
    if(rst_n == 1'b0)               octave <= 3'd0;
120
    else if(prepare_cnt_load_regs)  octave <= await_octave;
121
end
122
 
123
reg [2:0] feedback;
124
always @(posedge clk or negedge rst_n) begin
125
    if(rst_n == 1'b0)               feedback <= 3'd0;
126
    else if(prepare_cnt_load_regs)  feedback <= await_feedback;
127
end
128
 
129
reg no_modulation;
130
always @(posedge clk or negedge rst_n) begin
131
    if(rst_n == 1'b0)               no_modulation <= 1'b0;
132
    else if(prepare_cnt_load_regs)  no_modulation <= await_no_modulation;
133
end
134
 
135
//------------------------------------------------------------------------------
136
 
137
wire enable_normal_a     = write_B0h_B8h && writedata[5];
138
wire disable_normal_a    = write_B0h_B8h && ~(writedata[5]);
139
 
140
wire enable_rythm_a      = rythm_write && ((channel_6 &&   rythm_bass_drum)  || (channel_7 &&   rythm_hi_hat)  || (channel_8 &&   rythm_tom_tom));
141
wire disable_percussion_a= rythm_write && ((channel_6 && ~(rythm_bass_drum)) || (channel_7 && ~(rythm_hi_hat)) || (channel_8 && ~(rythm_tom_tom)));
142
 
143
wire enable_normal_b     = write_B0h_B8h && writedata[5];
144
wire disable_normal_b    = write_B0h_B8h && ~(writedata[5]);
145
 
146
wire enable_rythm_b      = rythm_write && ((channel_6 &&   rythm_bass_drum)  || (channel_7 &&   rythm_snare_drum)  || (channel_8 &&   rythm_cymbal));
147
wire disable_percussion_b= rythm_write && ((channel_6 && ~(rythm_bass_drum)) || (channel_7 && ~(rythm_snare_drum)) || (channel_8 && ~(rythm_cymbal)));
148
 
149
//------------------------------------------------------------------------------
150
 
151
wire prepare_cnt_chanval_1 = prepare_cnt == 7'd110;
152
wire prepare_cnt_chanval_2 = prepare_cnt == 7'd111;
153
 
154
//------------------------------------------------------------------------------
155
 
156
wire [14:0] cval_op_b_times_2 = (cval_op_b[15] == 1'b0 && cval_op_b > 16'h3FFF)? 15'h3FFF : (cval_op_b[15] == 1'b1 && cval_op_b < 16'hC000)? 15'h4000 : cval_op_b[14:0];
157
wire [14:0] cval_op_a_times_2 = (cval_op_a[15] == 1'b0 && cval_op_a > 16'h3FFF)? 15'h3FFF : (cval_op_a[15] == 1'b1 && cval_op_a < 16'hC000)? 15'h4000 : cval_op_a[14:0];
158
 
159
wire [16:0] cval_op_a_times_2_sum   = chanval + { cval_op_a_times_2, 1'b0 };
160
wire [15:0] cval_op_a_times_2_final =
161
    (cval_op_a_times_2_sum[16] == 1'b1 && chanval[15] == 1'b0 && cval_op_a_times_2[14] == 1'b0)?    16'h7FFF :
162
    (cval_op_a_times_2_sum[16] == 1'b0 && chanval[15] == 1'b1 && cval_op_a_times_2[14] == 1'b1)?    16'h8000 :
163
                                                                                                    cval_op_a_times_2_sum[15:0];
164
wire [16:0] cval_op_a_sum   = chanval + cval_op_a;
165
wire [15:0] cval_op_a_final =
166
    (cval_op_a_sum[16] == 1'b1 && chanval[15] == 1'b0 && cval_op_a[14] == 1'b0)?    16'h7FFF :
167
    (cval_op_a_sum[16] == 1'b0 && chanval[15] == 1'b1 && cval_op_a[14] == 1'b1)?    16'h8000 :
168
                                                                                    cval_op_a_sum[15:0];
169
 
170
always @(posedge clk or negedge rst_n) begin
171
    if(rst_n == 1'b0)                                                                                                       chanval <= 16'd0;
172
 
173
    else if(prepare_cnt_chanval_1 && rythm_enable && channel_6)                                                             chanval <= { cval_op_b_times_2, 1'b0 };
174
    else if(prepare_cnt_chanval_1 && rythm_enable && (channel_7 || channel_8))                                              chanval <= { cval_op_b_times_2, 1'b0 };
175
    else if(prepare_cnt_chanval_2 && rythm_enable && (channel_7 || channel_8))                                              chanval <= cval_op_a_times_2_final;
176
 
177
    else if(prepare_cnt_chanval_1 && (~(rythm_enable) || (~(channel_6) && ~(channel_7) && ~(channel_8))))                   chanval <= cval_op_b;
178
    else if(prepare_cnt_chanval_2 && (~(rythm_enable) || (~(channel_6) && ~(channel_7) && ~(channel_8))) && no_modulation)  chanval <= cval_op_a_final;
179
 
180
    else if(prepare_cnt_chanval_1)                                                                                          chanval <= 16'd0;
181
end
182
 
183
wire modulate_with_feedback =
184
    (rythm_enable && channel_6 && ~(no_modulation)) ||
185
    (~(rythm_enable) || (~(channel_6) && ~(channel_7) && ~(channel_8)));
186
 
187
wire modulate_op_b =
188
    (rythm_enable && channel_6 && ~(no_modulation)) ||
189
    ((~(rythm_enable) || (~(channel_6) && ~(channel_7) && ~(channel_8))) && ~(no_modulation));
190
 
191
wire [15:0] modulator_b = (modulate_op_b)? cval_op_a : 16'd0;
192
 
193
wire [2:0] feedback_a   = (modulate_with_feedback)? feedback : 3'd0;
194
 
195
 
196
//------------------------------------------------------------------------------
197
 
198
//6.0 drum bass
199
//6.1 drum bass
200
//7.0 hi hat
201
//7.1 snare
202
//8.0 tom tom
203
//8.1 cymbal
204
 
205
//------------------------------------------------------------------------------
206
 
207
wire [16:0] freq_and_octave =
208
    (octave == 3'd0)?   { 7'd0, f_number } :
209
    (octave == 3'd1)?   { 6'd0, f_number, 1'd0 } :
210
    (octave == 3'd2)?   { 5'd0, f_number, 2'd0 } :
211
    (octave == 3'd3)?   { 4'd0, f_number, 3'd0 } :
212
    (octave == 3'd4)?   { 3'd0, f_number, 4'd0 } :
213
    (octave == 3'd5)?   { 2'd0, f_number, 5'd0 } :
214
    (octave == 3'd6)?   { 1'd0, f_number, 6'd0 } :
215
                        {       f_number, 7'd0 };
216
 
217
//------------------------------------------------------------------------------
218
 
219
wire wform_decrel_request_a;
220
wire wform_decrel_request_b;
221
 
222
wire [7:0]  wform_decrel_address_a;
223
wire [7:0]  wform_decrel_address_b;
224
 
225
wire [15:0] wform_decrel_q_a;
226
wire [15:0] wform_decrel_q_b;
227
 
228
simple_rom #(
229
    .widthad    (9),
230
    .width      (16),
231
    .datafile   ("./../soc/sound/opl2_waveform_rom.hex")
232
)
233
waveform_rom_inst (
234
    .clk        (clk),
235
 
236
    .addr_a     ({ wform_decrel_request_a, wform_decrel_address_a }),
237
    .addr_b     ({ wform_decrel_request_b, wform_decrel_address_b }),
238
    .q_a        (wform_decrel_q_a),
239
    .q_b        (wform_decrel_q_b)
240
);
241
 
242
//------------------------------------------------------------------------------
243
 
244
wire [7:0] attack_address_a;
245
wire [7:0] attack_address_b;
246
 
247
wire [19:0] attack_value_a;
248
wire [19:0] attack_value_b;
249
 
250
simple_rom #(
251
    .widthad    (8),
252
    .width      (20),
253
    .datafile   ("./../soc/sound/opl2_attack_rom.hex")
254
)
255
attack_rom_inst (
256
    .clk        (clk),
257
 
258
    .addr_a     (attack_address_a),
259
    .addr_b     (attack_address_b),
260
 
261
    .q_a        (attack_value_a),
262
    .q_b        (attack_value_b)
263
);
264
 
265
//------------------------------------------------------------------------------
266
 
267
wire [15:0] cval_op_a;
268
wire [15:0] cval_op_b;
269
 
270
wire rythm_c2;
271
 
272
sound_opl2_operator op1_inst(
273
    .clk                    (clk),
274
    .rst_n                  (rst_n),
275
 
276
    .write_20h_35h          (write_20h_35h_op1),        //input
277
    .write_40h_55h          (write_40h_55h_op1),        //input
278
    .write_60h_75h          (write_60h_75h_op1),        //input
279
    .write_80h_95h          (write_80h_95h_op1),        //input
280
    .write_E0h_F5h          (write_E0h_F5h_op1),        //input
281
 
282
    .writedata              (writedata),                //input [7:0]
283
 
284
    .freq_and_octave        (freq_and_octave),          //input [16:0]
285
    .freq_high              (f_number[9:6]),            //input [3:0]
286
    .octave                 (octave),                   //input [2:0]
287
    .feedback               (feedback_a),               //input [2:0]
288
 
289
    .vibrato_depth          (vibrato_depth),            //input
290
    .tremolo_depth          (tremolo_depth),            //input
291
 
292
    .wform_decrel_request   (wform_decrel_request_a),   //output
293
    .wform_decrel_address   (wform_decrel_address_a),   //output [7:0]
294
    .wform_decrel_q         (wform_decrel_q_a),         //input [15:0]
295
 
296
    .waveform_select_enable (waveform_select_enable),   //input
297
 
298
    .cval                   (cval_op_a),                //output [15:0]
299
    .keyboard_split         (keyboard_split),           //input
300
 
301
    .attack_address         (attack_address_a),         //output [7:0]
302
    .attack_value           (attack_value_a),           //input [19:0]
303
 
304
    .prepare_cnt            (prepare_cnt),              //input [6:0]
305
 
306
    .enable_normal          (enable_normal_a),          //input
307
    .enable_rythm           (enable_rythm_a),           //input
308
    .disable_normal         (disable_normal_a),         //input
309
    .disable_percussion     (disable_percussion_a),     //input
310
 
311
    .rythm_c1               (rythm_c1),                 //output
312
    .rythm_c2               (rythm_c2),                 //output
313
    /* verilator lint_off PINNOCONNECT */
314
    .rythm_c3               (),                         //output / not used
315
    /* verilator lint_on PINNOCONNECT */
316
 
317
    .rythm_phasebit         (rythm_phasebit),           //input
318
    .rythm_noisebit         (rythm_noisebit),           //input
319
    .rythm_snarebit         (1'b0),                     //input
320
 
321
    .rythm_hihat            (channel_7),                //input
322
    .rythm_snare            (1'b0),                     //input
323
    .rythm_cymbal           (1'b0),                     //input
324
 
325
    .operator_a             (1'b1),                     //input
326
    .operator_b             (1'b0),                     //input
327
 
328
    .modulator              (16'd0)                     //input [15:0]
329
);
330
 
331
sound_opl2_operator op2_inst(
332
    .clk                    (clk),
333
    .rst_n                  (rst_n),
334
 
335
    .write_20h_35h          (write_20h_35h_op2),        //input
336
    .write_40h_55h          (write_40h_55h_op2),        //input
337
    .write_60h_75h          (write_60h_75h_op2),        //input
338
    .write_80h_95h          (write_80h_95h_op2),        //input
339
    .write_E0h_F5h          (write_E0h_F5h_op2),        //input
340
 
341
    .writedata              (writedata),                //input [7:0]
342
 
343
    .freq_and_octave        (freq_and_octave),          //input [16:0]
344
    .freq_high              (f_number[9:6]),            //input [3:0]
345
    .octave                 (octave),                   //input [2:0]
346
    .feedback               (3'd0),                     //input [2:0]
347
 
348
    .vibrato_depth          (vibrato_depth),            //input
349
    .tremolo_depth          (tremolo_depth),            //input
350
 
351
    .wform_decrel_request   (wform_decrel_request_b),   //output
352
    .wform_decrel_address   (wform_decrel_address_b),   //output [7:0]
353
    .wform_decrel_q         (wform_decrel_q_b),         //input [15:0]
354
 
355
    .waveform_select_enable (waveform_select_enable),   //input
356
 
357
    .cval                   (cval_op_b),                //output [15:0]
358
    .keyboard_split         (keyboard_split),           //input
359
 
360
    .attack_address         (attack_address_b),         //output [7:0]
361
    .attack_value           (attack_value_b),           //input [19:0]
362
 
363
    .prepare_cnt            (prepare_cnt),              //input [6:0]
364
 
365
    .enable_normal          (enable_normal_b),          //input
366
    .enable_rythm           (enable_rythm_b),           //input
367
    .disable_normal         (disable_normal_b),         //input
368
    .disable_percussion     (disable_percussion_b),     //input
369
 
370
    /* verilator lint_off PINNOCONNECT */
371
    .rythm_c1               (),                         //output / not used
372
    .rythm_c2               (),                         //output / not used
373
    /* verilator lint_on PINNOCONNECT */
374
    .rythm_c3               (rythm_c3),                 //output
375
 
376
    .rythm_phasebit         (rythm_phasebit),           //input
377
    .rythm_noisebit         (rythm_noisebit),           //input
378
    .rythm_snarebit         (rythm_c2),                 //input
379
 
380
    .rythm_hihat            (1'b0),                     //input
381
    .rythm_snare            (channel_7),                //input
382
    .rythm_cymbal           (channel_8),                //input
383
 
384
    .operator_a             (1'b0),                     //input
385
    .operator_b             (1'b1),                     //input
386
 
387
    .modulator              (modulator_b)               //input [15:0]
388
);
389
 
390
//------------------------------------------------------------------------------
391
 
392
//------------------------------------------------------------------------------
393
 
394
endmodule

powered by: WebSVN 2.1.0

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