日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Xilinx-Verilog-学习笔记(19):正弦波信号发生器与DDS

發布時間:2024/3/12 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Xilinx-Verilog-学习笔记(19):正弦波信号发生器与DDS 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Xilinx-Verilog-學習筆記(19):正弦波信號發生器與DDS

一、正弦波信號發生器

1、浮點數的定點化

這里以2.918為例,實現浮點數向定點數的轉換:

(1)在進行浮點轉定點之前,要先確定整數部分位寬小數部分位寬。3位整數位寬,12位的小數位寬,最高位的符號位1位。
(2)15位寬的數能夠表示的數值范圍為-32768到32767。整數部分3位寬的數最大能表示到8,因此最大精度為8/32767=0.000244140625。
(3)2.918進行定點化的過程為2.918/(8/32768)=11952.128~=11952這個值就是定點后的2.918的值。而最后的0.128就是定點化會帶來量化誤差。

2、用matlab生成正弦波并進行量化處理

量化處理
量化在數字信號處理領域,是指將信號的連續取值(或者大量可能的離散取值)近似為有限多個(或較少的)離散值的過程。

正弦波量化思想
本實驗通過256個位寬為8的數據對正弦信號進行采樣,以對一個周期的正弦信號進行量化處理。每個數據位寬為8,相當于把正弦信號的幅度從-1到1進行256份等間隔劃分;采樣點數為256個,相當于對一個正弦周期等間隔地采樣了256個點。

量化后的數據由256個介于-1到1之間的數構成,之后將浮點型的數值進行定點化的轉換,使其為0~256之間的整數。(具體處理方法見代碼)

MatLab代碼:

clc; clear all; N=2^8; s_p=0:255;%正弦波一個周期的采樣點數 sin_data=sin(2*pi*s_p/N);%256個介于-1到1之間的數%打印我們的波形 % plot(sin_data,'r*'); % hold on; % plot(sin_data);%定點化 fix_p_sin_data=fix(sin_data*127);%256個介于-128到127之間的數 for i=1:Nif fix_p_sin_data(i)<0fix_p_sin_data(i)=N+fix_p_sin_data(i);%將負數搬到128到256之間(用255加即可)elsefix_p_sin_data(i)=fix_p_sin_data(i);%整數不用管end end%以下是生成mif文件,用于RAM的初始化 fid=fopen('sp_ram_256x8.mif','w+'); fprintf(fid,'WIDTH=8;\n'); fprintf(fid,'DEPTH=256;\n'); fprintf(fid,'ADDRESS_RADIX=UNS;\n'); fprintf(fid,'DATA_RADIX=UNS;\n'); fprintf(fid,'CONTENT BEGIN \n'); for i=1:Nfprintf(fid,'%d:%d; \n',i-1,fix_p_sin_data(i)); end fprintf(fid,'END; \n'); fclose(fid);

通過sin_data=sin(2 * pi * s_p/N); 即可實現對一個正弦周期的量化。

3、design文件

module ex_dds(input wire sclk,input wire rst_n,output wire [7:0] o_wave );reg [7:0] addr;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)addr <= 'd0;else addr <= addr + 1'b1;sp_ram_256x8 sp_ram_256x8_inst (.address ( addr ),.clock ( sclk ),.data ( 8'd0 ),.wren ( 1'b0 ),.q ( o_wave )); endmodule

其中例化的深度256,位寬為8的RAM是直接調用IP核產生的。

4、testbench文件

