DDS信号发生器:直接数字式频率合成器 (Direct Digital Synthesizer)

1、任意波形

首先参考之前写过的ip_rom这篇文章。 与上述文章不同的是。任意波形,只是将.mif文件替代掉。

https://blog.csdn.net/WJC1997/article/details/118994133?spm=1001.2014.3001.5501

例:生成一个正弦波

① 使用波形生成器软件,生成一个数据长度为256、位宽为8的正弦波后,保存。(保存的格式为.mif格式)在这里插入图片描述在这里插入图片描述
②这里点 Browse 选择 自己生成的 sin.mif 文件替代

在这里插入图片描述
③ 其余均参照之前的文章
1、radix—>unsigned 2、format—>auto… 3、format—>custom(max:255——min:0)
在这里插入图片描述

2、任意相位:—>改变初始相位(改变初始地址)即可

3、任意频率:

正弦波当前不改变情况下对应频率:
T = 20ns * 256——> f = 1/ T = 1 / (20ns * 256) =1 /20ns*1 /256 =50M / 256 = 195.312Khz
在这里插入图片描述
如何改变当前195.31KHz频率?

(1):当前开发板晶振频率50Mhz,改变晶振时钟大小从而改变输出频率(不太现实

(2):增加地址步进值,之前每次加一时得到频率195.31Khz,如果把地址的步进值设置值+2,意味着地址从0计数到255的时间缩短一半,从而频率增加二倍。(只能得到195.31KHz的整数倍,也不太现实

在这里插入图片描述
在这里插入图片描述
(3):增加一个虚拟地址计数器(temp_addr),虚拟地址计数器位宽比8大(8的整数倍),其中虚拟地址计数器作为当前地址的计数,不再为有效地址(addr),虚拟地址计数器每次加多少呢(取决于当前设置的虚拟地址计数器的位宽)?采用真实计数器地址取虚拟地址计数器高8位

T = 20ns * 256——> f = 1/ T = 1 / (20ns * 256) =1 /20ns*1 /256 =50M / 256 = 195.312Khz

f =50M / 256

195.31Khz = 50M / 256 = 50M / 2^8 *1(地址步进值)

1Khz = 50M/2^16B(地址步进值)—>B = 1Khz * 2^16/50Mhz = 1.31072
1Khz = 50M/2^24
B(地址步进值)—>B = 1Khz2^24/ 50Mhz = 335.54432
1Khz = 50M/2^32
B(地址步进值)—>B = 1Khz*2^32/50Mhz= 85899.34592

32位虚拟地址计数器位宽,真实地址取32位虚拟地址计数器对应的高8位
32位虚拟地址计数器能够计数的值: 2^32 = 4294967296
32位虚拟地址计数器对应的高8位:2^32 - 2^24 = 4278190080

F输出 = 50Mhz / 2^ N * B

**

测试:

**

  • 16位虚拟地址计数器位宽: Fclk = 763hz

  • 24位虚拟地址计数器位宽: Fclk = 1khz

    位宽越高,精度越高,误差越小。

①16位

module addr_ctrl(clk, rst_n, addr);

    input clk;
    input rst_n;
    
    output  [7:0] addr;     //控制ROM的地址变化(0~255)
    
    reg [15:0] temp_addr;

    always@ (posedge clk,negedge rst_n)begin
        if(rst_n == 1'b0)
            temp_addr <= 16'd0;
        else if(temp_addr < 2 ** 16 - 1'd1)
            temp_addr <= temp_addr + 16'd1;
        else
            temp_addr <= 16'd0;
    end
    
    assign addr  =  temp_addr[15 : 8];
    
endmodule

在这里插入图片描述
②24位

module addr_ctrl(clk, rst_n, addr);

	input clk;
	input rst_n;
	
	output  [7:0] addr;		//控制ROM的地址变化(0~255)
	
	reg [23:0] temp_addr;

	always@ (posedge clk,negedge rst_n)begin
		if(rst_n == 1'b0)
			temp_addr <= 24'd0;
		else if(temp_addr < 2 ** 24 - 1'd1)
			temp_addr <= temp_addr + 24'd336;
		else
			temp_addr <= 24'd0;
	end
	
	assign addr  =  temp_addr[23 : 16];
	
endmodule

在这里插入图片描述

4、结束语

“忽觉夏深年过半,不知不觉就已立秋了,空气中能捕捉那一丝凉意啦~
但还是最喜欢明媚的夏天,喜欢听着蝉在二重奏入睡,也喜欢烈火般的午后来一口冰凉的西瓜,又或者开一瓶冰汽水,喜欢穿着各色的裙子,那肆意昂扬的青春,小王小王要接着努力,不要偷懒呀~” ——小王随笔

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值