基于FPGA的DDS在Vivado中仿真以及在ZYNQ7020上板的实现(1)

1 篇文章 0 订阅

本系列文章详细介绍了DDS在Vivado中的仿真实现、综合、布线、生成bit流以及上板的过程。

(一)初始配置

1)先下载Vivado软件,本人使用的是2019.1版本的Vivado,使用其他版本Vivado的读者也可以类比操作,具体的下载安装过程很多文章都有,就不在本文中详细介绍了。
2)打开Vivado软件,点击create project,新建工程。
在这里插入图片描述
3)点击next
在这里插入图片描述
4)给文件命名,并保存到相应的路径,最好不要保存到C盘,设置好后直接点击next
在这里插入图片描述
5)之后如图中勾选,点击next
在这里插入图片描述
6)因为本人使用的是Zybo Z7系列ZYNQ7020开发板,因此相关配置如下图所示,读者可以根据自己使用的开发板进行相应的配置,配置好后点击next

本人使用的开发板Zybo Z7系列ZYNQ7020
在这里插入图片描述
对应的相关硬件配置
在这里插入图片描述
配置好之后,点击finish完成配置

(二)DDS程序编写

1)首先点击add source
在这里插入图片描述
2)建立design source文件,如图所示,点击next
在这里插入图片描述
3)点击Creat File
在这里插入图片描述
4)文件命名完点击ok
在这里插入图片描述
5)点击finish

6)之后点击OK,弹窗点击Yes就行
在这里插入图片描述
7)建立好设计文件直接编写设计文件就行,这里直接上代码

module DDS(
  input clk,
  input rst_n,
  input [1:0] Mode_Sel,
  input [1:0] fword_sel, 
  output DA_clk,
  output reg [11:0] Data

);
  reg [31:0] r_fword;
  reg [11:0] r_pword;
  reg [31:0] cnt;
  wire [11:0] rom_addr;
  wire[11:0]  rom_addr1;
  wire[11:0]  rom_addr2;
  wire[11:0]  rom_addr3;
  wire[11:0]  rom_addr4;
  

  always@(posedge clk or negedge rst_n)
  begin
    if(rst_n) begin
		  r_pword <= 0;
      end
    else begin
		  r_pword <= 2048;	 //这里时相位控制,单通道设计可以忽略
		end
  end

  
  always@(posedge clk or negedge rst_n)
     if(rst_n)
	    cnt <= 32'd0;
	   else
	    cnt <= cnt +r_fword;
	    	 
	assign rom_addr = cnt[31:20] + r_pword;
	assign rom_addr1 = cnt[31:20] + r_pword;
	assign rom_addr2 = cnt[31:20] + r_pword;
    assign rom_addr3 = cnt[31:20] + r_pword;
    assign rom_addr4 = cnt[31:20] + r_pword;   
    assign DA_clk=clk;
    
//例化不同的波形IP核
wire [11:0]Data_sin,Data_sin1,Data_square,Data_triangular,Data_sawtooth_wave;
	
sine_wave sine_DDS(
  .clka(clk),    // input wire clka
  .addra(rom_addr),  // input wire [11 : 0] addra
  .douta(Data_sin) // output wire [11 : 0] douta
);//正弦

triangular_wave triangular_DDS(
  .clka(clk),    // input wire clka
  .addra(rom_addr1),  // input wire [11 : 0] addra
  .douta(Data_triangular) // output wire [11 : 0] douta
);//三角
square_wave square_DDS(
  .clka(clk),    // input wire clka
  .addra(rom_addr2),  // input wire [11 : 0] addra
  .douta(Data_square) // output wire [11 : 0] douta
);//方波

sawtooth_wave sawtooth_wave_DDS(
  .clka(clk),    // input wire clka
  .addra(rom_addr3),  // input wire [11 : 0] addra
  .douta(Data_sawtooth_wave) // output wire [11 : 0] douta
);//锯齿
 sine1_DDS sine_DDS1(
  .clka(clk),    // input wire clka
  .addra(rom_addr4),  // input wire [11 : 0] addra
  .douta(Data_sin1) // output wire [11 : 0] douta
);//幅度改变的正弦


 //矩阵混合模块
wire signed [11:0] a11, a12, a21, a22;
    assign a11 = 12'h300; 
    assign a12 = 12'h600; 
    assign a21 = 12'h100; 
    assign a22 = 12'h800;  
reg signed [23:0] a11s1;
reg signed [23:0] a12s2;
reg signed [23:0] a21s1;
reg signed [23:0] a22s2;
always @(posedge clk or negedge rst_n)begin
    if(rst_n)begin
        a11s1 <= 'b0;
        a12s2 <= 'b0;
        a21s1 <= 'b0;
        a22s2 <= 'b0;
    end
    else begin//混合矩阵混合
        a11s1 <= a11 * Data_sin;
        a12s2 <= a12 * Data_square;
        a21s1 <= a21 * Data_sin;
        a22s2 <= a22 * Data_square;
    end
