赞
踩
直接数字频率合成(DDS)的基本原理是利用采样定理,通过查表法产生波形,其基本结构如下图所示,其中fc为数字逻辑电路的时钟频率。
第一步,我们先需要将正弦波进行量化,才能将数值输送到RAM中保存
这里给出利用C语言进行量化的程序,修改正弦波表达式即可得到对应正弦波
//在正弦波一个周期内取样512点,每点8bit量化,存储在memory[512]中 #include<math.h> #include<stdio.h> #define Pi 3.1415926 float SinWave(float x) { return ( 0.5 + 0.5*sin(x) ); //正弦波表达式 } void main() { int n,memory[512]; float w; FILE *f; f =fopen("result.txt","w"); //保存输出内容文档的名称,运行程序后在本程序文件夹生成 w = 2*Pi/512; for(n=0;n<512;n++) { memory[n] = 255 * SinWave(n*w); fprintf(f," memory[%3d] <= 8'h%x;\n",n,memory[n]); //已改为verilog程序中的格式 } fclose(f); }
需要提醒的是:该程序在devcpp
、codeblocks
等IDE上都无法正常运行,建议使用VC++6.0进行编译
之后发现可能是由于其需要整个工程文件来运行
**试图用自己实践文件的同学:**特别注意我更改的输出格式,如果用原先的格式输出放到verilog
程序里是有问题的(具体可对照verilog
实践的初始程序)。
本次实践中用RAM代替了ROM
这里给出RAM的框架
module RAM(clk,rst_n,addr,data_out); //这里的RAM就是器件名 input clk; input rst_n; input [8:0] addr; output[7:0] data_out; reg[7:0] data_out; reg[7:0] mem[511:0]; always @(posedge clk or negedge rst_n) if(~rst_n) begin /* 把之前输出的一大串mem值放这段 */ end always @(posedge clk) data_out = mem[addr]; endmodule
量化后的正弦波数值就保存在RAM中了。
一个RAM对应一路,如果你需要两路正弦波,就创建另一个verilog
文件,两个文件分别改第一行的名称为RAM_1和RAM_2,三路同理,以此类推。
接下来就是把量化后的正弦波在FPGA中通过D/A转换重新生成为连续波形。
这里给出三路正弦波转换的代码:
module SinWave(clk,rst_n,FTW,SinWaveData_1,SinWaveData_2,SinWaveData_3); input clk; input rst_n; input[31:0] FTW; output[7:0] SinWaveData_1; output[7:0] SinWaveData_2; output[7:0] SinWaveData_3; reg[31:0] FACCResult; always@(posedge clk or negedge rst_n) if(~rst_n) FACCResult <= 0; else FACCResult <= FACCResult + FTW; RAM RAM_inst( .clk(clk), .rst_n(rst_n), .addr(FACCResult[31:23]), .data_out(SinWaveData_1) ); RAM_1 RAM_1_inst( .clk(clk), .rst_n(rst_n), .addr(FACCResult[31:23]), .data_out(SinWaveData_2) ); RAM_2 RAM_2_inst( .clk(clk), .rst_n(rst_n), .addr(FACCResult[31:23]), .data_out(SinWaveData_3) ); endmodule
可以看到,我分别使用了三个RAM,因此输出端也要修改为三个,并且连接到对应的器件端口(data_out)。
修改好testbench
运行结果如下:
三路相差120度的正弦波
这里给出我的testbench
程序:
`timescale 1ns/1ps module testbench; reg clk; reg rst_n; reg[31:0] FTW; wire[7:0] SinWaveData_1; wire[7:0] SinWaveData_2; wire[7:0] SinWaveData_3; SinWave SinWave_inst ( .clk(clk), .rst_n(rst_n), .FTW(FTW), .SinWaveData_1(SinWaveData_1), .SinWaveData_2(SinWaveData_2), .SinWaveData_3(SinWaveData_3) ); always #5 clk = ~clk; //clock = 100MHz initial begin #0 clk = 1; rst_n = 0; FTW = 32'h01000000; #40 rst_n = 1; #10000 $stop; end endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。