/* 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 . Author: Jose Tejada Gomez. Twitter: @topapate Version: 1.0 Date: 14-2-2016 Based on information posted by Nemesis on: http://gendev.spritesmind.net/forum/viewtopic.php?t=386&postdays=0&postorder=asc&start=167 Based on jt51_phasegen.v, from JT51 */ `timescale 1ns / 1ps /* tab size 4 */ module jt12_pg( input clk, input rst, // Channel frequency input [10:0] fnum_I, input [ 2:0] block_I, // Operator multiplying input [ 3:0] mul_V, // Operator detuning input [ 2:0] dt1_II, // same as JT51's DT1 // phase modulation from LFO //input [ 7:0] pm, //input [ 2:0] pms, // phase operation input pg_rst_III, input zero, input pg_stop, output reg [ 4:0] keycode_III, output reg [ 9:0] phase_VIII ); /* 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 jt12_pm u_pm( // Channel frequency .kc(kc), .kf(kf), .add(~pm[7]), .mod(mod), .kcex(keycode_I) ); */ wire pg_rst_VI; ////////////////////////////////////////////////// // I reg [4:0] keycode_II; reg [16:0] phinc_II; always @(posedge clk) begin : phase_calculation_I case ( block_I ) 3'd0: phinc_II <= { 7'd0, fnum_I[10:1] }; 3'd1: phinc_II <= { 6'd0, fnum_I }; 3'd2: phinc_II <= { 5'd0, fnum_I, 1'd0 }; 3'd3: phinc_II <= { 4'd0, fnum_I, 2'd0 }; 3'd4: phinc_II <= { 3'd0, fnum_I, 3'd0 }; 3'd5: phinc_II <= { 2'd0, fnum_I, 4'd0 }; 3'd6: phinc_II <= { 1'd0, fnum_I, 5'd0 }; 3'd7: phinc_II <= { fnum_I, 6'd0 }; endcase keycode_II <= { block_I, fnum_I[10], fnum_I[10] ? (|fnum_I[9:7]) : (&fnum_I[9:7])}; end ////////////////////////////////////////////////// // II reg [ 5:0] dt1_kf_III; reg [16:0] phinc_III; reg [ 2:0] dt1_III; always @(posedge clk) begin : phase_calculation_II case( dt1_II[1:0] ) 2'd1: dt1_kf_III <= { 1'b0, keycode_II } - 6'd4; 2'd2: dt1_kf_III <= { 1'b0, keycode_II } + 6'd4; 2'd3: dt1_kf_III <= { 1'b0, keycode_II } + 6'd8; default:dt1_kf_III <= { 1'b0, keycode_II }; endcase dt1_III <= dt1_II; phinc_III <= phinc_II; keycode_III <= keycode_II; end ////////////////////////////////////////////////// // III reg [16:0] phinc_IV; reg [ 4:0] pow2; reg [ 2:0] dt1_IV; always @(*) begin : calcpow2 case( dt1_kf_III[2:0] ) 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_unlimited; reg [4:0] dt1_limit, dt1_offset_IV; always @(*) begin : dt1_limit_mux case( dt1_III[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_III[5:3] ) 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 end always @(posedge clk) begin : phase_calculation_III dt1_offset_IV <= dt1_unlimited > dt1_limit ? dt1_limit : dt1_unlimited[4:0]; dt1_IV <= dt1_III; phinc_IV <= phinc_III; end ////////////////////////////////////////////////// // IV reg [16:0] phinc_V; always @(posedge clk) begin : phase_calculation_IV if( dt1_IV[1:0]==2'd0 ) phinc_V <= phinc_IV; else begin if( !dt1_IV[2] ) phinc_V <= phinc_IV + dt1_offset_IV; else phinc_V <= phinc_IV - dt1_offset_IV; end end ////////////////////////////////////////////////// // V APPLY_MUL reg [16:0] phinc_VI; always @(posedge clk) begin : phase_calculation_V if( mul_V==4'd0 ) phinc_VI <= { 1'b0, phinc_V[16:1] }; else phinc_VI <= phinc_V * mul_V; end ////////////////////////////////////////////////// // VI add phinc to the phase wire keyon_VI; wire [19:0] phase_drop; reg [19:0] phase_in; reg [ 9:0] phase_VII; always @(*) phase_in <= pg_rst_VI ? 20'd0 : ( pg_stop ? phase_drop : phase_drop + phinc_VI); always @(posedge clk) begin : phase_calculation_VI phase_VII <= phase_in[19:10]; end ////////////////////////////////////////////////// // VIII padding always @(posedge clk) phase_VIII <= phase_VII; jt12_sh #( .width(20), .stages(24) ) u_phsh( .clk ( clk ), // .rst ( rst ), .din ( phase_in ), .drop ( phase_drop) ); jt12_sh #( .width(1), .stages(3) ) u_rstsh( .clk ( clk ), .din ( pg_rst_III), .drop ( pg_rst_VI ) ); `ifdef SIMULATION reg [4:0] sep24_cnt; wire [9:0] pg_ch0s1, pg_ch1s1, pg_ch2s1, pg_ch3s1, pg_ch4s1, pg_ch5s1, pg_ch0s2, pg_ch1s2, pg_ch2s2, pg_ch3s2, pg_ch4s2, pg_ch5s2, pg_ch0s3, pg_ch1s3, pg_ch2s3, pg_ch3s3, pg_ch4s3, pg_ch5s3, pg_ch0s4, pg_ch1s4, pg_ch2s4, pg_ch3s4, pg_ch4s4, pg_ch5s4; always @(posedge clk) sep24_cnt <= !zero ? sep24_cnt+1'b1 : 5'd0; sep24 #( .width(10), .pos0(18)) stsep ( .clk ( clk ), .mixed ( phase_VIII), .mask ( 0 ), .cnt ( sep24_cnt ), .ch0s1 (pg_ch0s1), .ch1s1 (pg_ch1s1), .ch2s1 (pg_ch2s1), .ch3s1 (pg_ch3s1), .ch4s1 (pg_ch4s1), .ch5s1 (pg_ch5s1), .ch0s2 (pg_ch0s2), .ch1s2 (pg_ch1s2), .ch2s2 (pg_ch2s2), .ch3s2 (pg_ch3s2), .ch4s2 (pg_ch4s2), .ch5s2 (pg_ch5s2), .ch0s3 (pg_ch0s3), .ch1s3 (pg_ch1s3), .ch2s3 (pg_ch2s3), .ch3s3 (pg_ch3s3), .ch4s3 (pg_ch4s3), .ch5s3 (pg_ch5s3), .ch0s4 (pg_ch0s4), .ch1s4 (pg_ch1s4), .ch2s4 (pg_ch2s4), .ch3s4 (pg_ch3s4), .ch4s4 (pg_ch4s4), .ch5s4 (pg_ch5s4) ); wire [16:0] phinc_ch0s1, phinc_ch1s1, phinc_ch2s1, phinc_ch3s1, phinc_ch4s1, phinc_ch5s1, phinc_ch0s2, phinc_ch1s2, phinc_ch2s2, phinc_ch3s2, phinc_ch4s2, phinc_ch5s2, phinc_ch0s3, phinc_ch1s3, phinc_ch2s3, phinc_ch3s3, phinc_ch4s3, phinc_ch5s3, phinc_ch0s4, phinc_ch1s4, phinc_ch2s4, phinc_ch3s4, phinc_ch4s4, phinc_ch5s4; sep24 #( .width(17), .pos0(3+6)) pisep ( .clk ( clk ), .mixed ( phinc_VI), .mask ( 0 ), .cnt ( sep24_cnt ), .ch0s1 (phinc_ch0s1), .ch1s1 (phinc_ch1s1), .ch2s1 (phinc_ch2s1), .ch3s1 (phinc_ch3s1), .ch4s1 (phinc_ch4s1), .ch5s1 (phinc_ch5s1), .ch0s2 (phinc_ch0s2), .ch1s2 (phinc_ch1s2), .ch2s2 (phinc_ch2s2), .ch3s2 (phinc_ch3s2), .ch4s2 (phinc_ch4s2), .ch5s2 (phinc_ch5s2), .ch0s3 (phinc_ch0s3), .ch1s3 (phinc_ch1s3), .ch2s3 (phinc_ch2s3), .ch3s3 (phinc_ch3s3), .ch4s3 (phinc_ch4s3), .ch5s3 (phinc_ch5s3), .ch0s4 (phinc_ch0s4), .ch1s4 (phinc_ch1s4), .ch2s4 (phinc_ch2s4), .ch3s4 (phinc_ch3s4), .ch4s4 (phinc_ch4s4), .ch5s4 (phinc_ch5s4) ); wire [10:0] fnum_ch0s1, fnum_ch1s1, fnum_ch2s1, fnum_ch3s1, fnum_ch4s1, fnum_ch5s1, fnum_ch0s2, fnum_ch1s2, fnum_ch2s2, fnum_ch3s2, fnum_ch4s2, fnum_ch5s2, fnum_ch0s3, fnum_ch1s3, fnum_ch2s3, fnum_ch3s3, fnum_ch4s3, fnum_ch5s3, fnum_ch0s4, fnum_ch1s4, fnum_ch2s4, fnum_ch3s4, fnum_ch4s4, fnum_ch5s4; sep24 #( .width(11), .pos0(3+1)) fnsep ( .clk ( clk ), .mixed ( fnum_I), .mask ( 0 ), .cnt ( sep24_cnt ), .ch0s1 (fnum_ch0s1), .ch1s1 (fnum_ch1s1), .ch2s1 (fnum_ch2s1), .ch3s1 (fnum_ch3s1), .ch4s1 (fnum_ch4s1), .ch5s1 (fnum_ch5s1), .ch0s2 (fnum_ch0s2), .ch1s2 (fnum_ch1s2), .ch2s2 (fnum_ch2s2), .ch3s2 (fnum_ch3s2), .ch4s2 (fnum_ch4s2), .ch5s2 (fnum_ch5s2), .ch0s3 (fnum_ch0s3), .ch1s3 (fnum_ch1s3), .ch2s3 (fnum_ch2s3), .ch3s3 (fnum_ch3s3), .ch4s3 (fnum_ch4s3), .ch5s3 (fnum_ch5s3), .ch0s4 (fnum_ch0s4), .ch1s4 (fnum_ch1s4), .ch2s4 (fnum_ch2s4), .ch3s4 (fnum_ch3s4), .ch4s4 (fnum_ch4s4), .ch5s4 (fnum_ch5s4) ); wire pgrst_III_ch0s1, pgrst_III_ch1s1, pgrst_III_ch2s1, pgrst_III_ch3s1, pgrst_III_ch4s1, pgrst_III_ch5s1, pgrst_III_ch0s2, pgrst_III_ch1s2, pgrst_III_ch2s2, pgrst_III_ch3s2, pgrst_III_ch4s2, pgrst_III_ch5s2, pgrst_III_ch0s3, pgrst_III_ch1s3, pgrst_III_ch2s3, pgrst_III_ch3s3, pgrst_III_ch4s3, pgrst_III_ch5s3, pgrst_III_ch0s4, pgrst_III_ch1s4, pgrst_III_ch2s4, pgrst_III_ch3s4, pgrst_III_ch4s4, pgrst_III_ch5s4; sep24 #( .width(1), .pos0(23)) pgrstsep ( .clk ( clk ), .mixed ( pg_rst_III), .mask ( 0 ), .cnt ( sep24_cnt ), .ch0s1 (pgrst_III_ch0s1), .ch1s1 (pgrst_III_ch1s1), .ch2s1 (pgrst_III_ch2s1), .ch3s1 (pgrst_III_ch3s1), .ch4s1 (pgrst_III_ch4s1), .ch5s1 (pgrst_III_ch5s1), .ch0s2 (pgrst_III_ch0s2), .ch1s2 (pgrst_III_ch1s2), .ch2s2 (pgrst_III_ch2s2), .ch3s2 (pgrst_III_ch3s2), .ch4s2 (pgrst_III_ch4s2), .ch5s2 (pgrst_III_ch5s2), .ch0s3 (pgrst_III_ch0s3), .ch1s3 (pgrst_III_ch1s3), .ch2s3 (pgrst_III_ch2s3), .ch3s3 (pgrst_III_ch3s3), .ch4s3 (pgrst_III_ch4s3), .ch5s3 (pgrst_III_ch5s3), .ch0s4 (pgrst_III_ch0s4), .ch1s4 (pgrst_III_ch1s4), .ch2s4 (pgrst_III_ch2s4), .ch3s4 (pgrst_III_ch3s4), .ch4s4 (pgrst_III_ch4s4), .ch5s4 (pgrst_III_ch5s4) ); `endif endmodule