I'm working on a project for a digital design course, and I have to play musical notes using frequencies in my project. I must say I'm fairly inexperienced in verilog (have to use verilog for the project). I researched a bit regarding the topic and found (here) the following code snippet:
module music(clk, speaker);
input clk;
output speaker;
parameter clkdivider = 25000000/440/2;
reg [14:0] counter;
always @(posedge clk) if(counter==0) counter <= clkdivider-1; else counter <= counter-1;
reg speaker;
always @(posedge clk) if(counter==0) speaker <= ~speaker;
endmodule
In this code the clock is 25MHz and the frequency of the output is 440, what I want to do is change the frequency of the output according to user input, so I assume I just have to change the value the counter counts to. How can I neatly add that to the code so it should work ?
To get you started, I've set-up an environment for you. You must add you're logic to make the correct functionality (homework) especially in counter register where in you have to calculate the required frequency.
// change logic here (to add userinput)
counter <= clkdivider-1;
Since you want to change the frequency of the output according to user input,
you should add an input port to the music
module.
module music(clk, reset, userinput, valid, speaker);
input clk, valid, reset;
input [7:0] userinput;
output speaker;
userinput
is 8 bits but you can change this based from your requirements.
Take note that a valid
signal is also needed for handshaking with the other
modules.
Reset is also added to clear your music
module.
Here is your testbench
module testmusic;
reg clk;
reg [7:0] userinput;
wire speaker;
reg valid;
reg reset;
initial begin
forever begin
#1 clk = !clk;
end
end
initial begin
clk = 0;
userinput = 0;
valid = 0;
@(posedge clk);
$monitor("userinput: %0h valid: %0h speaker: %0h\n", userinput, valid, speaker);
end
task resetdut;
reset = 0;
repeat (3) begin
@(posedge clk);
end
reset <= 1;
repeat (3) begin
@(posedge clk);
end
reset <= 0;
endtask
music dut(clk, reset, userinput, valid, speaker);
initial begin
#10000; $finish;
end
// perform our testing here
initial begin
// perform reset to initialize our dut
resetdut;
testuserinput;
end
task testuserinput;
@(posedge clk);
userinput <= 8'hF; // insert user input here
valid <= 1;
@(posedge clk);
userinput <= 0;
valid <= 0;
@(posedge clk);
endtask
endmodule
Here is your RTL code that you need to fix.
module music(clk, reset, userinput, valid, speaker);
input clk, valid, reset;
input [7:0] userinput;
output speaker;
parameter clkdivider = 25000000/440/2;
reg [14:0] counter;
reg [7:0] reginput;
always @(posedge clk) begin
if (reset) begin
counter <= 0;
end
else begin
if(counter==0) begin
// change logic here (to add userinput)
counter <= clkdivider-1;
end
else begin
counter <= counter-1;
end
end
end
reg speaker;
always @(posedge clk) begin
if (reset) begin
speaker <= 0;
end
else begin
if(counter==0) begin
speaker <= ~speaker;
end
end
end
// handshake
always @(posedge clk) begin
if (reset) begin
reginput <= 0;
end
else begin
if (valid) begin
reginput <= userinput;
end
end
end
endmodule
You may want to compile the code here http://www.edaplayground.com/x/PR2