1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-04-28 05:05:19 +00:00
Files
Gehstock.Mist_FPGA/common/Sound/jt51/jt51_pg.v
2020-04-13 22:15:49 +02:00

301 lines
8.1 KiB
Verilog

/* This file is part of JT51.
JT51 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.
JT51 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 JT51. If not, see <http://www.gnu.org/licenses/>.
Author: Jose Tejada Gomez. Twitter: @topapate
Version: 1.0
Date: 27-10-2016
*/
`timescale 1ns / 1ps
module jt51_pg(
input rst,
input clk,
input cen /* direct_enable */,
input zero,
// Channel frequency
input [6:0] kc_I,
input [5:0] kf_I,
// Operator multiplying
input [3:0] mul_VI,
// Operator detuning
input [2:0] dt1_II,
input [1:0] dt2_I,
// phase modulation from LFO
input [7:0] pm,
input [2:0] pms_I,
// phase operation
input pg_rst_III,
output reg [ 4:0] keycode_III,
output [ 9:0] pg_phase_X
);
wire [19:0] ph_VII;
reg [19:0] phase_base_VI, phase_step_VII, ph_VIII;
reg [17:0] phase_base_IV, phase_base_V;
wire pg_rst_VII;
wire [11:0] phinc_III;
reg [ 9:0] phinc_addr_III;
reg [13:0] keycode_II;
reg [5:0] dt1_kf_III;
reg [ 2:0] dt1_kf_IV;
reg [4:0] pow2;
reg [4:0] dt1_offset_V;
reg [2:0] pow2ind_IV;
reg [2:0] dt1_III, dt1_IV, dt1_V;
jt51_phinc_rom u_phinctable(
// .clk ( clk ),
.keycode( phinc_addr_III[9:0] ),
.phinc ( phinc_III )
);
always @(*) begin : calcpow2
case( pow2ind_IV )
3'd0: pow2 = 5'd16;
3'd1: pow2 = 5'd17;
3'd2: pow2 = 5'd19;
3'd3: pow2 = 5'd20;
3'd4: pow2 = 5'd22;
3'd5: pow2 = 5'd24;
3'd6: pow2 = 5'd26;
3'd7: pow2 = 5'd29;
endcase
end
reg [5:0] dt1_limit, dt1_unlimited;
reg [4:0] dt1_limited_IV;
always @(*) begin : dt1_limit_mux
case( dt1_IV[1:0] )
default: dt1_limit = 6'd8;
2'd1: dt1_limit = 6'd8;
2'd2: dt1_limit = 6'd16;
2'd3: dt1_limit = 6'd22;
endcase
case( dt1_kf_IV )
3'd0: dt1_unlimited = { 5'd0, pow2[4] }; // <2
3'd1: dt1_unlimited = { 4'd0, pow2[4:3] }; // <4
3'd2: dt1_unlimited = { 3'd0, pow2[4:2] }; // <8
3'd3: dt1_unlimited = { 2'd0, pow2[4:1] };
3'd4: dt1_unlimited = { 1'd0, pow2[4:0] };
3'd5: dt1_unlimited = { pow2[4:0], 1'd0 };
default:dt1_unlimited = 6'd0;
endcase
dt1_limited_IV = dt1_unlimited > dt1_limit ?
dt1_limit[4:0] : dt1_unlimited[4:0];
end
reg signed [8:0] mod_I;
always @(*) begin
case( pms_I ) // comprobar en silicio
3'd0: mod_I = 9'd0;
3'd1: mod_I = { 7'd0, pm[6:5] };
3'd2: mod_I = { 6'd0, pm[6:4] };
3'd3: mod_I = { 5'd0, pm[6:3] };
3'd4: mod_I = { 4'd0, pm[6:2] };
3'd5: mod_I = { 3'd0, pm[6:1] };
3'd6: mod_I = { 1'd0, pm[6:0], 1'b0 };
3'd7: mod_I = { pm[6:0], 2'b0 };
endcase
end
reg [3:0] octave_III;
wire [12:0] keycode_I;
jt51_pm u_pm(
// Channel frequency
.kc_I ( kc_I ),
.kf_I ( kf_I ),
.add ( ~pm[7] ),
.mod_I ( mod_I ),
.kcex ( keycode_I )
);
// limit value at which we add +64 to the keycode
// I assume this is to avoid the note==3 violation somehow
parameter dt2_lim2 = 8'd11 + 8'd64;
parameter dt2_lim3 = 8'd31 + 8'd64;
// I
always @(posedge clk) if(cen) begin : phase_calculation
case ( dt2_I )
2'd0: keycode_II <= { 1'b0, keycode_I } +
(keycode_I[7:6]==2'd3 ? 14'd64:14'd0);
2'd1: keycode_II <= { 1'b0, keycode_I } + 14'd512 +
(keycode_I[7:6]==2'd3 ? 14'd64:14'd0);
2'd2: keycode_II <= { 1'b0, keycode_I } + 14'd628 +
(keycode_I[7:0]>dt2_lim2 ? 14'd64:14'd0);
2'd3: keycode_II <= { 1'b0, keycode_I } + 14'd800 +
(keycode_I[7:0]>dt2_lim3 ? 14'd64:14'd0);
endcase
end
// II
always @(posedge clk) if(cen) begin
phinc_addr_III <= keycode_II[9:0];
octave_III <= keycode_II[13:10];
keycode_III <= keycode_II[12:8];
case( dt1_II[1:0] )
2'd1: dt1_kf_III <= keycode_II[13:8] - (6'b1<<2);
2'd2: dt1_kf_III <= keycode_II[13:8] + (6'b1<<2);
2'd3: dt1_kf_III <= keycode_II[13:8] + (6'b1<<3);
default:dt1_kf_III <= keycode_II[13:8];
endcase
dt1_III <= dt1_II;
end
// III
always @(posedge clk) if(cen) begin
case( octave_III )
4'd0: phase_base_IV <= { 8'd0, phinc_III[11:2] };
4'd1: phase_base_IV <= { 7'd0, phinc_III[11:1] };
4'd2: phase_base_IV <= { 6'd0, phinc_III[11:0] };
4'd3: phase_base_IV <= { 5'd0, phinc_III[11:0], 1'b0 };
4'd4: phase_base_IV <= { 4'd0, phinc_III[11:0], 2'b0 };
4'd5: phase_base_IV <= { 3'd0, phinc_III[11:0], 3'b0 };
4'd6: phase_base_IV <= { 2'd0, phinc_III[11:0], 4'b0 };
4'd7: phase_base_IV <= { 1'd0, phinc_III[11:0], 5'b0 };
4'd8: phase_base_IV <= { phinc_III[11:0], 6'b0 };
default:phase_base_IV <= 18'd0;
endcase
pow2ind_IV <= dt1_kf_III[2:0];
dt1_IV <= dt1_III;
dt1_kf_IV <= dt1_kf_III[5:3];
end
// IV LIMIT_BASE
always @(posedge clk) if(cen) begin
if( phase_base_IV > 18'd82976 )
phase_base_V <= 18'd82976;
else
phase_base_V <= phase_base_IV;
dt1_offset_V <= dt1_limited_IV;
dt1_V <= dt1_IV;
end
// V APPLY_DT1
always @(posedge clk) if(cen) begin
if( dt1_V[1:0]==2'd0 )
phase_base_VI <= {2'b0, phase_base_V};
else begin
if( !dt1_V[2] )
phase_base_VI <= {2'b0, phase_base_V} + { 15'd0, dt1_offset_V };
else
phase_base_VI <= {2'b0, phase_base_V} - { 15'd0, dt1_offset_V };
end
end
// VI APPLY_MUL
always @(posedge clk) if(cen) begin
if( mul_VI==4'd0 )
phase_step_VII <= { 1'b0, phase_base_VI[19:1] };
else
phase_step_VII <= phase_base_VI * mul_VI;
end
// VII have same number of stages as jt51_envelope
always @(posedge clk, posedge rst) begin
if( rst )
ph_VIII <= 20'd0;
else if(cen) begin
ph_VIII <= pg_rst_VII ? 20'd0 : ph_VII + phase_step_VII;
`ifdef DISPLAY_STEP
$display( "%d", phase_step_VII );
`endif
end
end
// VIII
reg [19:0] ph_IX;
always @(posedge clk, posedge rst) begin
if( rst )
ph_IX <= 20'd0;
else if(cen) begin
ph_IX <= ph_VIII[19:0];
end
end
// IX
reg [19:0] ph_X;
assign pg_phase_X = ph_X[19:10];
always @(posedge clk, posedge rst) begin
if( rst ) begin
ph_X <= 20'd0;
end else if(cen) begin
ph_X <= ph_IX;
end
end
jt51_sh #( .width(20), .stages(32-3) ) u_phsh(
.rst ( rst ),
.clk ( clk ),
.cen ( cen ),
.din ( ph_X ),
.drop ( ph_VII )
);
jt51_sh #( .width(1), .stages(4) ) u_pgrstsh(
.rst ( rst ),
.clk ( clk ),
.cen ( cen ),
.din ( pg_rst_III),
.drop ( pg_rst_VII)
);
`ifndef JT51_NODEBUG
`ifdef SIMULATION
/* verilator lint_off PINMISSING */
wire [4:0] cnt;
sep32_cnt u_sep32_cnt (.clk(clk), .cen(cen), .zero(zero), .cnt(cnt));
// wire zero_VIII;
//
// jt51_sh #(.width(1),.stages(7)) u_sep_aux(
// .clk ( clk ),
// .din ( zero ),
// .drop ( zero_VIII )
// );
//
// sep32 #(.width(1),.stg(8)) sep_ref(
// .clk ( clk ),
// .cen(cen),
// .mixed ( zero_VIII ),
// .cnt ( cnt )
// );
sep32 #(.width(10),.stg(10)) sep_ph(
.clk ( clk ),
.cen(cen),
.mixed ( pg_phase_X ),
.cnt ( cnt )
);
/* verilator lint_on PINMISSING */
`endif
`endif
endmodule