Update sys. Re-organize the sources.

This commit is contained in:
sorgelig
2020-05-11 23:17:53 +08:00
parent 0c1cb37dba
commit 5a66d5ec1c
102 changed files with 1996 additions and 1364 deletions

363
rtl/sound/jt12/jt12_reg.v Normal file
View File

@ -0,0 +1,363 @@
`timescale 1ns / 1ps
/* This file is part of JT12.
JT12 program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
JT12 program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JT12. If not, see <http://www.gnu.org/licenses/>.
Author: Jose Tejada Gomez. Twitter: @topapate
Version: 1.0
Date: 14-2-2017
*/
module jt12_reg(
input rst,
input clk,
input [7:0] din,
input [2:0] ch,
input [1:0] op,
input csm,
input flag_A,
input overflow_A,
input up_keyon,
input up_alg,
input up_block,
input up_fnumlo,
input up_pms,
input up_dt1,
input up_tl,
input up_ks_ar,
input up_amen_d1r,
input up_d2r,
input up_d1l,
input up_ssgeg,
output busy,
output reg ch6op, // 1 when the operator belongs to CH6
// CH3 Effect-mode operation
input effect,
input [10:0] fnum_ch3op2,
input [10:0] fnum_ch3op3,
input [10:0] fnum_ch3op1,
input [ 2:0] block_ch3op2,
input [ 2:0] block_ch3op3,
input [ 2:0] block_ch3op1,
// Pipeline order
output reg zero,
output s1_enters,
output s2_enters,
output s3_enters,
output s4_enters,
// Operator
output use_prevprev1,
output use_internal_x,
output use_internal_y,
output use_prev2,
output use_prev1,
// PG
output [10:0] fnum_I,
output [ 2:0] block_I,
// channel configuration
output [1:0] rl,
output reg [2:0] fb_II,
output [2:0] alg,
// Operator multiplying
output [ 3:0] mul_V,
// Operator detuning
output [ 2:0] dt1_II,
// EG
output [4:0] ar_II, // attack rate
output [4:0] d1r_II, // decay rate
output [4:0] d2r_II, // sustain rate
output [3:0] rr_II, // release rate
output [3:0] d1l, // sustain level
output [1:0] ks_III, // key scale
output ssg_en_II,
output [2:0] ssg_eg_II,
output [6:0] tl_VII,
output [2:0] pms,
output [1:0] ams_VII,
output amsen_VII,
// envelope operation
output keyon_II
);
reg [4:0] cnt;
reg [1:0] next_op, cur_op;
reg [2:0] next_ch, cur_ch;
assign s1_enters = cur_op == 2'b00;
assign s3_enters = cur_op == 2'b01;
assign s2_enters = cur_op == 2'b10;
assign s4_enters = cur_op == 2'b11;
wire [4:0] next = { next_op, next_ch };
wire [4:0] cur = { cur_op, cur_ch };
wire [2:0] fb_I;
always @(posedge clk) begin
fb_II <= fb_I;
ch6op <= next_ch==3'd6;
end
// FNUM and BLOCK
wire [10:0] fnum_I_raw;
wire [ 2:0] block_I_raw;
wire effect_on = effect && (cur_ch==3'd2);
wire effect_on_s1 = effect_on && (cur_op == 2'd0 );
wire effect_on_s3 = effect_on && (cur_op == 2'd1 );
wire effect_on_s2 = effect_on && (cur_op == 2'd2 );
wire noeffect = ~|{effect_on_s1, effect_on_s3, effect_on_s2};
assign fnum_I = ( {11{effect_on_s1}} & fnum_ch3op1 ) |
( {11{effect_on_s2}} & fnum_ch3op2 ) |
( {11{effect_on_s3}} & fnum_ch3op3 ) |
( {11{noeffect}} & fnum_I_raw );
assign block_I =( {3{effect_on_s1}} & block_ch3op1 ) |
( {3{effect_on_s2}} & block_ch3op2 ) |
( {3{effect_on_s3}} & block_ch3op3 ) |
( {3{noeffect}} & block_I_raw );
wire [2:0] ch_II, ch_III, ch_IV, ch_V, ch_VI;
wire [4:0] req_opch_I = { op, ch };
wire [4:0] req_opch_II, req_opch_III,
req_opch_IV, req_opch_V, req_opch_VI;
jt12_sumch u_opch_II ( .chin(req_opch_I ), .chout(req_opch_II) );
jt12_sumch u_opch_III( .chin(req_opch_II ), .chout(req_opch_III) );
jt12_sumch u_opch_IV ( .chin(req_opch_III), .chout(req_opch_IV) );
jt12_sumch u_opch_V ( .chin(req_opch_IV ), .chout(req_opch_V) );
jt12_sumch u_opch_VI ( .chin(req_opch_V ), .chout(req_opch_VI) );
wire update_op_I = cur == req_opch_I;
wire update_op_II = cur == req_opch_II;
wire update_op_III= cur == req_opch_III;
// wire update_op_IV = cur == opch_IV;
wire update_op_V = cur == req_opch_V;
// wire update_op_VI = cur == opch_VI;
wire [2:0] op_plus1 = op+2'd1;
wire update_op_VII= cur == { op_plus1[1:0], ch };
// key on/off
wire [3:0] keyon_op = din[7:4];
wire [2:0] keyon_ch = din[2:0];
// channel data
wire [1:0] rl_in = din[7:6];
wire [2:0] fb_in = din[5:3];
wire [2:0] alg_in = din[2:0];
wire [2:0] pms_in = din[2:0];
wire [1:0] ams_in = din[5:4];
wire [2:0] block_in= din[5:3];
wire [2:0] fnhi_in = din[2:0];
wire [7:0] fnlo_in = din;
// operator data
wire [2:0] dt1_in = din[6:4];
wire [3:0] mul_in = din[3:0];
wire [6:0] tl_in = din[6:0];
wire [1:0] ks_in = din[7:6];
wire [4:0] ar_in = din[4:0];
wire amen_in = din[7];
wire [4:0] d1r_in = din[4:0];
wire [4:0] d2r_in = din[4:0];
wire [3:0] d1l_in = din[7:4];
wire [3:0] rr_in = din[3:0];
wire [3:0] ssg_in = din[3:0];
wire [3:0] ssg;
reg last;
wire update_ch_I = cur_ch == ch;
wire up_alg_ch = up_alg & update_ch_I;
wire up_block_ch= up_block & update_ch_I;
wire up_fnumlo_ch=up_fnumlo & update_ch_I;
wire up_pms_ch = up_pms & update_ch_I;
// DT1 & MUL
wire up_dt1_op = up_dt1 & update_op_II;
wire up_mul_op = up_dt1 & update_op_V;
// TL
wire up_tl_op = up_tl & update_op_VII;
// KS & AR
wire up_ks_op = up_ks_ar & update_op_III;
wire up_ar_op = up_ks_ar & update_op_II;
// AM ON, D1R
wire up_amen_op = up_amen_d1r & update_op_VII;
wire up_d1r_op = up_amen_d1r & update_op_II;
// Sustain Rate (D2R)
wire up_d2r_op = up_d2r & update_op_II;
// D1L & RR
wire up_d1l_op = up_d1l & update_op_I;
wire up_rr_op = up_d1l & update_op_II;
// SSG
//wire up_ssgen_op = up_ssgeg & update_op_I;
wire up_ssg_op = up_ssgeg & update_op_II;
wire up = up_alg | up_block | up_fnumlo | up_pms |
up_dt1 | up_tl | up_ks_ar | up_amen_d1r |
up_d2r | up_d1l | up_ssgeg | up_keyon;
always @(*) begin
// next <= cur==5'd23 ? 5'd0 : cur +1'b1;
next_op <= cur_ch==3'd6 ? cur_op+1'b1 : cur_op;
next_ch <= cur_ch[1:0]==2'b10 ? cur_ch+2'd2 : cur_ch+1'd1;
end
reg busy_op;
reg up_keyon_long;
assign busy = busy_op;
always @(posedge clk) begin : up_counter
if( rst ) begin
cnt <= 5'h0;
last <= 1'b0;
zero <= 1'b1;
busy_op <= 1'b0;
up_keyon_long <= 1'b0;
cur_op <= 2'd0;
cur_ch <= 3'd0;
end
else begin
{ cur_op, cur_ch } <= { next_op, next_ch };
zero <= next == 5'd0;
last <= up;
if( up && !last ) begin
cnt <= cur;
busy_op <= 1'b1;
up_keyon_long <= up_keyon;
end
else if( cnt == cur ) begin
busy_op <= 1'b0;
up_keyon_long <= 1'b0;
end
end
end
jt12_kon u_kon(
.rst ( rst ),
.clk ( clk ),
.keyon_op ( keyon_op ),
.keyon_ch ( keyon_ch ),
.cur_op ( cur_op ),
.cur_ch ( cur_ch ),
.up_keyon ( up_keyon_long ),
.csm ( csm ),
.flag_A ( flag_A ),
.overflow_A ( overflow_A),
.keyon_II ( keyon_II )
);
jt12_mod u_mod(
.alg_I ( alg ),
.s1_enters ( s1_enters ),
.s3_enters ( s3_enters ),
.s2_enters ( s2_enters ),
.s4_enters ( s4_enters ),
.use_prevprev1 ( use_prevprev1 ),
.use_internal_x( use_internal_x ),
.use_internal_y( use_internal_y ),
.use_prev2 ( use_prev2 ),
.use_prev1 ( use_prev1 )
);
// memory for OP registers
parameter regop_width=44;
wire [regop_width-1:0] regop_in, regop_out;
jt12_opram u_opram(
.clk ( clk ),
.wr_addr ( cur ),
.rd_addr ( next ),
.data ( regop_in ),
.q ( regop_out )
);
assign regop_in = {
up_tl_op ? tl_in : tl_VII, // 7
up_dt1_op ? dt1_in : dt1_II, // 3
up_mul_op ? mul_in : mul_V, // 4 - 7
up_ks_op ? ks_in : ks_III, // 2 - 16
up_ar_op ? ar_in : ar_II, // 5 - 21
up_amen_op ? amen_in: amsen_VII,// 1 - 22
up_d1r_op ? d1r_in : d1r_II, // 5 - 25
up_d2r_op ? d2r_in : d2r_II, // 5 - 30
up_d1l_op ? d1l_in : d1l, // 4 - 34
up_rr_op ? rr_in : rr_II, // 4 - 38
up_ssg_op ? ssg_in[3] : ssg_en_II, // 1 - 39
up_ssg_op ? ssg_in[2:0] : ssg_eg_II // 3 - 42
};
assign { tl_VII, dt1_II, mul_V, ks_III,
ar_II, amsen_VII, d1r_II, d2r_II, d1l, rr_II,
ssg_en_II, ssg_eg_II } = regop_out;
wire [2:0] block_latch, fnum_latch;
// memory for CH registers
// Block/fnum data is latched until fnum low byte is written to
// Trying to synthesize this memory as M-9K RAM in Altera devices
// turns out worse in terms of resource utilization. Probably because
// this memory is already very small. It is better to leave it as it is.
parameter regch_width=31;
wire [regch_width-1:0] regch_out;
wire [regch_width-1:0] regch_in = {
up_block_ch ? { block_in, fnhi_in } : { block_latch, fnum_latch }, // 3+3
up_fnumlo_ch? { block_latch, fnum_latch, fnlo_in } : { block_I_raw, fnum_I_raw }, // 14
up_alg_ch ? { fb_in, alg_in } : { fb_I, alg },//3+3
up_pms_ch ? { ams_in, pms_in } : { ams_VII, pms }//2+2+3
};
assign { block_latch, fnum_latch,
block_I_raw, fnum_I_raw,
fb_I, alg, ams_VII, pms } = regch_out;
jt12_sh #(.width(regch_width),.stages(6)) u_regch(
.clk ( clk ),
//.rst ( rst ),
.din ( regch_in ),
.drop ( regch_out )
);
// RL is on a different register to
// have the reset to 1
jt12_sh_rst #(.width(2),.stages(6),.rstval(1'b1)) u_regch_rl(
.clk ( clk ),
// .rst ( rst ),
.din ( up_pms_ch ? rl_in : rl ),
.drop ( rl )
);
endmodule