DDS电路核心RTL
输入:时钟,归零RST,ROM地址的增量FWIN[31..0],读取FWIN的使能FWEN
- 本设计加入了额外的D触发器流水线以减小ROM的I/O延迟带来的影响,可以从RTL看出从左开始第一个第三个第四个都是#1添加的D触发器
- u_sinrom模块由顶层Verilog文件嵌套使用产生,DDS_CORE_ROM.v文件在同一文件夹下,引用时使用u_sinrom的名字,接口的名字需要做对应,这与之前学习的VHDL类似
matlab生成波表ROM
由m文件生成,存储位置在如图所示,每次执行会覆盖DDS_CORE_ROM.v文件
DDS代码
module dds_core_sin(
CLK , // clock, posedge valid
RST , // reset, high level reset
FWEN , // frequency word update enable, high level enable
FWIN , // input frequency word
CLKOUT, // output clock
SINOUT); // sine signal output, 2's complement format
input CLK;
input RST;
input FWEN;
input [32-1:0] FWIN;
output[12-1:0] SINOUT;
output CLKOUT;
parameter FW_WL = 32; // frequency word word length in bit
parameter RA_WL = 10; // rom address word length in bit
parameter RD_WL = 12; // rom data word word length in bit
reg [FW_WL -1:0] fwin_R; // freq word DFF
reg [FW_WL -1:0] acc_R; // phase ACC DFF
reg [RA_WL -1:0] addr_R; // rom address DFF
reg [RD_WL -1:0] sinout_R; // sin wave output DFF
wire [RD_WL -1:0] romout_W; // rom data output wire
always @ (posedge CLK or posedge RST) begin
if(RST) begin
fwin_R <= 0;
acc_R <= 0;
addr_R <= 0;
sinout_R <= 0;
end
else begin
// update fwin_R DFF
if(FWEN)
fwin_R <= #1 FWIN;
else
fwin_R <= #1 fwin_R;
// update acc_R
acc_R <= #1 fwin_R + acc_R;
// update addr_R, the acc_R high RA_WL is rom address
addr_R <= acc_R[FW_WL-1:FW_WL-1-(RA_WL-1)];
// update output DFF
sinout_R <= #1 romout_W;
end
end
DDS_CORE_ROM u_sinrom(
.CLK (CLK ), // clock
.RA (addr_R ), // read address
.RD (romout_W )); // read data
assign SINOUT = sinout_R;
assign CLKOUT = CLK;
endmodule // module dds_core
-
DDS_CORE_ROM u_sinrom( .CLK (CLK ), // clock .RA (addr_R ), // read address .RD (romout_W )); // read data
波形仿真
把sinout_R设置成波形,点击Analog Waveform后可以设置波形是连续还是离散的,信号的高度。我设置高度为10.
可以看到波形是不平整的,这是因为不同D触发器的输出不够同步。
DDS开发板测试平台
- 使用按键来控制频率字的改变
- 设定频率的UP和DOWN按键,让DDS轮流输出1MHz,2MHz,....10MHz的时域波形
RTL视图
- powerup_reset模块:做50MHz下的计数,计数到最大值5_000_000输出RSTOUT
- button_in_out模块通过复位按键判断复位的状态和UP、DOWN的状态
- generate_freq_word模块:定义参数VAL_FREQ_BASE为50MHz下每1MHz对应的地址的增量值,VAL_FREQ_MAX为VAL_FREQ_BASE的10倍,即10MHz对应的值。
真值表如下
RST | BUTTON | 执行情况 |
1 | 无 | 中间使能清零 |
0 | UP键按下 | butup_enR<=1 |
DOWN键按下 | downup_enR<=1 |
RST | butup_enR | butdown_enR | FQWD | 执行 | 执行 |
FQWD | FWEN | ||||
1 | 无 | 无 | 无 | 赋值VAL_FREQ_BASE | 赋值1 |
0 | 0 | 1 | VAL_FREQ_BASE | 赋值VAL_FREQ_MAX | 无 |
不等于VAL_FREQ_MAX | +VAL_FREQ_BASE | 无 | |||
0 | 1 | 0 | VAL_FREQ_BASE | 赋值VAL_FREQ_MAX | 无 |
不等于VAL_FREQ_BASE | -VAL_FREQ_BASE | 无 |
- dds_core_sin模块是前一个文件的代码做了模块,可以做bdf的递归,或由bdf生成hdl后在新的project生成bdf
signal波形
初始波形如图,在1MHz
按一次UP键,频率为2MHz,FQWD变大
再按一次DOWN,频率和FQWD恢复之前的数值
再按一次DOWN,频率和FQWD变为最大值,频率s10MHz,波形放大后已经变形
按RST后恢复开始的数值
------------------------------------------------------------------------------------------------------------------------------
MATLAB分析
从signaltap波形图中选中sin信号,右键->创建list文件,从list文件复制出抽样点的值,在excel中粘贴,使用“分列”功能,分出抽样点的幅值。
在matlab中使用相关的函数对幅值处理得到频谱分析
从图中可以看出频谱主要集中在4.82×10^-15,其他频率的幅值都在-60dB一下
DDS的设计要点
截取了前两个波形的代码,函数的增量不同,产生的波形频率不同