重温FPGA开发30

基于AD9767高速ADC的DDS信号发生器

  1. 希望做一个双通道的信号发生器输出

  2. 能够简单的调整每个通道的频率输出(通过按键来循环切换几个固定的频率输出)1\10\100\1000\10000\100000\1000000\5000000Hz
    在这里插入图片描述

  3. 能够调整每个通道的输出相位(通过按键来循环切换几个固定的相位输出)
    0\30\60\90\150\180\270\320
    在这里插入图片描述

    在这里插入图片描述
    希望实现任意频率和相位的设定。

  4. 能够输出的波形形式(正弦波、方波、三角波)

创建一个工程,需要用到上一次的DDS代码

DDS_Module.v:

`timescale 1ns/1ns

module DDS_Module(
	Clk,
	Reset,
	Mode_sel,
	Fword,
	Pword,
	Data
	);

	input Clk;
	input Reset;
	input [1:0]Mode_Sel;
	input [31:0]Fword;   // 32位 最少需要4G的存储空间
	input [11:0]Pword;   // 为什么是12位 4096个点
	input [13:0]Data;    // 使用的14位的DA

	// 频率控制字同步寄存器
	reg [31:0] Fword_r;
	always(posedge Clk)
		Fword_r <= Fword;

	// 相位控制字同步寄存器
	reg [31:0] Pword_r;
	always(posedge Clk)
		Pword_r <= Pword;

	// 相位累加器
	 reg [31:0] Freq_ACC;
	 always@(posedge Clk or negedge Reset)
	 if(!Reset)
	 	Freq_ACC <= 0;
	 else
	 	Freq_ACC <= Fword_r + Freq_ACC;
	 	
	 // 按照图来看,其实可以看成组合逻辑
	 // wire [31:0]Freq_ACC_out;
	 // assign Freq_ACC_out = Freq_ACC + Pword_r;
	 
	 // 相位累加器与相位控制字的结果输出
	 reg [31:0] Freq_ACC_out;
	 always@(posedge Clk or negedge Reset)
	 if(!Reset)	
	 	Freq_ACC_out <= 0else
	 	Freq_ACC_out <= Freq_ACC + Pword_r;
	 
	 // 波形数据表地址 ROM
	 reg [11:0] Rom_addr;
	 // assign = Freq_ACC_out;
	 // Fword = 2'20
	 // Freq_ACC_out[31:20]  
	 assign Rom_Addr = Freq_ACC_out[31:20];
	 
	// 例化ROM
	blk.mem_gen_0 rom_sine(
	.clka(Clk),
	.addra(Rom_Addr),
	.douta(Data_sine)
	);

	// 例化ROM
	blk.mem_gen_0 rom_square(
	.clka(Clk),
	.addra(Rom_Addr),
	.douta(Data_square)
	);

	// 例化ROM
	blk.mem_gen_0 rom_triangular(
	.clka(Clk),
	.addra(Rom_Addr),
	.douta(Data_triangular)
	);

	always@(*)
		case(Mode_Sel)
			0:Data = Data_sine;
			1:Data = Data_square;
			2:Data = Data_triangular;
			3:Data = 8192;
		endcase	

endmodule

DDS_AD9767.v:

`timescale 1ns/1ps

module DDS_AD9767(
	Clk,
	Reset,
	Mode_SelA,
	Mode_SelB,
	DataA,
	DataB,
	Key,
	ClkA,
	ClkB,
	WRTA,
	WRTB,	
	);

	input Clk,
	input Reset,
	input [1:0]Mode_SelA,
	input [1:0]Mode_SelB,
	output [13:0]DataA,
	output [13:0]DataB,
	input [3:0]Key
	output [13:0]DataA;
	output ClkA;
	output [13:0]DataB;
	output ClkB;
	output WRTB;

	assign ClkA = Clk;
	assign ClkB = Clk;
	assign WRTB = ClkB;
	

	reg [31:0] fworda, fowordb;
	reg [11:0] pworda, pwordb;

DDS_Module DDS_moduleA(
	.Clk(Clk),
	.Reset(Reset),
	.Mode_Sel(Mode_SelA),
	.Fword(Fword_A),
	.Pword(PwordA),
	.Data(DataA)
	);

