BeatrixBelle
Newbie level 1
- Joined
- Apr 13, 2013
- Messages
- 1
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,291
Hello,
I am trying to create a finite-state machine design to turn an FPGA development board into a simple programmable music box.
The system should be able to generate melodies, i.e., a sequence of notes. Notes can be selected
from a bank of 16 possible sounds: 15 notes and a pause (no sound).
The following is my code to produce a simple blip sound of a specific note:
However, now I need to enable my system to play a melopody based on a given sequence of notes. I will need to create a module which can be initialised to contain the desired sequence of notes. Upon pressure of a push button, these notes will be read by the machine and played through the speaker. Notes should be played such that each note is sounded for 0.6 seconds followed by a 0.2 second period of silence.
The following is the code I have so far. I am using two clocks, the enable function.... however I am really stuck and any help would be very much appreciated:
I am trying to create a finite-state machine design to turn an FPGA development board into a simple programmable music box.
The system should be able to generate melodies, i.e., a sequence of notes. Notes can be selected
from a bank of 16 possible sounds: 15 notes and a pause (no sound).
The following is my code to produce a simple blip sound of a specific note:
Code:
module level1(
input wire clk,
input wire [3:0]note,
input wire reset,
output reg speaker,
output reg [3:0]note_leds
);
// Binary counter, 16-bits wide
reg [15:0] counter;
initial
begin
counter =0;
end
always @(posedge clk) counter <= counter+1;
reg[15:0]frequency;
always @*
begin
case(note)
1: begin frequency = 381679; note_leds = 4'b0001; end //C1
2: begin frequency = 340136; note_leds = 4'b0010; end //D1
3: begin frequency = 303030; note_leds = 4'b0011; end //E1
4: begin frequency = 285714; note_leds = 4'b0100; end //F1
5: begin frequency = 255102; note_leds = 4'b0101; end //G1
6: begin frequency = 227272; note_leds = 4'b0110; end //A1
7: begin frequency = 202429; note_leds = 4'b0111; end //B1
8: begin frequency = 190839; note_leds = 4'b1000; end //C2
9: begin frequency = 170068; note_leds = 4'b1001; end //D2
10: begin frequency = 151515; note_leds = 4'b1010; end //E2
11: begin frequency = 143266; note_leds = 4'b1011; end //F2
12: begin frequency = 127551; note_leds = 4'b1100; end //G2
13: begin frequency = 113636; note_leds = 4'b1101; end //A2
14: begin frequency = 101214; note_leds = 4'b1110; end //B2
15: begin frequency = 95602; note_leds = 4'b1111; end //C3
default: begin frequency = 1; note_leds = 4'b0000; end //nothing
endcase
end
reg count_freq;
reg [15:0]count;
always @(posedge clk)
count_freq <= (count == frequency);
always @(posedge clk)
begin
if(count_freq | reset)
count <= 0;
else
count <= count + 1'b1;
end
// Use the highest bit of the counter (MSB) to drive the speaker
always @(posedge clk)
if(reset)
speaker <= 0;
else if(count_freq) speaker <= speaker ^ 1'b1;
//else speaker <= speaker; //(not required in sequential logic)
endmodule
However, now I need to enable my system to play a melopody based on a given sequence of notes. I will need to create a module which can be initialised to contain the desired sequence of notes. Upon pressure of a push button, these notes will be read by the machine and played through the speaker. Notes should be played such that each note is sounded for 0.6 seconds followed by a 0.2 second period of silence.
The following is the code I have so far. I am using two clocks, the enable function.... however I am really stuck and any help would be very much appreciated:
Code:
module melody (
input wire clk,
input wire reset,
input wire enable
output reg speaker,
);
reg [17:0] counter;
reg [7:0] sequence;
reg [17:0] nte;
parameter C1 = 190839, D1 = 170068, E1 = 151515, // these are the notes that will be played
F1 = 142857, G1 = 127551, A1 = 113636,
B1 = 101214, C2 = 95419, D2 = 85034,
E2 = 75757, F2 = 71633, G2 = 63775,
A2 = 56818, B2 = 50607, C3 = 47801,
silence = 0;
initial
begin
counter =0;
end
always @(posedge clk) counter <= counter+1; //setting the counter
always @ (posedge clk)
case(sequence)//inputing the sequence of notes
1: nte = C2;
2: nte = D2;
3: nte = E2;
4: nte = C2;
5: nte = C2;
6: nte = D2;
7: nte = E2;
8: nte = C2;
9: nte = E2;
10: nte = F2;
11: nte = G2;
12: nte = silence;
13: nte = E2;
14: nte = F2;
15: nte = G2;
16: nte = silence;
17: nte = G2;
18: nte = A2;
19: nte = G2;
20: nte = F2;
21: nte = E2;
22: nte = silence;
23: nte = C2;
24: nte = silence;
25: nte = G2;
26: nte = A2;
27: nte = G2;
28: nte = F2;
29: nte = E2;
30: nte = silence;
31: nte = C2;
32: nte = silence;
33: nte = D2;
34: nte = silence;
35: nte = G1;
36: nte = silence;
37: nte = C2;
39: nte = silence;
40: nte = D2;
41: nte = silence;
42: nte = G1;
43: nte = silence;
44: nte = C2;
45: nte = silence;
default: div=silence;
endcase
reg [15:0]count;
always @(posedge clk)
speaker <= (count == frequency);
begin //this is to play the notes after eachother
if(reset)
sequence <= 0;
else
sequence <= sequence + 1'b1;
//keeps moving to the next note
always @ (posedge clk)
begin COUNTER //block using clock and enable to get each note to be played for 0.6 seconds and paused for 0.2
if (reset == 1'b1) begin
speaker <= #1 4'b0000
end
elseif (enable == 1'b1) begin
speaker <= #1 speaker + 1;
end
end
end