HDL-实验(3):DDS作业
来源:互联网 发布:pl sql scott登录不了 编辑:程序博客网 时间:2024/05/16 08:39
1.人工绘制的 电路结构RTL设计图
DDS 具体工作过程如下:每来一个时钟脉冲CLK,N位全加器将频率控制字FQWD与累加寄存器输出的累加相位数据N相加,把相加后的结果送至累加寄存器的输入端。累加寄存器一方面将上一时钟周期作用后所产生的新的数据反馈到加法器的输入端,以使加法器在下一时钟的作用下继续与频率控制数字相加;另一方面将这个值作为取样地址值送入幅度/相位转换电路,此电路根据取样地址输出相应的波形数据。最后经D/A 转换器和低通滤波器将波形数据转换成所需要的模拟波形。
DDS的工作原理:在本次实验中一共用了4个拨码开关SW[3..0],其中拨码开关SW[3]用于频率控制时能,SW[2..0]用于产生不同的频率控制字,根据输出频率公式:
2.Quartus扫描生成的电路RTL图
(1)generate_freq_word模块的RTL结构图:
(2)phase_accumulator模块的RTL结构图:
(3)DDS_CORE_ROM模块的RTL结构图:
3.相位累加器的输出,SignalTap截图
(1)当频率控制字:FQWD=10
此时一个完整的正弦波周期采样102个点,在50MHZ的晶振脉冲下,采样一个点的时间为0.02s,故当频率控制字为10时,输出正弦波的频率约为:
相位累加器的输出:
波表ROM的输入地址
输出正弦波的样值波形如下:
(2)当频率控制字:FQWD=20
此时一个完整的正弦波周期采样51个点,在50MHZ的晶振脉冲下,采样一个点的时间为0.02s,故当频率控制字为20时,输出正弦波的频率约为:
相位累加器的输出波表ROM的输入地址输出正弦波的样值波形如下:
####(3)当频率控制字:FQWD=60
此时一个完整的正弦波周期采样17个点,在50MHZ的晶振脉冲下,采样一个点的时间为0.02s,故当频率控制字为60时,输出正弦波的频率约为:
相位累加器的输出波表ROM的输入地址输出正弦波的样值波形如下:
6.Verilog代码
//***********************************************************************//生成频率控制字模块module generate_freq_word( CLK , // 时钟信号 FQIN,//用于生成频率字的输入信号 EN,//频率控制时能,高有效 CNT ); //输出值,即生成的频率字 input CLK;input [2:0] FQIN;input EN;output [31:0] CNT;reg [31:0] CNT;always @ (FQIN) begin if(EN) begin case(FQIN) 3'b001: CNT <= 32'd10;//用第1个拨码开关用于生成频率控制字10 3'b010: CNT <= 32'd20;//用第2个拨码开关用于生成频率控制字20 3'b100: CNT <= 32'd60;//用第3个拨码开关用于生成频率控制字60 endcase endendendmodule//***********************************************************************//相位累加器模块module phase_accumulator( CLK , //时钟信号 FQWD , // 输出频率控制字 FWEN ,//频率控制时能,高有效 CNTVAL ); // 累加值input CLK; input [31:0] FQWD; //频率字字长32位 input FWEN;output [9:0] CNTVAL; reg [9:0] CNTVAL;always @ (posedge CLK) begin if(FWEN) CNTVAL <= FQWD + CNTVAL; else CNTVAL <= CNTVAL;end endmodule
Matlab代码
说明:老师,由于Matlab基础较差,所以短时间内写出这段代码真的很有难度,所以借鉴了您的,但是一直在学习Matlab中,还希望您能谅解!
function gen_rom_rtl(rom_cfg, data_vec); rom_word_len = rom_cfg.rom_word_len ; rom_file_name = rom_cfg.rom_file_name ; rom_file_dir = rom_cfg.rom_file_dir ; description = rom_cfg.description ; data_vec_len = length(data_vec); addr_word_len = ceil(log2(data_vec_len)); % check input be integer value data_vec_fixed = fix(data_vec); diff_sum = sum(data_vec == data_vec_fixed); % all integer elements will cause the diff_sum be vector length if(diff_sum < data_vec_len) fprintf(1,'# ERROR, gen_rom_rtl(), input data_vec must be integer value\n'); return; end rom_file_dir_name = strcat(rom_file_dir, rom_file_name); data_vec_fixed_2c = data_vec_fixed + (2^rom_word_len) .* (data_vec_fixed < 0); romNum = 2^addr_word_len; data_str_cell = cell(data_vec_len, 1); for(idx = 1:data_vec_len) data_str_cell{idx} = Dec2BinStr(data_vec_fixed_2c(idx), rom_word_len); end % for(idx = 1:data_vec_len) if(romNum > data_vec_len) for(idx = data_vec_len+1:romNum) data_str_cell{idx} = Dec2BinStr(0, rom_word_len); end end fid_rom_file = fopen(rom_file_dir_name, 'w'); if(fid_rom_file == -1) errMsg = strcat('ERROR, gen_rom_rtl(), create file',rom_file_dir_name, ',failed'); fprintf(1, '%s\n', errMsg); return; end % rom data print % get rom module name rom_name = rom_file_name; len_rom_file_name = length(rom_file_name); if(rom_name(len_rom_file_name-1:len_rom_file_name) == '.v') rom_name(len_rom_file_name-1:len_rom_file_name) = []; else fprintf(1,'#WARNINIG, gen_rom_rtl(), rom_file_name may error, check it!\n'); end fprintf(fid_rom_file, ... '// ************************************************************** //\n'); fprintf(fid_rom_file, ... '// FILE : %s \n', rom_file_name); fprintf(fid_rom_file, ... '// DSCP : %s\n', description); fprintf(fid_rom_file, ... '// ABOUT : auto generated rom file by gen_rom_rtl.m\n'); fprintf(fid_rom_file, ... '// DATE : %s \n', datestr(now)); fprintf(fid_rom_file, ... '// ************************************************************** //\n'); % generate the crom module fprintf(fid_rom_file, ... '// module %s()\n', rom_name); fprintf(fid_rom_file, ... 'module %s(\n', rom_name); fprintf(fid_rom_file, ... ' CLK , // clock\n'); fprintf(fid_rom_file, ... ' RA , // read address\n'); fprintf(fid_rom_file, ... ' RD ); // read data\n'); fprintf(fid_rom_file, ... 'input CLK;\n'); fprintf(fid_rom_file, ... 'input [%-2d :0] RA;\n', addr_word_len-1); fprintf(fid_rom_file, ... 'output [%-2d :0] RD;\n', rom_word_len-1); fprintf(fid_rom_file, ... 'reg [%-2d :0] RD;\n', rom_word_len-1); fprintf(fid_rom_file, ... 'always @ (posedge CLK)\n'); fprintf(fid_rom_file, ... ' case(RA)\n'); for addr = 0:1:data_vec_len-1 fprintf(fid_rom_file, ... ' %-2d''d %-6d:RD = #1 %-2d''b %s; ', ... addr_word_len,addr, rom_word_len, data_str_cell{addr+1}); fprintf(fid_rom_file, ... '// %6d 0x%s \n', ... data_vec_fixed(addr+1), dec2hex(data_vec_fixed_2c(addr+1))); end fprintf(fid_rom_file, ... ' default : RD = #1 0;\n'); fprintf(fid_rom_file, ... ' endcase\n'); fprintf(fid_rom_file, ... 'endmodule \n'); fclose(fid_rom_file); fprintf(1,'# File: %s written\n', rom_file_dir_name);end % function gen_rom_rtl() % ////////////////////////////////////////////////////////////////////function str = Dec2BinStr(data, word_len) str = ''; for(idx = word_len-1:-1:0) bit_val = bitand(1, bitshift(data, -idx)); str = strcat(str, int2str(bit_val)); endend % function Dec2BinStr()
波表ROM代码
注:波表ROM代码是用matlab生成的
module DDS_CORE_ROM( CLK , // clock RA , // read address RD ); // read datainput CLK;input [9 :0] RA;output [11 :0] RD;reg [11 :0] RD;always @ (posedge CLK) case(RA) 10'd 0 :RD = #1 12'b 000000000000; // 0 0x0 10'd 1 :RD = #1 12'b 000000001100; // 12 0xC 10'd 2 :RD = #1 12'b 000000011001; // 25 0x19 10'd 3 :RD = #1 12'b 000000100101; // 37 0x25 10'd 4 :RD = #1 12'b 000000110010; // 50 0x32 ...... default : RD = #1 0; endcaseendmodule
7.Matlab 正弦波信号频谱分析
(1)当输出频率为500KHZ时
signal_tap_data_500KHZ.m文件
signal_out=[ 852 , 964 , 1073 , 1178 , 1279 , 1374 , 1465 , 1550 , 1629 , 1702 , 1768 , 1828 , 1881 , 1927 , ... ... ];
500KHZ频谱图matlab代码
clear;signal_tap_data_500KHZ;fs=50E6; %采样频率N=1024; %采样点数t=[0:1/fs:(N-1)/fs]; %采样时刻xlabel('Time (s)');ylabel('Magnitude(dB)');signal=transpose(signal_out); %矩阵转置 y=fft(signal,N);%对信号进行傅里叶变换yy=abs(y); %求得傅里叶变换后的振幅yy=yy/(N/2); %换算成实际的幅度figure(1);plot(t,signal);F=([1:N]-1)*fs/N; %换算成实际的频率值,Fn=(n-1)*Fs/Nfigure(2);stem(F(1:N/2),yy(1:N/2)); %显示换算后的FFT模值结果axis([0 5E6 0 2500]);title('幅度-频率曲线图');xlabel('Frequency (Hz)');ylabel('Magnitude');
500KHZ频谱图:
1MHZ频谱图:
3MHZ频谱图:
- HDL-实验(3):DDS作业
- Verilog HDL DDS设计(作业3)
- DDS作业(作业3)
- 作业3:DDS
- 作业3 DDS模块设计
- DDS作业
- DDS作业
- 2016秋季,DDS 作业
- 第三次作业DDS
- EDA实验DDS设计
- Verilog HDL计数器组合电路(作业2)
- Verilog HDL 定点数探索实验(加&乘)
- 作业 实验3
- c++实验3作业
- Verilog HDL作业1_1
- Verilog HDL作业1_2
- Verilog HDL 实验环境搭建
- Verilog HDL signed探索实验
- 校园导游咨询(图的应用)
- http协议2---GET方式和POST方式获取表单数据举例 1(非统一方式获取数据,比较麻烦)
- 水平垂直居中的几种写法
- 线段树练习2
- 郝斌数据结构 24 链表创建和链表遍历算法的演示
- HDL-实验(3):DDS作业
- c语言指针问题
- C#如何生成图种
- WEB、WEB标准、W3C的理解
- caffe--安装心得
- UVa11889 Benefit
- 记:STM32F205双USB开发做device
- 11个Java 开源 socket框架
- 算法Day2-三数之和