基于FPGA的可调节DDS设计与实现

本文承接以上博主的博客且增添了相位可调节,双通道输出和多种合成波输出的功能,同时通过ILA仿真验证其功能。基于FPGA的DDS在Vivado中仿真以及在ZYNQ7020上板的实现(2)_vivado dds可以在板子里使用嘛_静心.舍得.放下的博客-CSDN博客ILA硬件仿真内容:(详细过程可参考bilibili博主:小梅哥爱漂流  的 Vivado在线调试工具ILA使用教程)

1)点击IP Catalog

2)搜索框内输入ILA,双击如下图所示

3)如图按照如下配置所需

4)跳出如下界面,点击Generate

5)在Sources出现该文件

6)在IP Sources里选择,双击ila_0.veo,打开文件

 7)复制此段程序到DDS.v的文件里

8)在DDS中根据需求,例化ILA程序

9)点击Run Synthesis

10)点击Run Implementation 

11)运行成功后,点击Genrate Bistream

12)静静等待,点击Auto Connect

 

13)连接硬件,连接成功后出现

14)点击Program device

15)即可出现波形

相位可调节实现

1)新建文件key_debounce.v文件(按键消抖)

 

//按键消抖模块
module key_debounce(
    input        sys_clk ,
    input        sys_rst_n ,
    input        key ,         //外部输入的按键值
    output  reg  key_value ,   //消抖后的按键值
    output  reg  key_flag      //消抖后的按键值的效标志
);

//reg define
reg [19:0] cnt ;
reg  key_reg ;


//按键值消抖
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n) begin
        cnt <= 20'd0;
        key_reg <= 1'b1;
    end
    else begin
        key_reg <= key;           //将按键值延迟一拍
        if(key_reg != key) begin  //如果当前按键值和前一拍的按键值不一样,即按键被按下或松开
            cnt <= 20'd100_0000;  //则将计数器置为20'd100_0000,
                                  //即延时100_0000 * 20ns(1s/50MHz) = 20ms
        end
        else begin                //如果当前按键值和前一个按键值一样,即按键没有发生变化
            if(cnt > 20'd0)       //则计数器递减到0
                cnt <= cnt - 1'b1;  
            else
                cnt <= 20'd0;
        end
    end
end

//将消抖后的最终的按键值送出去
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n) begin
        key_value <= 1'b1;
        key_flag  <= 1'b0;
    end
	//在计数器递减到1时送出按键值
    else if(cnt == 20'd1) begin
		key_value <= key;
		key_flag  <= 1'b1;
        end
    else begin
		key_value <= key_value;
		key_flag  <= 1'b0;
    end
end

endmodule

2)新建文件key_control.v文件 (按键控制)

