【FPGA & Verilog】手把手教你实现一个DDS信号发生器

信号发⽣器的设计与实现

1.输出波形:⽅波(占空⽐50%)、锯⻮波、三⻆波、脉冲信号(占空⽐连续可调)、正弦波、任意波等

2.输出频率:100KHz

3.波形选择:使⽤拨码开关选择

思路:

      使用FPGA搭建信号发生器DDS,重点是制作能够提前下载进开发板板载ROM的数据文件,这里用到的是mif文件,里面保存了数种波形(正弦波,方波,三角波,锯齿波)的点值,这些点值是由前期采样得来的,然后编写verilog代码,实现功能选择(波形选择等),在quartus中配置所选器件的ROM,将mif文件加载进去,在代码中调用rom中的数据,然后仿真时绘制显示波形,这时显示的是离散的数字信号,可以在仿真端modsim里选择模拟信号显示。

【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第1张图片

 【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第2张图片

 

mif文件的创建:

   这里用的是matlab编程,生成正弦波,方波,三角波,锯齿波,然后利用Fs采样频率对其采样,提取其离散值保存到创建的mif文件中

   同时使用plot函数输出波形,检查

【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第3张图片

 【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第4张图片

 【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第5张图片

 【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第6张图片

【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第7张图片

 

module  dds
(
    input   wire            sys_clk     ,
    input   wire            sys_rst_n   ,
    input   wire    [3:0]   key         ,

    output  wire            dac_clk     ,
    output  wire    [7:0]   dac_data
);

wire    [3:0]   wave_sel;
assign  dac_clk = ~sys_clk;

key_ctrl    key_ctrl_inst
(
    .sys_clk     (sys_clk),
    .sys_rst_n   (sys_rst_n),
    .key         (key),

    .wave_sel    (wave_sel)
);

dds_ctrl    dds_ctrl_inst
(
    .sys_clk     (sys_clk),
    .sys_rst_n   (sys_rst_n),
    .wave_sel    (wave_sel),

    .dac_data    (dac_data)
);

endmodule

【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第8张图片

其中

dds.v是主模块,在编译前要设置为顶层文件set as the top-level-entity,里面包含了调用的模块及其对应端口赋值(连线) key_ctrl.v和dds_ctrl.v

dds_ctrl.v中包含了对ROM的初始化,这里调用了rom_wave(一会在rom中添加文件的名称要与rom_wave一致

【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第9张图片

 

在ROM中添加已经创建好的mif文件

        在IP catalog中搜索rom,选择rom port1,注意这里的ip variation file name要与程序中的一致

 【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第10张图片

 

注意 q的输出位宽和数据数要与创建的mif文件内容一致

在创建成功后可以发现quartus的file左栏出现生成的romwave.v:

仿真:

这次没有单独在modsim中添加文件仿真,因为经常报错,因此采用quartus唤起modsim仿真的方法

1.要在quartus中设置modsim的启动程序的路径,不然无法拉起仿真

 【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第11张图片

 

2.要在settings中添加仿真文件testbench,告诉modsim拿什么仿真

   【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第12张图片

 启动仿真:

【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第13张图片

 【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第14张图片

 

`timescale 1ns/1ns
module  tb_dds_ctrl();

reg         sys_clk ;
reg         sys_rst_n;
reg [3:0]   wave_sel;

wire    [7:0]   dac_data;

initial
    begin
        sys_clk = 1'b1;
        sys_rst_n   <=  1'b0;
        wave_sel    <=  4'b0000;
        #200
        sys_rst_n   <=  1'b1;
        #10000
        wave_sel    <=  4'b0001;
        #8000000;
        wave_sel    <=  4'b0010;
        #8000000;
        wave_sel    <=  4'b0100;
        #8000000;
        wave_sel    <=  4'b1000;
        #8000000;
        wave_sel    <=  4'b0000;
    end

always #10 sys_clk = ~sys_clk;


dds_ctrl    dds_ctrl_inst
(
    .sys_clk     (sys_clk),
    .sys_rst_n   (sys_rst_n),
    .wave_sel    (wave_sel),

    .dac_data    (dac_data)
);

endmodule

延迟800000000个时间单位后,进行wave切换

波形设置为模拟:【FPGA & Verilog】手把手教你实现一个DDS信号发生器_第15张图片

 大功告成!

可私信获取整个项目Project文件

你可能感兴趣的:(FPGA学习记录,fpga开发)