用Verilog HDL语言实现基于DDS技术的余弦信号发生器,其输出位宽为 16bit。
3.2 使用MATLAB定点正、余弦波形数值借助MATLAB生成ROM中的定点正、余弦波形数值,形成.coe文件。
1.利用MATLAB计算出正、余弦波形的浮点值,并量化 16bit 的定点波形数值[2]。
x= linspace(0,6.28,1024); %在区间[0,6.28]之间等间隔地取1024个点
y1=cos(x); %计算相应的正余弦值
y2=sin(x);
%由于正余弦波形的值在[0,1]之间,需要量化成16bit,先将数值放大
y1=y1*32678;
y2=y2*32768;
%再将放大的浮点值量化,并写到存放在E盘的文本中
fid = fopen('e:/cos_coe.txt', 'wt');
fprintf(fid, '%16.0f\n', y1); %在写文件时量化成16bit
fclose(fid)
fid = fopen('e:/sin_coe.txt', 'wt');
fprintf(fid, '%16.0f\n', y2);
fclose(fid)
2.产生.coe 文件
在 e 盘根目录下,将 cos_coe.txt 和 sin_coe.txt 的后缀改成.coe,打开文件,把每一行之间的空格用文本的替换功能换成逗号“,”,并在最后一行添加一个分号“;”。最后在文件的最开始添加下面两行:
memory_initialization_radix=10;
memory_initialization_vector =
然后保存文件退出。
3.3将 coe 文件加载到BLOCKROM所生成的ROM中新建一个BLOCKRAM的 IP Core,其位置为Memories & Storage Elements/RAMs & ROMs/Block Memory Generator v4.3,在第一页选择single port rom,在第二页选择位宽为16、深度为1 024,在第三页下载.coe 文件,然后双击 finish,完成IP core 的生成。如果.coe文件生成的不对,图中用椭圆标志之处是红色的,.coe 文件错误的类型主要有数据基数不对和数据的长度不对这两类。
3.4 DDS的Verilog HDL的实现
module dds(data, we, clk, ce, reset, sine, cose);
input [31 : 0] data; //频率控制字
input we; //频率控制字写使能
input clk; //时钟
input ce; //DDS使能
input reset; //复位
output [15 : 0] sine; //正弦信号输出
output [15 : 0] cose; //余弦信号输出
reg [31 : 0] ADD_A; //正弦波产生模块的相位累加器
reg [31 : 0] ADD_B; //余弦波产生模块的相位累加器
reg [15 : 0] cose_DR; //余弦波的查找表输出
reg [15 : 0] sine_DR; //正弦波的查找表输出
wire [31 : 0] data; //频率控制字
wire [9 : 0] ROM_A;
wire [15 : 0] cose_D;
wire [15 : 0] sine_D;
assign cose = cose_DR;
assign sine = sine_DR;
assign ROM_A = ADD_B[31 : 22];
always @ (posedge clk or posedge reset)
begin
if(reset) //系统初始化时,默认的频率控制字为0
ADD_A <= 0;
else if(we)
ADD_A <= data;
end
always @ (posedge clk or posedge reset)
begin
if(reset)
ADD_B <= 0;
else if(ce)
ADD_B <= ADD_B + ADD_A; //ADD_B为累加的结果
end
always @ (posedge clk or posedge reset)
begin
if(reset)
cose_DR <= 0;
else if(ce)
cose_DR <= cose_D;
end
always @ (posedge clk or posedge reset)
begin
if(reset)
sine_DR <= 0;
else if(ce)
sine_DR <= sine_D;
end
//调用两个ROM,存储着正余弦波形一个周期的数值
cos u1(
.clka(clk),
.addra(ROM_A),
.douta(cose_D));
sin u2(
.clka(clk),
.addra(ROM_A),
.douta(sine_D));
endmodule