end

reg signed [11:0] wave1;
reg signed [11:0] wave2;
always@(posedge clk or negedge rst_n)begin
    if(rst_n)begin
        wave1 <= 'b0;
        wave2 <= 'b0;
    end
    else begin
        wave1 <= (a11s1 >>> 12) + (a12s2 >>> 12);
        wave2 <= (a21s1 >>> 12) - (a22s2 >>> 12);
    end
end
//频率的切换   
    always@(*)
        case(fword_sel)
            0:r_fword=8590;//250HZ
            1:r_fword=85899;//2500HZ
            2:r_fword=858993;//25KHZ
            3:r_fword=8589935;//250KHZ
            
        endcase 
//波形的切换
   always@(*)
        case(Mode_Sel)
            0:Data=Data_sin;//正弦波
            1:Data=Data_square;//方波
//          1:Data=Data_sin1;//与第一个正弦波相比幅度改变的正弦波
            2:Data=Data_triangular;//三角波
//          3:Data=Data_sawtooth_wave;//锯齿波
            3:Data=wave1;//正弦和方波进行一定比例混合的混合波
            
         endcase
         
  
endmodule

此代码在2020版本综合时可能会报错,具体解决方法见本系列第三篇文章。

fword的数值问题要运用公式进行计算,具体的算法可以见这篇博文DDS公式计算,本文把该博文中用到的公式及频率控制字对应数值展示如下:
在这里插入图片描述
其中,本设计的系统时钟位125MHZ,另一位博主用的是50MHZ,因此相同的数值下,本设计所产生的频率为上述图示的2.5倍

8)因为代码中包含例化,所以还需要在Vivado中自制ip核,自制IP核可以用matlab编写coe文件,或者直接下载一个mif精灵生成coe文件,本文使用的方法是直接下载mif精灵。本设计使用的是小梅哥团队开发的mif精灵。下载过程很简单,具体下载过程见下面链接
mif精灵下载
9)下载完成后,打开界面,选择xilinx公司,之后直接生成各种波形即可,本设计使用的位宽是12位,数据深度是4096
在这里插入图片描述
(这里不知道是不是有一个小bug,生成方波和三角波时幅度最大值,即maxi,不能选4096,4096以下才可以,而锯齿波和正弦波可以选4096,不然对后续导入coe文件有影响。所以读者在产生文件时幅度最好不要超过深度)

10)生成完文件之后,把文件放到工程目录下,方便进行之后的导入
在这里插入图片描述
(sine_wave和sine_wave1是改变了一下幅度的最大值)
11)之后回到vivado界面,进行ip核配置,首先点击图示处
在这里插入图片描述
12)之后搜索block,选择下面选项
在这里插入图片描述
13)进行命名和相关配置,配置除了图示,其余保持默认即可
在这里插入图片描述
在这里插入图片描述
这里将之前生成的的coe文件导入即可
在这里插入图片描述
之后一直按照默认选项选择ok即可
然后一直依葫芦画瓢将方波、三角波、正弦波、锯齿波导入即可。

注:
1、本设计导入了两个不同幅度的波形,为了做幅度调节的对比使用。
2、ip核的命名一定要与下图标注的例化处命名保持一致
在这里插入图片描述
3、ip核生成之后命名就无法改变了,所以一定要注意提前命名的准确性

仿真和上板的相关步骤见下一节

  • 17
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Zynq 7020内部集成了一个FPGA(Field Programmable Gate Array),用于实现可编程逻辑(PL)部分。 FPGA是一种可编程逻辑器件,可以通过编程来实现各种数字电路功能。在Zynq 7020,PL部分可以与PS(Processing System)部分进行高效交互,通过AXI4协议来实现数据传输。开发人员可以使用Vivado软件进行FPGA的配置和调试。 Zynq 7020配套的开发板为Zybo Z7系列,该开发板上搭载了Zynq 7020芯片,并且具有相应的硬件配置。 总结来说,Zynq 7020内部集成了一个FPGA,可以通过Vivado进行配置和调试。在开发过程,可以使用Zybo Z7系列开发板进行硬件开发。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ZYNQ AX7020 PL读写PS端 DDR 数据 vivado](https://download.csdn.net/download/Calvin790704/87389599)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [基于FPGADDSVivado仿真以及在ZYNQ7020上板实现(1)](https://blog.csdn.net/syyzuiqiang/article/details/118103211)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值