galaxians
[fpga-games] / galaxian / src / mc_sound_b.v
1 //===============================================================================
2 // FPGA MOONCRESTA WAVE SOUND
3 //
4 // Version : 1.00
5 //
6 // Copyright(c) 2004 Katsumi Degawa , All rights reserved
7 //
8 // Important !
9 //
10 // This program is freeware for non-commercial use.
11 // An author does no guarantee about this program.
12 // You can use this under your own risk.
13 //
14 //================================================================================
15
16
17 module mc_sound_b(
18
19 I_CLK1,
20 I_CLK2,
21 I_RSTn,
22 I_SW,
23
24 O_WAV_A0,
25 O_WAV_A1,
26 O_WAV_A2,
27 I_WAV_D0,
28 I_WAV_D1,
29 I_WAV_D2,
30
31 O_SDAT
32
33 );
34
35 input I_CLK1; // 18MHz
36 input I_CLK2; // 6MHz
37 input I_RSTn;
38 input [2:0]I_SW;
39 output [7:0]O_SDAT;
40 output [18:0]O_WAV_A0;
41 output [18:0]O_WAV_A1;
42 output [18:0]O_WAV_A2;
43 input [7:0]I_WAV_D0;
44 input [7:0]I_WAV_D1;
45 input [7:0]I_WAV_D2;
46
47 parameter sample_time = 1670/2; // sample time 22050Hz
48 //parameter sample_time = 1670; // sample time 11025Hz
49 parameter fire_cnt = 14'h3FF0;
50 parameter hit_cnt = 16'hA830;
51 parameter effect_cnt = 16'hBFC0;
52
53 reg [9:0]sample;
54 reg sample_pls;
55
56 always@(posedge I_CLK1 or negedge I_RSTn)
57 begin
58 if(I_RSTn == 1'b0)begin
59 sample <= 0;
60 sample_pls <= 0;
61 end
62 else begin
63 sample <= (sample == sample_time-1)? 0 : sample+1;
64 sample_pls <= (sample == sample_time-1)? 1 : 0 ;
65 end
66 end
67
68 //----------- FIRE SOUND ------------------------------------------
69 reg [13:0]fire_ad;
70 reg [1:0]s0_trg_ff;
71 reg s0_trg;
72 reg s0_play;
73
74 always@(posedge I_CLK1 or negedge I_RSTn)
75 begin
76 if(I_RSTn == 1'b0)begin
77 s0_trg_ff <= 0;
78 s0_trg <= 0;
79 end
80 else begin
81 s0_trg_ff[0] <= I_SW[0];
82 s0_trg_ff[1] <= s0_trg_ff[0];
83 s0_trg <= ~s0_trg_ff[1]&s0_trg_ff[0]&~s0_play;
84 end
85 end
86
87 always@(posedge I_CLK1 or negedge I_RSTn)
88 begin
89 if(I_RSTn == 1'b0)
90 s0_play <= 0;
91 else begin
92 if(fire_ad <= fire_cnt-1)
93 s0_play <= 1;
94 else
95 s0_play <= 0;
96 end
97 end
98
99 always@(posedge I_CLK1 or negedge I_RSTn)
100 begin
101 if(I_RSTn == 1'b0)
102 fire_ad <= fire_cnt;
103 else begin
104 if(s0_trg) fire_ad <= 0;
105 else begin
106 if(sample_pls)begin
107 if(fire_ad <= fire_cnt)
108 fire_ad <= fire_ad +1 ;
109 else
110 fire_ad <= fire_ad ;
111 end
112 end
113 end
114 end
115 //----------- HIT SOUND ------------------------------------------
116 reg [15:0]hit_ad;
117 reg [1:0]s1_trg_ff;
118 reg s1_trg;
119 reg s1_play;
120
121 always@(posedge I_CLK1 or negedge I_RSTn)
122 begin
123 if(I_RSTn == 1'b0)begin
124 s1_trg_ff <= 0;
125 s1_trg <= 0;
126 end
127 else begin
128 s1_trg_ff[0] <= I_SW[1];
129 s1_trg_ff[1] <= s1_trg_ff[0];
130 s1_trg <= ~s1_trg_ff[1]&s1_trg_ff[0]&~s1_play;
131 end
132 end
133
134 always@(posedge I_CLK1 or negedge I_RSTn)
135 begin
136 if(I_RSTn == 1'b0)
137 s1_play <= 0;
138 else begin
139 if(hit_ad <= hit_cnt-1)
140 s1_play <= 1;
141 else
142 s1_play <= 0;
143 end
144 end
145
146 always@(posedge I_CLK1 or negedge I_RSTn)
147 begin
148 if(I_RSTn == 1'b0)
149 hit_ad <= hit_cnt;
150 else begin
151 if(s1_trg) hit_ad <= 0;
152 else begin
153 if(sample_pls)begin
154 if(hit_ad <= hit_cnt)
155 hit_ad <= hit_ad +1 ;
156 else
157 hit_ad <= hit_ad ;
158 end
159 end
160 end
161 end
162 //----------- EFFICT SOUND ---------------------------------------
163 reg [15:0]effect_ad;
164
165 always@(posedge I_CLK1 or negedge I_RSTn)
166 begin
167 if(I_RSTn == 1'b0)
168 effect_ad <= effect_cnt;
169 else begin
170 if(I_SW[2])begin
171 if(sample_pls)begin
172 if(effect_ad >= effect_cnt)
173 effect_ad <= 0;
174 else
175 effect_ad <= effect_ad + 1;
176 end
177 end
178 else begin
179 effect_ad <= effect_cnt;
180 end
181 end
182 end
183
184 assign O_WAV_A0 = {3'h1,2'h0,fire_ad};
185 assign O_WAV_A1 = {3'h1,4'h4+hit_ad[15:12],hit_ad[11:0]};
186 assign O_WAV_A2 = {3'h2,effect_ad};
187
188 wire [7:0]W_WAV_D0 = I_WAV_D0;
189 wire [7:0]W_WAV_D1 = I_WAV_D1;
190 wire [7:0]W_WAV_D2 = I_WAV_D2;
191
192 // sound mix
193 wire [8:0]mix0 = W_WAV_D0 + W_WAV_D1 ;
194 reg [8:0]mix_0;
195 always@(posedge I_CLK1)
196 begin
197 if(mix0 >= 9'h17F) // POS Limiter
198 mix_0 <= 9'h0FF;
199 else if(mix0 <= 9'h080)// NEG Limiter
200 mix_0 <= 9'h000;
201 else
202 mix_0 <= mix0 - 9'h080;
203 end
204
205 wire [8:0]mix1 = mix0[7:0] + W_WAV_D2 ;
206 reg [8:0]mix_1;
207 always@(posedge I_CLK1)
208 begin
209 if(mix1 >= 9'h17F) // POS Limiter
210 mix_1 <= 9'h0FF;
211 else if(mix1 <= 9'h080)// NEG Limiter
212 mix_1 <= 9'h000;
213 else
214 mix_1 <= mix1 - 9'h080;
215 end
216
217 assign O_SDAT = mix_1[7:0];
218
219
220 endmodule
Impressum, Datenschutz