lcytms
发表于 2016-11-21 17:23:32
IP核管理界面p7。
选中最后两行rom_inst.v和rom_bb.v。
点击Finish,完成IP核管理界面的设置,总计7个设置页面。
lcytms
发表于 2016-11-21 17:24:32
这时检查工程导航一栏,发现Files一项中已经自动生成对应的IP核文件rom.qip。
打开下一级的rom.v,可以看到其封装代码。
lcytms
发表于 2016-11-21 17:25:40
打开已经生成的rom_inst.v文件。
rom rom_inst (
.address ( address_sig ),
.clock ( clock_sig ),
.q ( q_sig )
);
lcytms
发表于 2016-11-21 17:29:11
将rom_inst.v代码拷贝粘贴到dds.v模块中,修改实例化的信号名。
新建control模块,编写框架代码。
在dds.v模块中放入control模块,对其进行实例化操作。
编写dds.v模块如下。
module dds (clk, rst_n, num);
input clk, rst_n;
output num;
wire addr;
control control_inst (
.clk(clk),
.rst_n(rst_n),
.addr(addr)
);
rom rom_inst (
.address ( addr ),
.clock ( clk ),
.q ( num )
);
endmodule
lcytms
发表于 2016-11-21 17:56:50
本帖最后由 lcytms 于 2016-11-21 18:00 编辑
继续完成control模块。
编写control模块代码如下。
module control (clk, rst_n, addr);
input clk, rst_n;
output reg addr;
always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
addr <= 0;
else
addr <= addr + 8'd1;
end
endmodule
lcytms
发表于 2016-11-21 18:03:45
新建仿真模块Testbench。
新建dds_tb.v模块,编写代码如下。
`timescale 1ns/1ps
module dds_tb;
reg clk, rst_n;
wire num;
dds dut (.clk(clk), .rst_n(rst_n), .num(num));
initial
begin
clk = 1;
rst_n = 0;
#200.1
rst_n = 1;
#20_000 $stop;
end
always #10 clk = ~clk;
endmodule
lcytms
发表于 2016-11-21 18:05:09
仿真运行结果
设置好仿真之后,可以看到仿真结果。
将输出的数据格式(radix一项)设置成模拟的数据。
可以看到复位完成后,输出正弦波,周期为195.31 kHz,依次循环。
lcytms
发表于 2016-11-21 18:06:14
正弦波在相位为0度的时候开始出波形,是因为我们的地址是从0递增到255的,而0地址的数据恰好就是正弦波相位为0度的数据,故而初始相位为0度。
我们所使用的时钟为50 MHz,而正弦波被分成了256个点,我们来计算一下:
结果很显然,结果等于195312.5 Hz,也就是195.31 KHz。
lcytms
发表于 2016-11-21 18:08:35
本帖最后由 lcytms 于 2016-11-21 18:10 编辑
五、实验扩展
1)波形发生器(不可调频,但可以调相)
经过上一小节的分析,改变地址的初值就可以改变初始的相位,我们可以按照下面的公式来进行计算初始相位和地址初值的关系:
地址初值 = 256 * (初始相位/360度)
初始相位变成了90度,但是频率还是195.31KHz。通过改变相位控制字,就可以改变相位,达到了可调相的功能。
lcytms
发表于 2016-11-21 18:12:08
我们来修改control模块。
在control模块里面增加一个相位控制字pword。
修改control模块代码如下。
module control (clk, rst_n, addr);
input clk, rst_n;
output reg addr;
parameter pword = 0; // phase control word
always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
addr <= pword;
else
addr <= addr + 8'd1;
end
endmodule