//按键控制模块
module key_control(
    input sys_clk ,  	//接时钟
    input sys_rst_n,	//接复位
    input key,			//接你的key
    output reg led,	//可以接一个led来显示你的按键是否成功按下
	output reg [1:0] counter	//counter 四个状态 接到你自己写的counter就行 四种不同的相位
    );
    wire key_value ;				//key的value信号 可以忽略不管
    wire key_flag ;					//key的flag信号 可以忽略不管

    key_debounce u_key_debounce(
        .sys_clk (sys_clk),
        .sys_rst_n (sys_rst_n),
        .key (key),
        .key_value (key_value),
        .key_flag (key_flag)
    );
    always @ (posedge sys_clk or negedge sys_rst_n) begin
        if(sys_rst_n)	//sys_rst_n 按下,复位
            begin
                led <= 1'b0;
				counter<= 2'b00;
            end
        else 	begin
            if (key_flag && (key_value == 1'b0))	begin
				if(counter == 2'b11) begin //counter 四个状态 00 01 10 11
					led <= ~led;
					counter<= 2'b00;	
				end
				else begin    
					led <= ~led;
					counter <= counter + 1 ;	
				end
            end    
        end
    end   

endmodule

3)将DDS.V设置成顶层文件,右击DDS.v 

 

双通道设置和合成波:下面给出DDS文件总代码

module DDS(
  input clk,
  input key,
  input rst_n,
  input [1:0] Mode_Sel,
  input [1:0] fword_sel, 
  output DA_clk,
  output DB_clk,
  output  led,
  output reg [11:0] Data,
  output reg [11:0] Data1
);

  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;

wire [1:0] counter;
  
 key_control key_control(
    .sys_clk(clk),
    .sys_rst_n(rst_n),
    .key(key),
    .led(led),
    .counter(counter)
 ) ;
  
/* reg[1:0] counter=2'b00;
 always@(posedge clk or negedge rst_n)begin
      if(rst_n)begin
         counter<=2'b00;
      end else begin
          if(counter==3)begin
             counter<=0;
          end else begin
             counter<=counter+1;
          end
      end
 end

  
 ila_0 ila_0 (
	.clk(clk), // input wire clk



	.probe0(Data_sin[11:4]), // input wire [7:0]  probe0  
	.probe1(Data_square[11:4]), // input wire [7:0]  probe1    
	.probe2(Data_triangular[11:4]), // input wire [7:0]  probe2 
	.probe3(Data_sawtooth_wave[11:4]) // input wire [7:0]  probe3
);
 */ 

  always@(*)
  begin
    if(counter==0) begin
		  r_pword <= 0;
      end
    else if(counter==1) begin
		  r_pword <= 512;	 
		end
	else if(counter==2) begin
		  r_pword <= 1024;	 
		end
    else if(counter==3) 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;
    assign DB_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'h400; 
    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_triangular;
    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


 //矩阵混合模块
wire signed [11:0] b11, b12, b21, b22;
    assign b11 = 12'h300; 
    assign b12 = 12'h600; 
    assign b21 = 12'h100; 
    assign b22 = 12'h800;  
reg signed [23:0] b11s1;
reg signed [23:0] b12s2;
reg signed [23:0] b21s1;
reg signed [23:0] b22s2;
always @(posedge clk or negedge rst_n)begin
    if(rst_n)begin
        b11s1 <= 'b0;
        b12s2 <= 'b0;
        b21s1 <= 'b0;
        b22s2 <= 'b0;
    end
    else begin//混合矩阵混合
        b11s1 <= b11 * Data_triangular;
        b12s2 <= b12 * Data_sawtooth_wave;
        b21s1 <= b21 * Data_triangular;
        b22s2 <= b22 * Data_sawtooth_wave;
    end
end

reg signed [11:0] wave3;
reg signed [11:0] wave4;
always@(posedge clk or negedge rst_n)begin
    if(rst_n)begin
        wave3 <= 'b0;
        wave4 <= 'b0;
    end
    else begin
        wave3 <= (b11s1 >>> 12) + (b12s2 >>> 12);
        wave4 <= (b21s1 >>> 12) - (b22s2 >>> 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:begin
                   Data=Data_sin;
                   Data1=Data_square;
               end//正弦波和方波
            1:begin
                   Data=Data_triangular;
                   Data1=Data_sawtooth_wave;
              end//三角波和锯齿波
            2:begin
                   Data=wave1; 
                   Data1=wave2;
               end//wave1:正弦波和方波的混合;wave2:正弦和三角波的混合
             3:begin
                   Data=wave3;
                   Data1=wave4;
               end//三角波和锯齿的混合  
            
         endcase
           
endmodule

 管脚约束文件XDC改为以下内容

set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property PACKAGE_PIN K17 [get_ports clk]
set_property PACKAGE_PIN Y16 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports DA_clk]
set_property PACKAGE_PIN V8 [get_ports DA_clk]
set_property IOSTANDARD LVCMOS33 [get_ports {Mode_Sel[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Mode_Sel[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[9]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[10]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data[11]}]
set_property PACKAGE_PIN V15 [get_ports {Data[11]}]
set_property PACKAGE_PIN W15 [get_ports {Data[10]}]
set_property PACKAGE_PIN T11 [get_ports {Data[9]}]
set_property PACKAGE_PIN T10 [get_ports {Data[8]}]
set_property PACKAGE_PIN W14 [get_ports {Data[7]}]
set_property PACKAGE_PIN Y14 [get_ports {Data[6]}]
set_property PACKAGE_PIN T12 [get_ports {Data[5]}]
set_property PACKAGE_PIN U12 [get_ports {Data[4]}]
set_property PACKAGE_PIN G15 [get_ports {Mode_Sel[1]}]
set_property PACKAGE_PIN P15 [get_ports {Mode_Sel[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fword_sel[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {fword_sel[0]}]
set_property PACKAGE_PIN W13 [get_ports {fword_sel[1]}]
set_property PACKAGE_PIN T16 [get_ports {fword_sel[0]}]


set_property IOSTANDARD LVCMOS33 [get_ports {Data1[11]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[10]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[9]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Data1[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports DB_clk]

set_property PACKAGE_PIN W8 [get_ports DB_clk]
set_property PACKAGE_PIN T14 [get_ports {Data1[11]}]
set_property PACKAGE_PIN T15 [get_ports {Data1[10]}]
set_property PACKAGE_PIN P14 [get_ports {Data1[9]}]
set_property PACKAGE_PIN R14 [get_ports {Data1[8]}]
set_property PACKAGE_PIN U14 [get_ports {Data1[7]}]
set_property PACKAGE_PIN U15 [get_ports {Data1[6]}]
set_property PACKAGE_PIN V17 [get_ports {Data1[5]}]
set_property PACKAGE_PIN V18 [get_ports {Data1[4]}]

#set_property PACKAGE_PIN K19 [get_ports rword1]
#set_property PACKAGE_PIN P16 [get_ports rword2]
#set_property PACKAGE_PIN K18 [get_ports rword3]
#set_property IOSTANDARD LVCMOS33 [get_ports rword1]
#set_property IOSTANDARD LVCMOS33 [get_ports rword2]
#set_property IOSTANDARD LVCMOS33 [get_ports rword3]

set_property IOSTANDARD LVCMOS33 [get_ports key]
set_property IOSTANDARD LVCMOS33 [get_ports led]
set_property PACKAGE_PIN K19 [get_ports key]
set_property PACKAGE_PIN M14 [get_ports led]

运行结果展示

250HZ频率展示:

2.5KHZ频率展示:

硬件展示

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值