/*  This file is part of JT12.

	JT12 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 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

	The non SSG-EG section is basically that of JT51's jt51_envelope.v
	adapted to 6 channels, instead of the eight.

	The SSG-EG is based on the works of Nemesis, published on
	http://gendev.spritesmind.net/forum/search.php?st=0&sk=t&sd=d&sr=posts&keywords=SSG-EG&t=386&sf=msgonly&ch=-1&start=15

	This module tries to replicate exactly the original YM2612 waveforms.
	Nonetheless, the verilog code is not a replica of the original circuit
	as there is no reverse engineering description of it.

	Questions:
		-I latch the SSG enable bit on keyon. I have to do this in order to ignore the inversion bit before the keyon
		-If SSG enable is set to 0 by software before issueing a keyoff it will be ignored
		-However, the other SSG bits will have an effect if changed in the meantime between keyon and keyoff
		-Was YM2612 like that?

	*/

`timescale 1ns / 1ps

/*

	tab size 4

*/

module jt12_eg (
	`ifdef TEST_SUPPORT
	input				test_eg,
	`endif
	input			 	rst,
	input			 	clk,
	input				zero,
	input				eg_stop,
	// envelope configuration
	input		[4:0]	keycode_III,
	input		[4:0]	arate_II, // attack  rate
	input		[4:0]	rate1_II, // decay   rate
	input		[4:0]	rate2_II, // sustain rate
	input		[3:0]	rrate_II, // release rate
	input		[3:0]	d1l,   // sustain level
	input		[1:0]	ks_III,	   // key scale
	// SSG operation
	input				ssg_en_II,
	input		[2:0]	ssg_eg_II,
	// envelope operation
	input				keyon_II,
	// envelope number
	input		[6:0]	am,
	input		[6:0]	tl_VII,
	input		[1:0]	ams_VII,
	input				amsen_VII,

	output	reg	[9:0]	eg_IX,
	output	reg			pg_rst_III
);

 // eg[9:6] -> direct attenuation (divide by 2)
		// eg[5:0] -> mantisa attenuation (uses LUT)
		// 1 LSB of eg is -0.09257 dB

wire ssg_inv_II  = ssg_eg_II[2] & ssg_en_II;
wire ssg_alt_II  = ssg_eg_II[1] & ssg_en_II;
wire ssg_hold_II = ssg_eg_II[0] & ssg_en_II;

parameter ATTACK=3'd0, DECAY1=3'd1, DECAY2=3'd2, RELEASE=3'd7, HOLD=3'd3;

reg		[4:0]	d1level_II;
reg		[9:0]	eg_III, eg_IV, eg_V;
wire	[9:0]	eg_II;

reg 	step_V;
reg		sum_up;
reg 	[5:0]	rate_V;

// remember: { log_msb, pow_addr } <= log_val[11:0] + { tl, 5'd0 } + { eg, 2'd0 };

reg		[1:0]	eg_cnt_base;
reg		[14:0]	eg_cnt;

always @(posedge clk) begin : envelope_counter
	if( rst ) begin
		eg_cnt_base	<= 2'd0;
		eg_cnt		<=15'd0;
	end
	else begin
		if( zero ) begin
			// envelope counter increases every 3 output samples,
			// there is one sample every 32 clock ticks
			if( eg_cnt_base == 2'd2 ) begin
				eg_cnt 		<= eg_cnt + 1'b1;
				eg_cnt_base	<= 2'd0;
			end
			else eg_cnt_base <= eg_cnt_base + 1'b1;
		end
	end
end

wire			cnt_out; // = all_cnt_last[3*31-1:3*30];


reg  [7:0]	step_idx;
reg	 [2:0]	state_III, state_IV, state_V, state_VI, state_VII, state_VIII;
wire [2:0]	state_II;


wire	ar_off_VI;
reg		ar_off_III;

//	Register Cycle I

always @(posedge clk) begin
	if( d1l == 4'd15 )
		d1level_II <= 5'h1f; // 93dB
	else
		d1level_II <= d1l;
end

//	Register Cycle II
wire	ssg_invertion_II, ssg_invertion_VIII;
reg		ssg_invertion_III;
reg	[4:0] cfg_III;
wire	ssg_pg_rst = eg_II>=10'h200 && ssg_en_II &&
							 !( ssg_alt_II || ssg_hold_II );
wire	ssg_en_out;
wire	keyon_last_II;
reg		ssg_en_in_II;

always @(*) begin
	if( state_II==RELEASE )
		ssg_en_in_II <= 1'b0;
	else
		ssg_en_in_II <= keyon_II ? ssg_en_II : ssg_en_out;
end

wire	ar_off_II = arate_II == 5'h1f;

wire	keyon_now_II  = !keyon_last_II && keyon_II;
wire	keyoff_now_II = keyon_last_II && !keyon_II;

always @(posedge clk) begin
	// ar_off_III	<= arate_II == 5'h1f;
	// trigger release
	if( keyoff_now_II ) begin
		cfg_III <= { rrate_II, 1'b1 };
		state_III <= RELEASE;
		pg_rst_III	<= 1'b0;
		ar_off_III <= 1'b0;
	end
	else begin
		// trigger 1st decay
		if( keyon_now_II ) begin
			cfg_III <= arate_II;
			state_III <= ATTACK;
			pg_rst_III <= 1'b1;
			ar_off_III <= ar_off_II;
		end
		else begin : sel_rate
			pg_rst_III <= (eg_II==10'h3FF) ||ssg_pg_rst;
			if( (state_II==DECAY1 ||state_II==DECAY2) && ssg_en_II && eg_II >= 10'h200 ) begin
				ssg_invertion_III <= ssg_alt_II ^ ssg_invertion_II;
				if( ssg_hold_II ) begin
					cfg_III <= 5'd0;
					state_III <= HOLD; // repeats!
					ar_off_III <= 1'b0;
				end
				else begin
					cfg_III	<=	rate2_II;
					state_III <= ATTACK; // repeats!
					ar_off_III <= 1'b1;
				end
			end
			else begin
				ssg_invertion_III <= state_II==RELEASE ? 1'b0 : ssg_invertion_II;
				case ( state_II )
					ATTACK: begin
						if( eg_II==10'd0 ) begin
							state_III <= DECAY1;
							cfg_III		 <= rate1_II;
						end
						else begin
							state_III <= state_II; // attack
							cfg_III		 <= arate_II;
						end
						ar_off_III <= 1'b0;
						end
					DECAY1: begin
						if( eg_II[9:5] >= d1level_II ) begin
							cfg_III <= rate2_II;
							state_III <= DECAY2;
						end
						else begin
							cfg_III	<=	rate1_II;
							state_III <= state_II;	// decay1
						end
						ar_off_III <= 1'b0;
						end
					DECAY2:
						begin
							cfg_III	<=	rate2_II;
							state_III <= state_II;	// decay2
							ar_off_III <= 1'b0;
						end
					RELEASE: begin
							cfg_III	<=	{ rrate_II, 1'b1 };
							state_III <= state_II;	// release
							ar_off_III <= 1'b0;
						end
					HOLD: begin
							cfg_III <= 5'd0;
							state_III <= HOLD; // repeats!
							ar_off_III <= 1'b0;
						end
				endcase
			end
		end
	end

	eg_III <= eg_II;
end

///////////////////////////////////////////////////////////////////
//	Register Cycle III
reg		[6:0]	pre_rate_III;
reg		[5:0]	rate_IV;

always @(*) begin : pre_rate_calc
	if( cfg_III == 5'd0 )
		pre_rate_III <= 6'd0;
	else
		case( ks_III )
			2'd3:	pre_rate_III <= { cfg_III, 1'b0 } + keycode_III;
			2'd2:	pre_rate_III <= { cfg_III, 1'b0 } + { 1'b0, keycode_III[4:1] };
			2'd1:	pre_rate_III <= { cfg_III, 1'b0 } + { 2'b0, keycode_III[4:2] };
			2'd0:	pre_rate_III <= { cfg_III, 1'b0 } + { 3'b0, keycode_III[4:3] };
		endcase
end

always @(posedge clk) begin 
	if( rst ) begin
		state_IV <= RELEASE;
		eg_IV <= 10'h3ff;
		rate_IV <= 5'h1F;
	end
	else begin
		state_IV <= state_III;
		eg_IV <= eg_III;
		rate_IV <= pre_rate_III[6] ? 6'd63 : pre_rate_III[5:0];
	end
end
///////////////////////////////////////////////////////////////////
//	Register Cycle IV
reg		[2:0]	cnt_V;

always @(posedge clk) begin
	if( rst ) begin
		state_V	<= RELEASE;
		rate_V <= 5'h1f;
		eg_V <= 10'h3ff;
		//cnt_V<= 3'd0;
	end
	else begin
		state_V	<= state_IV;
		rate_V <= rate_IV;
		eg_V <= eg_IV;
		if( state_IV == ATTACK )
			case( rate_IV[5:2] )
				4'h0: cnt_V <= eg_cnt[13:11];
				4'h1: cnt_V <= eg_cnt[12:10];
				4'h2: cnt_V <= eg_cnt[11: 9];
				4'h3: cnt_V <= eg_cnt[10: 8];
				4'h4: cnt_V <= eg_cnt[ 9: 7];
				4'h5: cnt_V <= eg_cnt[ 8: 6];
				4'h6: cnt_V <= eg_cnt[ 7: 5];
				4'h7: cnt_V <= eg_cnt[ 6: 4];
				4'h8: cnt_V <= eg_cnt[ 5: 3];
				4'h9: cnt_V <= eg_cnt[ 4: 2];
				4'ha: cnt_V <= eg_cnt[ 3: 1];
				default: cnt_V <= eg_cnt[ 2: 0];
			endcase
		else
			case( rate_IV[5:2] )
				4'h0: cnt_V <= eg_cnt[14:12];
				4'h1: cnt_V <= eg_cnt[13:11];
				4'h2: cnt_V <= eg_cnt[12:10];
				4'h3: cnt_V <= eg_cnt[11: 9];
				4'h4: cnt_V <= eg_cnt[10: 8];
				4'h5: cnt_V <= eg_cnt[ 9: 7];
				4'h6: cnt_V <= eg_cnt[ 8: 6];
				4'h7: cnt_V <= eg_cnt[ 7: 5];
				4'h8: cnt_V <= eg_cnt[ 6: 4];
				4'h9: cnt_V <= eg_cnt[ 5: 3];
				4'ha: cnt_V <= eg_cnt[ 4: 2];
				4'hb: cnt_V <= eg_cnt[ 3: 1];
				default: cnt_V <= eg_cnt[ 2: 0];
			endcase
	end
end
//////////////////////////////////////////////////////////////
// Register Cycle V
always @(*) begin : rate_step
	if( rate_V[5:4]==2'b11 ) begin // 0 means 1x, 1 means 2x
		if( rate_V[5:2]==4'hf && state_V == ATTACK)
			step_idx <= 8'b11111111; // Maximum attack speed, rates 60&61
		else
		case( rate_V[1:0] )
			2'd0: step_idx <= 8'b00000000;
			2'd1: step_idx <= 8'b10001000; // 2
			2'd2: step_idx <= 8'b10101010; // 4
			2'd3: step_idx <= 8'b11101110; // 6
		endcase
	end
	else begin
		if( rate_V[5:2]==4'd0 && state_V != ATTACK)
			step_idx <= 8'b11111110; // limit slowest decay rate_IV
		else
		case( rate_V[1:0] )
			2'd0: step_idx <= 8'b10101010; // 4
			2'd1: step_idx <= 8'b11101010; // 5
			2'd2: step_idx <= 8'b11101110; // 6
			2'd3: step_idx <= 8'b11111110; // 7
		endcase
	end
	// a rate_IV of zero keeps the level still
	step_V <= rate_V[5:1]==5'd0 ? 1'b0 : step_idx[ cnt_V ];
end

reg	[5:1]	rate_VI;
reg [9:0]	eg_VI;
reg			step_VI;

always @(posedge clk) begin
	if( rst ) begin
		state_VI <= RELEASE;
		rate_VI <= 5'd1;
		eg_VI <= 10'h3ff;
		sum_up <= 1'b0;
		step_VI <= 1'b0;
	end
	else begin
		state_VI <= state_V;
		rate_VI <= rate_V[5:1];
		eg_VI <= eg_V;
		sum_up <= cnt_V[0] != cnt_out;
		step_VI <= step_V;
	end
end
//////////////////////////////////////////////////////////////
// Register cycle VI
reg [3:0] 	preatt_VI;
reg [5:0] 	att_VI;
wire		ssg_en_VI;
reg	[9:0]	eg_VII, eg_stopped_VII;
reg	[10:0]	egatt_VI;

always @(*) begin
	case( rate_VI[5:2] )
		4'b1100: preatt_VI <= { step_VI, ~step_VI }; // 12
		4'b1101: preatt_VI <= { step_VI, ~step_VI, 1'b0 }; // 13
		4'b1110: preatt_VI <= { step_VI, ~step_VI, 2'b0 }; // 14
		4'b1111: preatt_VI <= 4'd8;// 15
		default: preatt_VI <= { step_VI, 1'b0 };
	endcase
	att_VI <= ssg_en_VI ? { preatt_VI, 2'd0 } : { 2'd0, preatt_VI };
	egatt_VI <= att_VI + eg_VI;
	eg_stopped_VII <= eg_VI;
end

reg [8:0] ar_sum0;
reg [9:0] ar_result, ar_sum;

always @(*) begin : ar_calculation
	casex( rate_VI[5:2] )
		default: ar_sum0 <= eg_VI[9:4] + 1'd1;
		4'b1100: ar_sum0 <= eg_VI[9:4] + 1'd1;
		4'b1101: ar_sum0 <= eg_VI[9:3] + 1'd1;
		4'b111x: ar_sum0 <= eg_VI[9:2] + 1'd1;
	endcase
	if( rate_VI[5:4] == 2'b11 )
		ar_sum <= step_VI ? { ar_sum0, 1'b0 } : { 1'b0, ar_sum0 };
	else
		ar_sum <= step_VI ? { 1'b0, ar_sum0 } : 10'd0;
	ar_result <= ar_sum<eg_VI ? eg_VI-ar_sum : 10'd0;
end

always @(posedge clk) begin
	if( rst ) begin
		eg_VII <= 10'h3ff;
		state_VII <= RELEASE;
	end
	else begin
		if( ar_off_VI ) begin
			// eg_VII <= ssg_en_II ? 10'h200 : 10'd0;
			eg_VII <= 10'd0;
		end
		else
		if( state_VI == ATTACK ) begin
			if( sum_up && eg_VI != 10'd0 )
				if( rate_VI[5:1]==4'hf )
					eg_VII <= 10'd0;
				else
					eg_VII <= ar_result;
			else
				eg_VII <= eg_VI;
		end
		else begin : DECAY_SUM
			if( sum_up ) begin
				if ( egatt_VI<= 10'd1023 )
					eg_VII <= egatt_VI[9:0];
				else eg_VII <= 10'h3FF;
			end
			else eg_VII <= eg_VI;
		end
		state_VII <= state_VI;
	end
end
//////////////////////////////////////////////////////////////
// Register cycle VII
reg		[9:0]	eg_internal_VIII;
reg		[8:0]	am_final;
reg		[11:0]	sum_eg_tl;

always @(*) begin : sum_eg_and_tl
	casex( {amsen_VII, ams_VII } )
		3'b0xx,3'b100: am_final <= 9'd0;
		3'b101: am_final <= { 2'b00, am };
		3'b110: am_final <= { 1'b0, am, 1'b0};
		3'b111: am_final <= { am, 2'b0	  };
	endcase
	`ifdef TEST_SUPPORT
	if( test_eg && tl_VII!=7'd0 )
		sum_eg_tl <= 11'd0;
	else
	`endif
		sum_eg_tl <= { tl_VII,   3'd0 }
				   + eg_VII
				   + { am_final, 1'b0 };
end

always @(posedge clk) begin
	if( rst ) begin
		eg_internal_VIII <= 10'h3ff;
		state_VIII <= RELEASE;
	end
	else begin
		eg_internal_VIII <= sum_eg_tl[11:10] > 2'b0 ? {10{1'b1}} : sum_eg_tl[9:0];
		state_VIII <= state_VII;
	end
end

//////////////////////////////////////////////////////////////
// Register cycle VIII
wire ssg_inv_VIII, ssg_en_VIII;
//reg	[9:0] eg_IX;
always @(posedge clk) begin
	if( rst )
		eg_IX <= 10'h3ff;
	else begin
		if( ssg_en_VIII && (ssg_invertion_VIII ^^ ssg_inv_VIII) )
			eg_IX <= eg_internal_VIII>=10'h200 ? 10'h0 : (10'h200 - eg_internal_VIII);
		else
			eg_IX <= eg_internal_VIII;
	end
end

//////////////////////////////////////////////////////////////
// Register cycle IX-XII
/*
jt12_sh #(.width(10), .stages(12-8)) u_padding(
	.clk	( clk		),
	.din	( eg_IX		),
	.drop	( eg_XII	)
);
*/
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
// Shift registers

jt12_sh24 #( .width(1) ) u_ssgen(
	.clk	( clk		),
	.din	( ssg_en_in_II ),
	.st4	( ssg_en_VI	  ),
	.st6	( ssg_en_VIII ), // note that din is *_II
	.st24	( ssg_en_out  )
);

jt12_sh #( .width(1), .stages(6) ) u_ssgattsh(
	.clk	( clk		),
	.din	( ssg_inv_II	),
	.drop	( ssg_inv_VIII	)
);

jt12_sh #( .width(1), .stages(3) ) u_aroffsh(
	.clk	( clk		),
	.din	( ar_off_III),
	.drop	( ar_off_VI	)
);

jt12_sh #( .width(1), .stages(5) ) u_ssg1sh(
	.clk	( clk		),
	.din	( ssg_invertion_III	),
	.drop	( ssg_invertion_VIII	)
);


jt12_sh #( .width(1), .stages(18) ) u_ssg2sh(
	.clk	( clk		),
	.din	( ssg_invertion_VIII	),
	.drop	( ssg_invertion_II	)
);


/* Had 27 stages in JT51, for 32 operators
   Has 19 stages here, for 24 operators
   plus 1 extra stage. 20 stages does not work well.
   Maybe JT51 should be 26!! */
jt12_sh/*_rst*/ #( .width(10), .stages(19)/*, .rstval(1'b1)*/ ) u_egsh(
	.clk	( clk		),
//	.rst	( rst		),
	.din	( eg_stop ? eg_stopped_VII : eg_VII		),
	.drop	( eg_II	)
);

/* Had 32 stages in JT51, for 32 operators
   Has 24 stages here, for 24 operators */
jt12_sh/*_rst*/ #( .width(1), .stages(24) ) u_cntsh(
	.clk	( clk		),
//	.rst	( rst		),	
	.din	( cnt_V[0]	),
	.drop	( cnt_out	)
);

jt12_sh_rst #( .width(1), .stages(24) ) u_konsh(
	.clk	( clk		),
//	.rst	( rst		),	
	.din	( keyon_II	),
	.drop	( keyon_last_II	)
);

/* Had 31 stages in JT51, for 32 operators
   Has 23 stages here, for 24 operators */
jt12_sh/*_rst*/ #( .width(3), .stages(18)/*, .rstval(1'b1)*/ ) u_statesh(
	.clk	( clk		),
//	.rst	( rst		),
	.din	( state_VIII),
	.drop	( state_II	)
);

`ifdef SIMULATION
reg [4:0] sep24_cnt;

wire [2:0] state_ch0s1, state_ch1s1, state_ch2s1, state_ch3s1,
		 state_ch4s1, state_ch5s1, state_ch0s2, state_ch1s2,
		 state_ch2s2, state_ch3s2, state_ch4s2, state_ch5s2,
		 state_ch0s3, state_ch1s3, state_ch2s3, state_ch3s3,
		 state_ch4s3, state_ch5s3, state_ch0s4, state_ch1s4,
		 state_ch2s4, state_ch3s4, state_ch4s4, state_ch5s4;


always @(posedge clk)
	sep24_cnt <= !zero ? sep24_cnt+1'b1 : 5'd0;

sep24 #( .width(3), .pos0(0) ) stsep
(
	.clk	( clk		),
	.mixed	( state_II	),
	.mask	( 0			),
	.cnt	( sep24_cnt	),

	.ch0s1 (state_ch0s1),
	.ch1s1 (state_ch1s1),
	.ch2s1 (state_ch2s1),
	.ch3s1 (state_ch3s1),
	.ch4s1 (state_ch4s1),
	.ch5s1 (state_ch5s1),

	.ch0s2 (state_ch0s2),
	.ch1s2 (state_ch1s2),
	.ch2s2 (state_ch2s2),
	.ch3s2 (state_ch3s2),
	.ch4s2 (state_ch4s2),
	.ch5s2 (state_ch5s2),

	.ch0s3 (state_ch0s3),
	.ch1s3 (state_ch1s3),
	.ch2s3 (state_ch2s3),
	.ch3s3 (state_ch3s3),
	.ch4s3 (state_ch4s3),
	.ch5s3 (state_ch5s3),

	.ch0s4 (state_ch0s4),
	.ch1s4 (state_ch1s4),
	.ch2s4 (state_ch2s4),
	.ch3s4 (state_ch3s4),
	.ch4s4 (state_ch4s4),
	.ch5s4 (state_ch5s4)
);

`endif

endmodule

