【fpga4fun】Music box

[fpga4fun] Music box

还没整完。

因为在学校收了一块野火征途mini FPGA开发板,在看的是配套的视频教程。群里学长推荐我做一做 fpga4fun 上的东西,那就整一整 ~

简介

这个项目是用 FPGA 驱动喇叭发出声音和音乐。

硬件连接为 FPGA 开发板,一个喇叭,一个 1kΩ 电阻。

Music box 1 -Simple beep

计数与频率

一个16位的计数器,范围位 0 ~ 65535 共65536个值,如果板子的主频为 25M ,如果在上升沿计数(时钟是个方波),那么这个16位计数器最高位对应的频率便为 $25\times10^6\div65536=381Hz$ (就是加到对应那一位变化之后算一次)

以此类推第15位为 $25\times10^6\div32768=762Hz$ , 第14位为 $25\times10^6\div16384=1525Hz$ …… 第2位为$25\times10^6\div4=6.25\times10^6Hz$ , 第1位为$25\times10^6\div2=15.5\times10^6Hz$

产生 A 的声音

A 的频率为 440Hz

以 25M 主频为例,产生440Hz可以先使用16位计数器,将 25M 分为 65536 份,此时计算出产生 440Hz 只需要计数到 56818 即可。

reg [15:0] counter;
always @(posedge clk)
    if(counter==56817)
        counter < = 0;
	else 
        counter < = counter+1;
assign speaker = counter[15];

但是这样的话,占空比就不是 50% 了,$b’1000\ 0000\ 0000\ 0000=d’32768$ ,所以低电平为 0 ~ 32767,高电平为 32768 ~ 56818,占空比为42%

所以可以折中一下,然后每次翻转 speaker 的电平值 ,而且折中之后可以省一位计数器的值~

reg [14:0] counter;
always @(posedge clk)
    if(counter==28408)
        counter< =0;
	else
        counter < = counter+1;

reg speaker;
always @(posedge clk)
    if(counter==28408)
        speaker < = ~speaker;

实践

因为征途mini的主频为50M,所以用17位可以产生的时钟为 $(2\times25\times10^6)\div(2\times65536)=381Hz$

要产生440Hz,计数到 $56818\times2=113636$ 即可。

使用翻转的方式,使用16位计数器,折中计数至 56818,同时加上了复位信号

主程序代码:

// music.v
module music (
    input       wire    clk,
    input       wire    rst,
    output      reg     speaker
);

reg [15:0]  counter;

always @(posedge clk or negedge rst)
    if(rst == 1'b0)
        counter < = 16'b0;
    else if(counter == 16'd56817)
        counter < = 16'b0;
    else
        counter < = counter + 1'b1;

always @(posedge clk or negedge rst)
    if(rst == 1'b0)
        speaker < = 1'b0;
    else if(counter == 16'd56817 )
        speaker < = ~speaker;
    else
        speaker < = speaker;

endmodule

仿真验证,Testbench 代码

// tb_music.v
`timescale  1ns/1ns
module  tb_music();

reg     clk;
reg     rst;
wire    speaker;

initial begin
    clk  = 1'b0;
    rst < = 1'b0;
    #20
    rst < = 1'b1;
end

always #10 clk = ~clk;

music music_inst
(
    .clk (clk), 
    .rst (rst),

    .speaker (speaker) 
);

endmodule

仿真结果

0

占空比 $4545450-3409090=1136360$ $3409090-2272730=1136360$ ,可以看出占空比确实为50%

频率 $\frac{1}{4545450-2272730}\times10^9=440Hz$

)因为我莫得喇叭,就先不上板子了……


剩下的等我学完……