1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-04-25 03:54:57 +00:00
Files
Gehstock.Mist_FPGA/common/Sound/jtopl/jtopl_reg.v
Gyorgy Szombathelyi 8070eddf08 Update jtopl
2022-10-13 18:44:30 +02:00

200 lines
5.8 KiB
Verilog

/* This file is part of JTOPL
JTOPL 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.
JTOPL 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 JTOPL. If not, see <http://www.gnu.org/licenses/>.
Author: Jose Tejada Gomez. Twitter: @topapate
Version: 1.0
Date: 13-6-2020
*/
module jtopl_reg(
input rst,
input clk,
input cen,
input [7:0] din,
input write,
// Pipeline order
output zero,
output [1:0] group,
output op, // 0 for modulator operators
output [17:0] slot, // hot one encoding of active slot
input [1:0] sel_group, // group to update
input [2:0] sel_sub, // subslot to update
input rhy_en, // rhythm enable
input [4:0] rhy_kon, // key-on for each rhythm instrument
//input csm,
//input flag_A,
//input overflow_A,
input up_fbcon,
input up_fnumlo,
input up_fnumhi,
input up_mult,
input up_ksl_tl,
input up_ar_dr,
input up_sl_rr,
input up_wav,
// PG
output [9:0] fnum_I,
output [2:0] block_I,
// channel configuration
output [2:0] fb_I,
output [3:0] mul_II, // frequency multiplier
output [1:0] ksl_IV, // key shift level
output amen_IV,
output viben_I,
// OP
output [1:0] wavsel_I,
input wave_mode,
// EG
output keyon_I,
output [5:0] tl_IV,
output en_sus_I, // enable sustain
output [3:0] arate_I, // attack rate
output [3:0] drate_I, // decay rate
output [3:0] rrate_I, // release rate
output [3:0] sl_I, // sustain level
output ks_II, // key scale
output con_I
);
parameter OPL_TYPE=1;
localparam CH=9;
wire [2:0] subslot;
wire match;
// channel data
wire [2:0] fb_in = din[3:1];
wire con_in = din[0];
wire up_fnumlo_ch = up_fnumlo & match,
up_fnumhi_ch = up_fnumhi & match,
up_fbcon_ch = up_fbcon & match,
update_op_I = !write && sel_group == group && sel_sub == subslot;
reg update_op_II, update_op_III, update_op_IV;
assign match = { group, subslot } == { sel_group, sel_sub};
jtopl_slot_cnt u_slot_cnt(
.rst ( rst ),
.clk ( clk ),
.cen ( cen ),
// Pipeline order
.zero ( zero ),
.group ( group ),
.op ( op ), // 0 for modulator operators
.subslot(subslot),
.slot ( slot ) // hot one encoding of active slot
);
always @(posedge clk) begin
if(write) begin
update_op_II <= 0;
update_op_III <= 0;
update_op_IV <= 0;
end else if( cen ) begin
update_op_II <= update_op_I;
update_op_III <= update_op_II;
update_op_IV <= update_op_III;
end
end
localparam OPCFGW = 4*8 + (OPL_TYPE!=1 ? 2 : 0);
wire [OPCFGW-1:0] shift_out;
wire en_sus, rhy_oen;
// Sustained is disabled in rhythm mode for channels in group 2 (i.e. 6,7,8)
assign en_sus_I = rhy_oen ? 1'b0 : en_sus;
jtopl_csr #(.LEN(CH*2),.W(OPCFGW), .OPL_TYPE(OPL_TYPE)) u_csr(
.rst ( rst ),
.clk ( clk ),
.cen ( cen ),
.din ( din ),
.shift_out ( shift_out ),
.up_mult ( up_mult ),
.up_ksl_tl ( up_ksl_tl ),
.up_ar_dr ( up_ar_dr ),
.up_sl_rr ( up_sl_rr ),
.up_wav ( up_wav ),
.update_op_I ( update_op_I ),
.update_op_II ( update_op_II ),
.update_op_IV ( update_op_IV )
);
assign { amen_IV, viben_I, en_sus, ks_II, mul_II,
ksl_IV, tl_IV,
arate_I, drate_I,
sl_I, rrate_I } = shift_out[4*8-1:0];
generate
if( OPL_TYPE==1 )
assign wavsel_I = 0;
else
assign wavsel_I = shift_out[OPCFGW-1:OPCFGW-2] & {2{wave_mode}};
endgenerate
// Memory for CH registers
localparam KONW = 1,
FNUMW = 10,
BLOCKW = 3,
FBW = 3,
CONW = 1;
localparam CHCSRW = KONW+FNUMW+BLOCKW+FBW+CONW;
wire [CHCSRW-1:0] chcfg, chcfg_inmux;
wire keyon_csr, con_csr, rhyon_csr;
wire disable_con;
assign chcfg_inmux = {
up_fnumhi_ch ? din[5:0] : { keyon_csr, block_I, fnum_I[9:8] },
up_fnumlo_ch ? din : fnum_I[7:0],
up_fbcon_ch ? { fb_in, con_in } : { fb_I, con_csr }
};
assign disable_con = rhy_oen && !slot[12] && !slot[13];
assign con_I = !rhy_en || !disable_con ? con_csr : 1'b1;
assign { keyon_csr, block_I, fnum_I, fb_I, con_csr } = chcfg;
assign keyon_I = rhy_oen ? rhyon_csr : keyon_csr;
jtopl_reg_ch#(CHCSRW) u_reg_ch(
.rst ( rst ),
.clk ( clk ),
.cen ( cen ),
.zero ( zero ),
.rhy_en ( rhy_en ),
.rhy_kon ( rhy_kon ),
.slot ( slot ),
.group ( group ),
.chcfg_inmux ( chcfg_inmux ),
.chcfg ( chcfg ),
.rhy_oen ( rhy_oen ),
.rhyon_csr ( rhyon_csr )
);
endmodule