DDS_Module DDS_moduleB(
	.Clk(Clk),
	.Reset(Reset),
	.Mode_Sel(Mode_SelB),
	.Fword(Fword_B),
	.Pword(PwordB),
	.Data(DataB)
	);

// 例化 按键消抖模块
key_filter key_filter(
	.Clk(Clk),
	.Reset(Reset),
	.Key(Key[0]),
	.Key_Flag(Key_Flag[0]),
	.Key_State(Key_State[0])
	);

// 例化 按键消抖模块
key_filter key_filter1(
	.Clk(Clk),
	.Reset(Reset),
	.Key(Key[1]),
	.Key_Flag(Key_Flag[1]),
	.Key_State(Key_State[1])
	);

// 例化 按键消抖模块
key_filter key_filter2(
	.Clk(Clk),
	.Reset(Reset),
	.Key(Key[2]),
	.Key_Flag(Key_Flag[2]),
	.Key_State(Key_State[2])
	);

// 例化 按键消抖模块
key_filter key_filter3(
	.Clk(Clk),
	.Reset(Reset),
	.Key(Key[3]),
	.Key_Flag(Key_Flag[3]),
	.Key_State(Key_State[3])
	);


//  频率的切换
	reg [2:0] cha_fword_sel;
	reg [2:0] chb_fword_sel;

	reg [2:0] cha_bword_sel;
	reg [2:0] chb_bword_sel;

	always@(posedge Clk or negedge Reset)
	if(Reset)
		cha_fword_sel <= 0;
	else if(Key_Flag[0] && Key_State[0] == 0)
		cha_fword_sel <= cha_fword_sel + 1'd1;
		
			
	always@(posedge Clk or negedge Reset)
	if(Reset)
		chb_fword_sel <= 0;
	else if(Key_Flag[1] && Key_State[1] == 0)
		chb_fword_sel <= chb_fword_sel + 1'd1;

	always@(posedge Clk or negedge Reset)
	if(Reset)
		cha_pword_sel <= 0;
	else if(Key_Flag[2] && Key_State[2] == 0)
		cha_pword_sel <= cha_pword_sel + 1'd1;

	always@(posedge Clk or negedge Reset)
	if(Reset)
		chb_pword_sel <= 0;
	else if(Key_Flag[3] && Key_State[3] == 0)
		chb_pword_sel <= chb_pword_sel + 1'd1;	

	always(*)
		case(cha_fword_sel)
			// 算频率控制字
			0: fworda = 2**32 / 50000000;  
			1: fworda = 2**32 / 5000000;  
			2: fworda = 2**32 / 500000;  
			3: fworda = 2**32 / 50000;  
			4: fworda = 2**32 / 5000;  
			5: fworda = 2**32 / 500;  
			6: fworda = 2**32 / 50;  
			7: fworda = 2**32 / 10;  
		endcase

	always(*)
		case(chb_fword_sel)
			// 算频率控制字
			0: fwordb = 2**32 / 50000000;  
			1: fwordb = 2**32 / 5000000;  
			2: fwordb = 2**32 / 500000;  
			3: fwordb = 2**32 / 50000;  
			4: fwordb = 2**32 / 5000;  
			5: fwordb = 2**32 / 500;  
			6: fwordb = 2**32 / 50;  
			7: fwordb = 2**32 / 10;  
		endcase

	always(*)
		case(cha_pword_sel)
			// 算频率控制字
			0: pworda = 0;  
			1: pworda = 341; 
			2: pworda = 683;   
			3: pworda = 1024;  
			4: pworda = 1707;  
			5: pworda = 2048;  
			6: pworda = 3072;  
			7: pworda = 3641;  
		endcase

	always(*)
		case(chb_pword_sel)
			// 算频率控制字
			0: pwordb = 0;  
			1: pwordb = 341; 
			2: pwordb = 683;   
			3: pwordb = 1024;  
			4: pwordb = 1707;  
			5: pwordb = 2048;  
			6: pwordb = 3072;  
			7: pwordb = 3641;  
		endcase

	

endmoudle

ACM9767模块是一款高性能高速双通道DAC模块。模块具有单电源5v供电输入,双通道数字转模拟信号输出,每个通道数据分辨率为14位,输出电压范围为±5v,且转换速率高达125Msps,非常适合信号发生器、数字调制通信等应用。

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值