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

Subversion Repositories jt51

[/] [jt51/] [trunk/] [jt51/] [jt51_phasegen.v] - Rev 2

Compare with Previous | Blame | View Log

/*  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
 
/*
 
	tab size 4
 
*/
 
module jt51_phasegen(
	input			 	clk,
	// Channel frequency
	input		[6:0]	kc,
	input		[5:0]	kf,
	// Operator multiplying
	input		[3:0]	mul,
	// Operator detuning
	input		[2:0]	dt1,
	input		[1:0]	dt2,
	// phase modulation from LFO
	input		[7:0]   pm,
	input		[2:0]   pms,
	// phase operation
	input				keyon,
	output  reg [ 4:0]  keycode_III,
	output		[19:0]	phase_now
);
 
wire [19:0]	phase_drop;
 
reg [19:0]	phase_base_VI, phase_step, phase_step_VII;
reg [17:0]	phase_base_IV, phase_base_V;
wire keyon_VII;
assign	phase_now = keyon_VII ? 20'd0 : phase_drop + phase_step;
 
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;
 
wire [3:0]	mul_V;
reg [2:0]	dt1_II, 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 <= 5'd8;
		2'd1: dt1_limit <= 5'd8;
		2'd2: dt1_limit <= 5'd16;
		2'd3: dt1_limit <= 5'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 : dt1_unlimited[4:0]; 
end
 
reg signed [8:0] mod;
 
always @(*) begin
	case( pms ) // comprobar en silicio
		3'd0: mod <= 9'd0;
		3'd1: mod <= { 7'd0, pm[6:5] };
		3'd2: mod <= { 6'd0, pm[6:4] };
		3'd3: mod <= { 5'd0, pm[6:3] };
		3'd4: mod <= { 4'd0, pm[6:2] };
		3'd5: mod <= { 3'd0, pm[6:1] };
		3'd6: mod <= { 1'd0, pm[6:0], 1'b0 };
		3'd7: mod <= {	     pm[6:0], 2'b0 };
	endcase 	
end
 
 
reg [3:0]	octave_III;
 
wire [12:0] keycode_I;
 
jt51_pm u_pm(
	// Channel frequency
	.kc(kc),
	.kf(kf),
    .add(~pm[7]),
	.mod(mod),
	.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;
 
always @(posedge clk) begin : phase_calculation
	// I
	case ( dt2 )
		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
	dt1_II <= dt1;
	// II
	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;
	// III		
	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];
	// IV LIMIT_BASE
	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;
	// V APPLY_DT1
	if( dt1_V[1:0]==2'd0 )
		phase_base_VI	<=	phase_base_V;
	else begin
		if( !dt1_V[2] )
			phase_base_VI	<=	phase_base_V + dt1_offset_V;
		else
			phase_base_VI	<=	phase_base_V - dt1_offset_V;
	end
	// VI APPLY_MUL
	if( mul_V==4'd0 )
		phase_step_VII	<= { 1'b0, phase_base_VI[19:1] };
	else
		phase_step_VII	<= phase_base_VI * mul_V;
	// VII have same number of stages as jt51_envelope
	phase_step	<= phase_step_VII;	
		`ifdef DISPLAY_STEP
				$display( "%d", phase_step );
		`endif 
end
 
jt51_sh #( .width(4), .stages(5) ) u_mulsh(
	.clk	( clk	),
	.din	( mul ),
	.drop	( mul_V )
);
 
jt51_sh #( .width(20), .stages(32) ) u_phsh(
	.clk	( clk	),
	.din	( phase_now ),
	.drop	( phase_drop)
);
 
jt51_sh #( .width(1), .stages(7) ) u_kosh(
	.clk	( clk	),
	.din	( keyon ),
	.drop	( keyon_VII)
);
 
endmodule
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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