//=============================================================================== // FPGA MOONCRESTA WAVE SOUND // // Version : 1.00 // // Copyright(c) 2004 Katsumi Degawa , All rights reserved // // Important ! // // This program is freeware for non-commercial use. // An author does no guarantee about this program. // You can use this under your own risk. // //================================================================================ module mc_sound_b( I_CLK1, I_CLK2, I_RSTn, I_SW, O_WAV_A0, O_WAV_A1, O_WAV_A2, I_WAV_D0, I_WAV_D1, I_WAV_D2, O_SDAT ); input I_CLK1; // 18MHz input I_CLK2; // 6MHz input I_RSTn; input [2:0]I_SW; output [7:0]O_SDAT; output [18:0]O_WAV_A0; output [18:0]O_WAV_A1; output [18:0]O_WAV_A2; input [7:0]I_WAV_D0; input [7:0]I_WAV_D1; input [7:0]I_WAV_D2; parameter sample_time = 1670/2; // sample time 22050Hz //parameter sample_time = 1670; // sample time 11025Hz parameter fire_cnt = 14'h3FF0; parameter hit_cnt = 16'hA830; parameter effect_cnt = 16'hBFC0; reg [9:0]sample; reg sample_pls; always@(posedge I_CLK1 or negedge I_RSTn) begin if(I_RSTn == 1'b0)begin sample <= 0; sample_pls <= 0; end else begin sample <= (sample == sample_time-1)? 0 : sample+1; sample_pls <= (sample == sample_time-1)? 1 : 0 ; end end //----------- FIRE SOUND ------------------------------------------ reg [13:0]fire_ad; reg [1:0]s0_trg_ff; reg s0_trg; reg s0_play; always@(posedge I_CLK1 or negedge I_RSTn) begin if(I_RSTn == 1'b0)begin s0_trg_ff <= 0; s0_trg <= 0; end else begin s0_trg_ff[0] <= I_SW[0]; s0_trg_ff[1] <= s0_trg_ff[0]; s0_trg <= ~s0_trg_ff[1]&s0_trg_ff[0]&~s0_play; end end always@(posedge I_CLK1 or negedge I_RSTn) begin if(I_RSTn == 1'b0) s0_play <= 0; else begin if(fire_ad <= fire_cnt-1) s0_play <= 1; else s0_play <= 0; end end always@(posedge I_CLK1 or negedge I_RSTn) begin if(I_RSTn == 1'b0) fire_ad <= fire_cnt; else begin if(s0_trg) fire_ad <= 0; else begin if(sample_pls)begin if(fire_ad <= fire_cnt) fire_ad <= fire_ad +1 ; else fire_ad <= fire_ad ; end end end end //----------- HIT SOUND ------------------------------------------ reg [15:0]hit_ad; reg [1:0]s1_trg_ff; reg s1_trg; reg s1_play; always@(posedge I_CLK1 or negedge I_RSTn) begin if(I_RSTn == 1'b0)begin s1_trg_ff <= 0; s1_trg <= 0; end else begin s1_trg_ff[0] <= I_SW[1]; s1_trg_ff[1] <= s1_trg_ff[0]; s1_trg <= ~s1_trg_ff[1]&s1_trg_ff[0]&~s1_play; end end always@(posedge I_CLK1 or negedge I_RSTn) begin if(I_RSTn == 1'b0) s1_play <= 0; else begin if(hit_ad <= hit_cnt-1) s1_play <= 1; else s1_play <= 0; end end always@(posedge I_CLK1 or negedge I_RSTn) begin if(I_RSTn == 1'b0) hit_ad <= hit_cnt; else begin if(s1_trg) hit_ad <= 0; else begin if(sample_pls)begin if(hit_ad <= hit_cnt) hit_ad <= hit_ad +1 ; else hit_ad <= hit_ad ; end end end end //----------- EFFICT SOUND --------------------------------------- reg [15:0]effect_ad; always@(posedge I_CLK1 or negedge I_RSTn) begin if(I_RSTn == 1'b0) effect_ad <= effect_cnt; else begin if(I_SW[2])begin if(sample_pls)begin if(effect_ad >= effect_cnt) effect_ad <= 0; else effect_ad <= effect_ad + 1; end end else begin effect_ad <= effect_cnt; end end end assign O_WAV_A0 = {3'h1,2'h0,fire_ad}; assign O_WAV_A1 = {3'h1,4'h4+hit_ad[15:12],hit_ad[11:0]}; assign O_WAV_A2 = {3'h2,effect_ad}; wire [7:0]W_WAV_D0 = I_WAV_D0; wire [7:0]W_WAV_D1 = I_WAV_D1; wire [7:0]W_WAV_D2 = I_WAV_D2; // sound mix wire [8:0]mix0 = W_WAV_D0 + W_WAV_D1 ; reg [8:0]mix_0; always@(posedge I_CLK1) begin if(mix0 >= 9'h17F) // POS Limiter mix_0 <= 9'h0FF; else if(mix0 <= 9'h080)// NEG Limiter mix_0 <= 9'h000; else mix_0 <= mix0 - 9'h080; end wire [8:0]mix1 = mix0[7:0] + W_WAV_D2 ; reg [8:0]mix_1; always@(posedge I_CLK1) begin if(mix1 >= 9'h17F) // POS Limiter mix_1 <= 9'h0FF; else if(mix1 <= 9'h080)// NEG Limiter mix_1 <= 9'h000; else mix_1 <= mix1 - 9'h080; end assign O_SDAT = mix_1[7:0]; endmodule