DDS作业

来源:互联网 发布:淘宝确认收货时间15天 编辑:程序博客网 时间:2024/05/01 02:25

实验内容

在FPGA上设计一个DDS模块,在DE0 开发板上运行,在FPGA芯片内部合成出数字波形即可。不用输出模拟信号,本模块满足以下条件:

  • 使用板载晶振的50MHz时钟,合成以下频率的信号
  • 1、500KHz 正弦波信号。 2、1MHz 正弦波信号。 3、3MHz 正弦波信号。
  • 频率字字长32位,波表ROM尺寸为 10比特地址,1024个word
  • 波形格式为2补码格式,12比特量化
  • 每个CLK输出一个有效样点。
  • 输入信号为频率字和频率字输入使能信号
  • 使用板载的拨码开关(Switch)控制生成的波形信号的不同频率。

注:波表ROM代码是用matlab或C打印生成的。不要手写

实验要求

  • 人工绘制的 电路结构RTL设计图,该图片用于说明你设计电路时的想法,注意要在RTL图中画出Verilog代码中的 生成D触发器 reg 变量
  • Quartus扫描生成的电路RTL图,该图片用于说明Quartus的电路编译结果
  • 相位累加器的输出,SignalTap截图
  • 波表ROM的输入地址,SignalTap截图
  • 至少捕获 一个完整的输出正弦波形周期的上述数据数值的SignalTap截图。
  • 输出正弦波的样值波形,SignalTap截图
  • 提交Verilog、相关MATLAB 代码,请使用博客中提供的代码块功能
  • 分析输出的正弦波信号的频谱,Matlab 截图

手工绘制RTL图


Quartus扫描生成的RTL




SignalTap截图

0.5M

1M
3M

MATLAB频谱分析截图

0.5M
1M

3M

Verilog代码


module switch_freq_word(    CLK     ,   //时钟    SW      ,   //选择频率    FQWD    ,   //输出频率字,作为下一级计数器的步进值    EN      );  //输出频率字的更新使能,高电平有效input CLK,EN;       input [2:0] SW; output reg[31:0] FQWD;  always @(posedge CLK) begin    if (EN) begin        case(SW)        3'b001: FQWD <= 10;//500kHz        3'b010: FQWD <= 20;//1MHz        3'b100: FQWD <= 60;//3MHz        default: FQWD <= 10;        endcase    end    else begin        FQWD <= FQWD ;    endendendmodule////////////////////////////////////////////////////module dds_core(  CLK   ,   // 时钟  IN    ,   // 步进值  SINOUT);  // 地址input CLK;input  [31:0] IN;//频率字字长32位output reg[9:0] SINOUT;always @ (posedge CLK) begin  SINOUT <= IN + SINOUT;endendmodule  

module DDS_CORE_ROM(  CLK    ,           // clock  RA     ,           // read address  RD     );          // read datainput         CLK;input  [9  :0] RA;output [11 :0] RD;reg    [11 :0] RD;always @ (posedge CLK)   case(RA)     10'd 0     :RD = #1 12'b 000000000000; //      0 0x0      10'd 1     :RD = #1 12'b 000000001100; //     12 0xC      10'd 2     :RD = #1 12'b 000000011001; //     25 0x19      10'd 3     :RD = #1 12'b 000000100101; //     37 0x25      ...     10'd 1023  :RD = #1 12'b 111111110100; //    -12 0xFF4  default : RD = #1 0;  endcaseendmodule 

MATLAB代码

MATLAB分析signaltap数据,进行频谱分析
san;data=san(:,5);%取数据中的第五列signal=transpose(data); %矩阵转置fs=50E6; %采样频率N=1024; %采样点数t=[0:1/fs:(N-1)/fs]; %采样时刻figure(1);plot(signal);xlabel('Time (s)');ylabel('Magnitude');Y = fft(signal,N); %做FFT变换Ayy = abs(Y); %取模Ayy=Ayy/(N/2); %换算成实际的幅度Ayy(1)=Ayy(1)/2;F=([1:N]-1)*fs/N; %换算成实际的频率值,Fn=(n-1)*Fs/Nfigure(2);stem(F(1:N/2),Ayy(1:N/2)); %显示换算后的FFT模值结果axis([0 5E6 0 2500]);title('幅度-频率曲线图');xlabel('Frequency (Hz)');ylabel('Magnitude');

生成波表ROM的MATLAB代码
#include<stdio.h>#include<math.h>#define PI 3.141593#define DEPTH 1024    /* 数据深度,即存储单元的个数 */#define WIDTH 12       /* 存储单元的宽度 */int main(void){    int n,temp;    float v;    FILE * fp;          /* 建立文件名为sine1024.mif新文件,允许写入数据,          文件名随意,但扩展名必须为.mif */    fp = fopen("sine1024.mif","w+");    if(NULL==fp)        printf("Can not creat file!\r\n");    else    {        printf("File created successfully!\n");              /* 生成文件头,注意不要忘了";" */        fprintf(fp,"DEPTH=%d;\n",DEPTH);        fprintf(fp,"WIDTH=%d;\n",WIDTH);        fprintf(fp,"ADDRESS_RADIX = HEX;\n");        fprintf(fp,"DATA_RADIX = HEX;\n");        fprintf(fp,"CONTENT\n");        fprintf(fp,"BEGIN\n");             /* 以十六进制输出地址和数据 */        for(n=0;n<DEPTH;n++)        {            /* 周期为1024个点的正弦波 */            v=sin(2*PI*n/DEPTH);            /* 将-1~1之间的正弦波的值扩展到0~4095之间 */            temp=(int)((v+1)*4095/2);   //v+1将数值平移到0~2之间            /* 以十六进制输出地址和数据 */            fprintf(fp,"%x\t:\t%x;\n",n,temp);        }        fprintf(fp,"END;\n");        fclose(fp);    //关闭文件    }}




0 0