一.DDS的原理
直接數字頻率合成器(DDS),功能是通過輸入頻率輸入字從而實現改變輸出信號的頻率的功能,它所利用的原理就是雖然對於一段正弦信號來說其幅度值是非線性的,但是其相位的值卻是線性增加的,如下圖所示:DDS的核心公式便脫穎而出
公式中N代表的是頻率字輸入的位數,當位數越大的時候輸出的頻率的頻率分辨率便會越高,DDS的核心原理也如上圖所示:
二.ROM的設計實現
如果僅僅是為了設計方針可以通過$redmem來實現對某一文件的讀取,但是為了實現可以綜合的系統的設計我們采用如下的采用vivado自帶的IP內核來設計,其實實現的過程是非常簡單的,我們要完成的最主要的任務就是用vivado(我所使用的開發平台)完成ROM的IP核的配置工作,以及其他的工作即可,那么接下來我們來介紹一下ROM的配置:
首先第一步:(打來項目的IP catalog)
第二步,搜索block memory關鍵詞
第三步,設置ROM的一些參數,包括其中的存儲內容.coe文件以及其數據深度和數據寬度(數據深度指的是:最大可以存儲的數據個數,比如12位的數據深度就是可以存儲4096個數據。數據寬度指的是:存儲數據的位數,即存儲的幾位數據)
第四步,點擊確認生成器件,在器件生成后依舊可以對器件進行修改,我們可以通過以下操作來引用ROM模塊(右邊是在sourses的IP sources的)。
三..coe文件的生成
move=2^12; %先生成文件,和頭格式 fid = fopen('all.coe','w'); fprintf(fid,'MEMORY_INITIALIZATION_RADIX=10;\n'); fprintf(fid,'MEMORY_INITIALIZATION_VECTOR=\n'); %先寫入sin函數值地址0~4095 t=0:2*pi/2^12:2*pi; y=0.5*sin(t)+0.5; r=ceil(y*(2^8-1)); %將小數轉換為整數,ceil是向上取整。 for i = 1:1:2^12 fprintf(fid,'%d',r(i)); fprintf(fid,','); if i%15==0 fprintf(fid,'\n'); end end %下面寫入方波 t=1:1:2^12; y=(t<=2047); r=ceil(y*(2^8-1)); for i = 1:1:2^12 fprintf(fid,'%d',r(i)); fprintf(fid,','); if i%15==0 fprintf(fid,'\n'); end end %最后寫入三角波 t=1:1:2^12; y=[0.5:0.5/1024:1-0.5/1024, 1-0.5/1024:-0.5/1024:0, 0.5/1024:0.5/1024:0.5]; r=ceil(y*(2^8-1)); for i = 1:1:2^12 fprintf(fid,'%d',r(i)); if i==2^12 fprintf(fid,';'); else fprintf(fid,','); end if i%15==0 fprintf(fid,'\n'); end end fclose(fid);
以上是正弦波,方波以及三角波的形成matlab代碼
四.verilog代碼的編寫
module top#(parameter move=4096)( input [13:0]fw,// input clk,// input reset,// output [9:0]out ); reg [14:0]phase; reg [13:0] relat; wire [13:0] addr; always@(posedge clk or negedge reset) begin if(!reset) begin phase<=0; relat<=0; end else begin if((fw>=move)) begin if(fw>=2*move) relat=fw-2*move; else relat=fw-move; end else relat=fw; phase=((phase+relat)>12'd4095)?0:(phase+relat); end end assign addr=phase+(fw-relat); rom r(.clk(clk),.phase(addr),.out(out)); endmodule
在波形設置的窗口可以設置模擬數字波形,這里還要注意的一點是如果要顯示方波一定在模擬波形的設置里面的hold勾上,因為verilog默認是線性畫圖。