用Verilog HDL語言實(shí)現(xiàn)基于DDS技術(shù)的余弦信號發(fā)生器,其輸出位寬為 16bit。
3.2 使用MATLAB定點(diǎn)正、余弦波形數(shù)值借助MATLAB生成ROM中的定點(diǎn)正、余弦波形數(shù)值,形成.coe文件。
1.利用MATLAB計算出正、余弦波形的浮點(diǎn)值,并量化 16bit 的定點(diǎn)波形數(shù)值[2]。
x= linspace(0,6.28,1024); %在區(qū)間[0,6.28]之間等間隔地取1024個點(diǎn)
y1=cos(x); %計算相應(yīng)的正余弦值
y2=sin(x);
%由于正余弦波形的值在[0,1]之間,需要量化成16bit,先將數(shù)值放大
y1=y1*32678;
y2=y2*32768;
%再將放大的浮點(diǎn)值量化,并寫到存放在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.產(chǎn)生.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文件生成的不對,圖中用橢圓標(biāo)志之處是紅色的,.coe 文件錯誤的類型主要有數(shù)據(jù)基數(shù)不對和數(shù)據(jù)的長度不對這兩類。
3.4 DDS的Verilog HDL的實(shí)現(xiàn)
module dds(data, we, clk, ce, reset, sine, cose);
input [31 : 0] data; //頻率控制字
input we; //頻率控制字寫使能
input clk; //時鐘
input ce; //DDS使能
input reset; //復(fù)位
output [15 : 0] sine; //正弦信號輸出
output [15 : 0] cose; //余弦信號輸出
reg [31 : 0] ADD_A; //正弦波產(chǎn)生模塊的相位累加器
reg [31 : 0] ADD_B; //余弦波產(chǎn)生模塊的相位累加器
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) //系統(tǒng)初始化時,默認(rèn)的頻率控制字為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為累加的結(jié)果
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
//調(diào)用兩個ROM,存儲著正余弦波形一個周期的數(shù)值
cos u1(
.clka(clk),
.addra(ROM_A),
.douta(cose_D));
sin u2(
.clka(clk),
.addra(ROM_A),
.douta(sine_D));
endmodule