(DDS)正弦波形发生器——幅值、频率、相位可调(二)
主要关于调相方面
一、项目任务:
设计一个幅值、频率、相位均可调的正弦波发生器。 频率每次增加10kHz相位每次增加 PI/2幅值每次增加两倍ROM的深度为1024、宽度为8二、文章内容:
完成调相模块并验证功能完成调幅模块按结构图来连接各个模块并仿真验证1、调相
从图像上来理解调整相位就是原函数在X轴上进行水平移动。
在本项目中函数的波形图按照顺序存在ROM中,我们只要按照比例调整读取ROM的地址,即可调相。
前文中我们使用32位寄存器的高8位用做ROM的地址,因此只要有按键按下,我们按照相位同比例的调整读取ROM的地址即可。
ROM的深度为1024、宽度为8储存标准正弦函数,那么可知其式为:
f(x)=128sin(x512π)+128% MathType!MTEF!2!1!+- % feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn % hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr % 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr % pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs % 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai % aabeqaamaabaabauaakeaacaqGMbGaaiikaiaadIhacaGGPaGaeyyp % a0JaaGymaiaaikdacaaI4aGaci4CaiaacMgacaGGUbGaaiikamaala % aabaGaamiEaaqaaiaaiwdacaaIXaGaaGOmaaaacqaHapaCcaGGPaaa % aa!4ECD! {\rm{f}}(x) = 128\sin (\frac{x}{{512}}\pi )+128 f(x)=128sin(512xπ)+128
这里x对应的是ROM地址、y对应的是ROM中数据也即幅值。范围取x从0到1023、y从0到255。
若按键一次,相位增加PI/2,则有:
g(x)=128sin(x512π+π2)+128=128sin((x512+12)π)+128=128sin((x+256512)π)+128% MathType!MTEF!2!1!+- % feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn % hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr % 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr % pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs % 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai % aabeqaamaabaabauaakqaabeqaaiaadEgacaGGOaGaamiEaiaacMca % cqGH9aqpcaaIXaGaaGOmaiaaiIdaciGGZbGaaiyAaiaac6gacaGGOa % WaaSaaaeaacaWG4baabaGaaGynaiaaigdacaaIYaaaaiabec8aWjab % gUcaRmaalaaabaGaeqiWdahabaGaaGOmaaaacaGGPaGaey4kaSIaaG % ymaiaaikdacaaI4aaabaGaaGjbVlaaysW7caaMe8UaaGjbVlaaysW7 % caaMe8UaaGjbVlaaysW7caaMe8Uaeyypa0JaaGymaiaaikdacaaI4a % Gaci4CaiaacMgacaGGUbGaaiikaiaacIcadaWcaaqaaiaadIhaaeaa % caaI1aGaaGymaiaaikdaaaGaey4kaSYaaSaaaeaacaaIXaaabaGaaG % OmaaaacaGGPaGaeqiWdaNaaiykaiabgUcaRiaaigdacaaIYaGaaGio % aaqaaiaaysW7caaMe8UaaGjbVlaaysW7caaMe8UaaGjbVlaaysW7ca % aMe8UaaGjbVlabg2da9iaaigdacaaIYaGaaGioaiGacohacaGGPbGa % aiOBaiaacIcacaGGOaWaaSaaaeaacaWG4bGaey4kaSIaaGOmaiaaiw % dacaaI2aaabaGaaGynaiaaigdacaaIYaaaaiaacMcacqaHapaCcaGG % PaGaey4kaSIaaGymaiaaikdacaaI4aaaaaa!9896! \begin{array}{l} g(x) = 128\sin (\frac{x}{{512}}\pi + \frac{\pi }{2}) + 128\\ \;\;\;\;\;\;\;\;\; = 128\sin ((\frac{x}{{512}} + \frac{1}{2})\pi ) + 128\\ \;\;\;\;\;\;\;\;\; = 128\sin ((\frac{{x + 256}}{{512}})\pi ) + 128 \end{array} g(x)=128sin(512xπ+2π)+128=128sin((512x+21)π)+128=128sin((512x+256)π)+128
其中绿色为f(x),紫色为调整相位后的g(x)。
即每次按下按键后相当于将图像向左平移256,那么也就是按下按键后,提前读取256个地址之后的数据。
module phase_ctrl(input clk,input rst_n,input f_phase,output [9:0] initiala_address);assign initiala_address = 10'd256;endmodulemodule addr_ctrl(input clk,input rst_n,input [31:0] freq_num,input [9:0] initiala_address,input f_phase,output [9:0] address);reg [31:0] cnt;always @(posedge clk,negedge rst_n)beginif(rst_n == 0)cnt <= 32'd0;else if(f_phase == 1)cnt[31:22] <= cnt[31:22] + initiala_address;elsecnt <= cnt + freq_num;end assign address = cnt[31:22];endmodule
验证:选取三个变频前后的点将其与理论计算的值进行对比
重点关注在f_phase拉高前后,正弦波上3个点**(address,data)**的大小
(43,161) (43+256,251)=(299,251)
(754,0) (754+256)=(1010,117)
(856,18) (856+256-1024,193)=(88,193)
理论计算:
(43,161)(43,251) (754,0)(754,117) (856,18) (856,193)
可以看到调相模块准确的完成了每次按键按下,相移PI/2的任务。
2、调幅
这一部分在代码方面比较简单,实际验证还需要数模转换和示波器的配合,限于条件无法达到,因此只展仿真结果。
在程序上要注意位宽的变化,由于不断的放大,因此将输出data设计为32位。
每次按键按下。幅值放大两倍。
module amplitude_ctrl(input clk,input rst_n,input f_ampli,input [7:0] data_in,output [31:0] data);reg [23:0] ampli_num;always @(posedge clk,negedge rst_n)beginif(rst_n == 0)ampli_num <= 24'd1;elseif(f_ampli == 1)ampli_num <= ampli_num * 24'd2;else ampli_num <= ampli_num;end assign data = ampli_num * data_in;endmodule
3、模块连接及总体功能验证
系统结构图为:
ModelSim仿真:
频率变化:
相位变化:
幅值变化:
测试代码:
`timescale 1ns/1nsmodule key_dds_tb();reg clk;reg rst_n;reg key_freq;reg key_phase;reg key_ampli;wire [31:0] data;key_dds key_dds_inst(.clk(clk),.rst_n (rst_n),.key_freq (key_freq),.key_phase(key_phase),.key_ampli(key_ampli),.data(data));initial clk = 1;always #10 clk = !clk;initialbeginrst_n = 0;key_freq = 1;key_phase = 1;key_ampli = 1;#200rst_n = 1;#200key_freq = 1;#10000000key_freq = 0;#2000key_freq = 1;#10000000key_freq = 0;#1000000key_freq = 1;#10000000key_phase = 1;#2000000key_phase = 0;#70000key_phase = 1;#11500key_phase = 0;#70000key_phase = 1;#25000key_phase = 0;#23333key_phase = 1;#1000000key_ampli = 1;#10000000key_ampli = 0;#2000key_ampli = 1;#1000000#10000$stop;endendmodule
备注:
之后有时间我想试着在屏幕上输出DDS产生的波形,看看效果。按键部分的功能是进行消陡然后输出一个同系统时钟的标志信号flag。作者:13tree
出处:/weixin_41890387
本文版权归作者所有,如需转载请保留此段声明。