DDS作业(作业3)
- 手繪RTL圖
- 系統(tǒng)生成的RTL圖
最后一張RTL的圖片因?yàn)橛?2位的輸入,圖片比較大,只截取了一部分。 SignalTap抓取的波形
輸出波形頻率=K?時(shí)鐘頻率1024
500KHz波形
1MHz波形
3MHz波形
基本原理:一個(gè)周期內(nèi)有1024 個(gè)采樣點(diǎn),基本的時(shí)鐘周期為50MHz;為使輸出的波形頻率發(fā)生變化,可以改變輸出的間隔即每隔K個(gè)點(diǎn)輸出一個(gè)采樣數(shù)據(jù),此時(shí)輸出的波形頻率與K之間的關(guān)系為:
當(dāng)輸出的頻率為500KHz時(shí),計(jì)算的K≈10,以此為基準(zhǔn)1MHz的輸出K=20,3MHz的輸出,K=60。代碼塊
VerilogHDL代碼
生成ROM表的MatLab程序是使用杜大大的程序:
function generate_DDS_rom() clc; close all; disp('# generate_DDS_rom() Running~');%%/// % set your rom config here rom_word_len = 12; % rom data word length in bit rom_addr_len = 10; % rom address word length in bit rom_file_name = 'DDS_CORE_ROM.v'; % rom file name rom_file_dir = './'; % rom file dir path description = 'DDS CORE ROM FILE' ;% rom description %%///rom_vec_len = 2^rom_addr_len; %2^10=1024 index = (0:rom_vec_len-1) ; %0~1023 rom_data_vec_float = sin(2*pi*index/rom_vec_len); %最大值為1的1024點(diǎn)正弦波 figure; plot(rom_data_vec_float); % for debug rom_data_vec_int = fix(rom_data_vec_float * (2^(rom_word_len-1) - 1)); %最大值為2047,為了保證最高位為符號(hào)位 figure; plot(rom_data_vec_int); % for debugrom_cfg.rom_word_len = rom_word_len ; rom_cfg.rom_file_name = rom_file_name ; rom_cfg.rom_file_dir = rom_file_dir ; rom_cfg.description = description ; gen_rom_rtl(rom_cfg, rom_data_vec_int);end % generate_DDS_rom()% /// % gen_rom_rtl() % generate synthesizable rom hdl code(need synthesizer support). % /// % INPUT: % data vector, must be integer value % rom word len % rom file dir string % rom file name string % OUTPUT: % verilog format rom file, all data in 2's complement code format 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 valuedata_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;endrom_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); endendfid_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 namerom_name = rom_file_name;len_rom_file_name = length(rom_file_name);if(strcmp(rom_name(len_rom_file_name-1:len_rom_file_name), '.v'))rom_name(len_rom_file_name-1:len_rom_file_name) = [];elsefprintf(1,'#WARNINIG, gen_rom_rtl(), rom_file_name may error, check it!\n');endfprintf(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 modulefprintf(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-1fprintf(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)));endfprintf(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));end end % function Dec2BinStr()- DDS輸出的圖像的頻域分析
500k波形時(shí)域圖
500k波形的頻域分析
1M波形的時(shí)域圖
1M波形的頻域分析
3M波形的時(shí)域圖
3M波形的頻域圖
用分析500k波形的MATLAB代碼作為示例:
signal = transpose(VarName6) / 2048; %數(shù)據(jù)歸一化處理 CLK = 50 * 1000000; N = 512; t=[0:1/CLK:(N-1)/CLK]; %持續(xù)時(shí)間 figure(1);plot(t,signal); xlabel('時(shí)間(s)');ylabel('value'); title('時(shí)域圖');%繪制時(shí)域圖形 Y = fft(signal,N); %FFT變換 size = abs(Y); %取模 size=size/(N/2); %換算成實(shí)際的幅度 figure(2); stem(F(1:N/2),size(1:N/2)); %fft頻域圖 axis([0 5E6 0 1.5]); title('頻譜圖'); xlabel('頻率(Hz)');ylabel('幅度');將signal tap中的數(shù)據(jù)導(dǎo)入到MATLAB中分析的注意事項(xiàng):
- 導(dǎo)出signal tap 中的數(shù)據(jù)有TXT和CSV兩種文本格式,但是CSV的數(shù)據(jù)格式是帶符號(hào)的二進(jìn)制數(shù)據(jù),用MATLAB分析需要先將其轉(zhuǎn)換為十進(jìn)制在分析。這個(gè)過程較為麻煩,TXT文本的數(shù)據(jù)是十進(jìn)制可以用MATLAB的import data直接導(dǎo)入。
- 用TXT導(dǎo)入數(shù)據(jù)時(shí),數(shù)據(jù)會(huì)被截?cái)嘈枰喜ⅰ?
- 導(dǎo)入的數(shù)據(jù)要注意是文本格式還是Number。
總結(jié)
以上是生活随笔為你收集整理的DDS作业(作业3)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样才算是好程序员?关于好程序员与好代码
- 下一篇: 实验02-微信公众号编辑模式应用