`timescale 1ns/1ns module tb_ex_dds; reg sclk,rst_n; wire [7:0] o_wave; initial beginsclk =0;rst_n=0;#100 rst_n =1; endalways #10 sclk =~sclk;//50Mhzex_dds ex_dds_inst(.sclk (sclk),.rst_n (rst_n),.o_wave (o_wave) );endmodule

5、仿真波形

將RAM輸出的數值用模擬波形表示出來,可以看出是正弦信號。對于地址是鋸齒波,因為是從0到255然后再到0。

二、DDS直接頻率合成器

1、基本原理

  • fc為每秒鐘累加多少次,2^n為累加器能夠累加到的最大范圍,所以fc/2 ^n為每秒鐘累加器會溢出多少次,即為周期(分辨率)。提高相位累加器的位寬n可以調高頻率分辨率。
  • 存儲正弦的RAM深度或者叫正弦波一個周期量化的點數,量化的點數越多生成的正弦波相位噪聲低。
  • M是控制字,通過頻率控制字來產生不同的頻率。

這里相位累加寄存器的位寬為32,目標實現1Mhz的信號:

(1)控制字設置:1e6=M * 50e6/2^32,則M=1e6 * 2^32/50e6~=85899345.
(2)相位累加器為32位,而最終輸出為8位,為了取整數倍,因此取相位累加器的高8位。


可以得到1Mhz的正弦周期。因此,通過修改M的值可以調節正弦信號的頻率。

于是我們可以設計過一段時間將M的值增大一定值,即可實現頻率的連續變換:

2、design文件

module ex_dds(input wire sclk,input wire rst_n,output wire [7:0] o_wave );parameter FRQ_W=32'd85899346; //相當于M parameter FRQ_ADD=32'd85899346/2; //相當于遞增量 reg [31:0] phase_sum; wire [7:0] addr; reg [31:0] frq_word; reg [6:0] div_cnt; reg div_flag;//記100個時鐘周期,M的值遞增一次 always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)div_cnt <= 1'b0;else if(div_cnt == 7'd99)div_cnt <= 1'b0;else div_cnt <= div_cnt + 1'b1;always @(posedge sclk or negedge rst_n) if(rst_n == 1'b0)div_flag <= 1'b0;else if(div_cnt == 7'd99)div_flag <= 1'b1;elsediv_flag <= 1'b0;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)frq_word <= FRQ_W;else if(div_flag == 1'b1)frq_word <= frq_word + FRQ_ADD;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)phase_sum <= 'd0;else phase_sum <= phase_sum + frq_word;assign addr = phase_sum[31:24];/* always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)addr <= 'd0;else addr <= addr + 1'b1; */sp_ram_256x8 sp_ram_256x8_inst (.address ( addr ),.clock ( sclk ),.data ( 8'd0 ),.wren ( 1'b0 ),.q ( o_wave )); endmodule

此時通過計數器,實現100個時鐘周期變頻一次。
如果用于高速電路的話,不要直接用分頻器作為標志,可以通過定義一個div_flag作為標志。

3、仿真波形


從波形可以看出,隨著M的逐漸增大,時鐘頻率也越來越高。

三、混頻器

混頻器的主要任務是將兩個不同頻率的信號進行疊加。

1、MatLab代碼

(1)首先定義好采樣率,兩個時鐘的頻率,從圖中可以看出,紅色的時鐘頻率是藍色的5倍。

(2)然后是混頻,混頻后的到的信號包含兩個頻率分量,一個是f1+f2,一個是f1-f2,即一個6Mhz,一個4Mhz。從時域信號中我們難以看出結果是否正確,因此需要對其進行FFT變換,從頻域分析。

前1024個點表示正頻域,后1024個點表示復頻域,因此只需要看前1024個即可。

頻率分辨率與FFT計算的點數N、采樣頻率fs都有關。頻率分辨率=fs/N
50M/2048=0.0244Mhz,這是FFT中能夠分辨出的最低的頻率,用0.0244*1024=25Mhz,正好是50Mhz采樣頻率能夠識別出來的頻率。

兩個峰的點分別是165和247,0.0244 *165=4Mhz,0.0244 * 247=6Mhz,正好是混頻后的兩個頻率分量。

clc; clear all; fs=50e6; %50Mhz采樣率 f1=1e6; %1Mhz頻率 f2=5e6; %5Mhz頻率 n=0:2047; s_1=sin(2*pi*n*f1/fs); s_2=sin(2*pi*n*f2/fs);%s_1和s_2混頻,就是相乘 s_12=s_1.*s_2; %混頻后包含兩個頻率分量,一個是f1+f2一個是f1-f2 %頻域分析 fft_out=fft(s_12,2048); fft_abs=abs(fft_out);

2、design文件

本實驗設計1Khz的正弦信號和10Khz的正弦信號進行混頻。
通過計算:
(1)1Khz:M=1000 * 2^32/50e6=85899
(2)10Khz:M=10000 * 2^32/50e6=858993

module ex_dds(input wire sclk,//50Mhzinput wire rst_n,output wire [15:0] o_wave ); parameter FRQ_W_1k=32'd85899; parameter FRQ_W_10k=32'd858993;reg [31:0] phase_sum_1k,phase_sum_10k; wire [7:0] addr_1k,addr_10k; wire [7:0] o_wave_1k; wire [7:0] o_wave_10k; // reg [22:0] sum; reg [14:0] sum_cnt; reg sum_flag; reg [22:0] sum_r;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)sum_cnt <= 'd0;else if(sum_cnt == 'd29999)sum_cnt <='d0;else sum_cnt <= sum_cnt + 1'b1;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)sum_flag<= 1'b0;else if(sum_cnt == 'd29999)sum_flag <= 1'b1;else sum_flag <= 1'b0;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)sum <= 'd0;else if(sum_flag == 1'b1)sum <= {{15{o_wave_1k[7]}},o_wave_1k};elsesum <= sum + {{15{o_wave_1k[7]}},o_wave_1k};always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)sum_r <= 'd0;else if(sum_flag == 1'b1)sum_r <= sum;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)phase_sum_1k<='d0;else phase_sum_1k <= phase_sum_1k + FRQ_W_1k ;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)phase_sum_10k<='d0;else phase_sum_10k <= phase_sum_10k + FRQ_W_10k ;assign addr_1k=phase_sum_1k[31:24];assign addr_10k=phase_sum_10k[31:24];//混頻器 mult_8x8_l0 mult_8x8_l0_inst (.dataa ( o_wave_1k ),.datab ( o_wave_10k ),.result ( o_wave ));sp_ram_256x8 sp_ram_256x8_inst (.address ( addr_1k ),.clock ( sclk ),.data ( 8'd0 ),.wren ( 1'b0 ),.q ( o_wave_1k ));sp_ram_256x8 sp_ram_256x8_inst_1 (.address ( addr_10k ),.clock ( sclk ),.data ( 8'd0 ),.wren ( 1'b0 ),.q ( o_wave_10k )); endmodule

該模塊中通過例化兩個RAM來生成兩個正弦波形,通過例化一個乘法器來實現兩個正弦信號的混頻。

3、testbench文件

`timescale 1ns/1ns module tb_ex_dds; reg sclk,rst_n; wire [15:0] o_wave; initial beginsclk =0;rst_n=0;#100 rst_n =1; endalways #10 sclk =~sclk;//50Mhzex_dds ex_dds_inst(.sclk (sclk),.rst_n (rst_n),.o_wave (o_wave) );endmodule

4、仿真波形


從波形中可以看出,下面兩個不同頻率的正弦信號進行混頻后,生成了含兩個頻率分量的信號o_wave。

總結

以上是生活随笔為你收集整理的Xilinx-Verilog-学习笔记(19):正弦波信号发生器与DDS的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。