赞
踩
设计一个能产生频率可变、相位可调的能产生正弦波、三角波、方波、锯齿波的信号发生器。
DDS 是直接数字式频率合成器(Direct Digital Synthesizer)的英文缩写,是一项关键的数字化技术。与传统的频率合成器相比,DDS 具有低成本、低功耗、高分辨率和快速转换时间等优点,广泛使用在电信与电子仪器领域,是实现设备全数字化的一个关键技术。作为设计人员,我们习惯称它为信号发生器,一般用它产生正弦、锯齿、方波等不同波形或不同频率的信号波形,在电子设计和测试中得到广泛应用。
注:图片摘自《FPGA Verliog开发实战指南》
图中主要包括相位累加器、相位调制器、波形存储器、数模转换器四大结构。
频率字K,数值大小控制输出信号的频率大小,数值越大输出信号频率越高,反之越小。
相位字P,数值大小控制输出信号的相位偏移,主要用于相位的信号调制。
相位累加器输入为频率字输入K表示相位增量,设其位宽为N,满足等式K=2^N*fout/fclk,其在输入相位累加器之前,在系统时钟同步下做数据寄存,数据改变时不会干扰相位累加器的正常工作。
波形数据表 ROM 中存有一个完整周期的正弦波信号。假设波形数据 ROM 的地址位宽为 12 位,存储数据位宽为 8 位,即 ROM 有 212 = 4096 个存储空间,每个存储空间可存储 1字节数据。将一个周期的正弦波信号,沿横轴等间隔采样 212 = 4096 次,每次采集的信号幅度用 1 字节数据表示,最大值为 255,最小值为 0。将 4096 次采样结果按顺序写入 ROM的 4096 个存储单元,一个完整周期正弦波的数字幅度信号写入了波形数据表 ROM 中。波形数据表 ROM 以相位调制器传入的相位码为 ROM 读地址,将地址对应存储单元中的电压幅值数字量输出。
D/A 转 换 器 将 输 入 的 电 压 幅 值 数 字 量 转 换 为 模 拟 量 输 出 , 就 得 到 输 出 信 号CLK_OUT。
输出信号 CLK_OUT 的信号频率 fOUT = K * fCLK / 2N。当 K = 1 时,可得 DDS 最小分辨率为:fOUT = fCLK / 2N,此时输出信号频率最低。根据采样定理,K 的最大值应小于 2N / 2。
相位累加器每计数 2N 次,对应一个正弦周期。而相位累加器 1 秒钟计数 fCLK次,在 k=1 时,DDS 输出的时钟频率就是频率分辨率。频率控制字 K 增加时,相位累加器溢出的频率增加,对应 DDS 输出信号 CLK_OUT 频率变为 K 倍的 DDS 频率分辨率。
DAC:自波形数据表 ROM 输出的波形数据传入 D/A 转换器转换为模拟信号。D/A 转换器即数/模转换器,简称 DAC(Digital to Analog Conver),是指将数字信号转换为模拟信号的电子元件或电路。
DAC使用外部挂载的高速AD/DA板卡。
首先使用matlab产生四种波形的mif文件,深度为4096*4,matlab代码见另一篇文章。
module key_ctrl( input wire clk, input wire rst_n, input wire [3:0]key, output reg [3:0]wave_select ); wire key0; wire key1; wire key2; wire key3; parameter sin_wave=4'b0001, //正弦波 squ_wave=4'b0010, //方波 tri_wave=4'b0100, //三角波 saw_wave=4'b1000; //锯齿波 key_filter key_filter0( .clk(clk), .rst_n(rst_n), .key_in(key[0]), .key_flag(key0) ); key_filter key_filter1( .clk(clk), .rst_n(rst_n), .key_in(key[1]), .key_flag(key1) ); key_filter key_filter2( .clk(clk), .rst_n(rst_n), .key_in(key[2]), .key_flag(key2) ); key_filter key_filter3( .clk(clk), .rst_n(rst_n), .key_in(key[3]), .key_flag(key3) ); always @(posedge clk or negedge rst_n) if(!rst_n) wave_select<=4'b0000; else if(key0) wave_select<=sin_wave; else if(key1) wave_select<=squ_wave; else if(key2) wave_select<=tri_wave; else if(key3) wave_select<=saw_wave; else wave_select<=wave_select; endmodule
按下四个按键分别生成四种波形
module key_filter #(parameter CNT_MAX=999_999) ( input wire clk, input wire rst_n, input wire key_in, output reg key_flag ); reg [19:0]cnt_20; always @(posedge clk or negedge rst_n) if(!rst_n) cnt_20<=1'b0; else if(key_in==1'b1) cnt_20<=1'b0; else if(cnt_20==CNT_MAX && key_in==1'b0) cnt_20<=cnt_20; else cnt_20<=cnt_20+1'b1; always @(posedge clk or negedge rst_n) if(!rst_n) key_flag<=1'b0; else if(cnt_20==CNT_MAX-1'b1) key_flag<=1'b1; else key_flag<=1'b0; endmodule
module dds( input wire clk, input wire rst_n, input wire [3:0]wave_select, output wire [7:0]data_out ); parameter sin_wave=4'b0001, //正弦波 squ_wave=4'b0010, //方波 tri_wave=4'b0100, //三角波 saw_wave=4'b1000; //锯齿波 //本实验,我们希望输出一个频率为 500Hz,初相位为π/2 的正弦波信号。 //计算参数 FREQ_CTRL,即频率输入字 K。 //FREQ_CTRL = K = 2N * fOUT / fCLK,其中 N = 32(相位累加器输出值 fre_add 的位宽)、 fOUT = 500Hz, //fCLK = 50MHz,带入公式,FREQ_CTRL = K = 42949.67296 ,取整数部分为42949; //PHASE_CTRL = P = / (2π / 2M),其中 M =12(输入 ROM 地址位宽)、 = π / 2,带入公式, //PHASE_CTRL = P = 1024。 //计算参数 PHASE_CTRL,即相位输入字 P。 parameter FREQ_CTRL=32'd42949,//相位累加器单次累加值, PHASE_CTRL=12'd1024;//相位偏移量 reg [31:0]fre_add; //相位累加器 reg [11:0]rom_addr_reg; //相位调制后的相位码 reg [13:0]rom_addr; //ROM读地址 //相位累加器 always @(posedge clk or negedge rst_n) if(!rst_n) fre_add<=1'b0; else fre_add<=fre_add+FREQ_CTRL; always @(posedge clk or negedge rst_n) if(!rst_n) begin rom_addr<=1'b0; rom_addr_reg<=1'b0; end else case(wave_select) sin_wave: begin rom_addr_reg<=fre_add[31:20]+PHASE_CTRL; rom_addr<=rom_addr_reg; end squ_wave: begin rom_addr_reg<=fre_add[31:20]+PHASE_CTRL; rom_addr<=rom_addr_reg+14'd4096; end tri_wave: begin rom_addr_reg<=fre_add[31:20]+PHASE_CTRL; rom_addr<=rom_addr_reg+14'd8192; end saw_wave: begin rom_addr_reg<=fre_add[31:20]+PHASE_CTRL; rom_addr<=rom_addr_reg+14'd12288; end default: begin rom_addr_reg<=fre_add[31:20]+PHASE_CTRL; rom_addr<=rom_addr_reg; end endcase wave_ip wave_ip0( .address(rom_addr), .clock(clk), .q(data_out) ); endmodule
module dds_top( input wire clk, input wire rst_n, input wire [3:0]key, output wire dac_clk, //输出DAC模块时钟 output wire [7:0]dac_data ); wire [3:0]wave_select; assign dac_clk=~clk; dds dds0( .clk(clk), .rst_n(rst_n), .wave_select(wave_select), .data_out(dac_data) ); key_ctrl key_ctrl0( .clk(clk), .rst_n(rst_n), .key(key), .wave_select(wave_select) ); endmodule
`timescale 1ns/1ns `define clk_period 20 module dds_top_tb; reg clk; reg rst_n; reg [3:0]key; wire dac_clk; //输出DAC模块时钟 wire [7:0]dac_data; reg [21:0]tb_cnt; reg key_in; reg [1:0]cnt_key; defparam dds_top_inst.key_ctrl0.key_filter0.CNT_MAX=24, dds_top_inst.key_ctrl0.key_filter1.CNT_MAX=24, dds_top_inst.key_ctrl0.key_filter2.CNT_MAX=24, dds_top_inst.key_ctrl0.key_filter3.CNT_MAX=24; parameter CNT_1MS = 20'd19000 , CNT_11MS = 21'd69000 , CNT_41MS = 22'd149000 , CNT_51MS = 22'd199000 , CNT_60MS = 22'd249000 ; dds_top dds_top_inst( .clk(clk), .rst_n(rst_n), .key(key), .dac_clk(dac_clk), //输出DAC模块时钟 .dac_data(dac_data) ); initial clk=1'b1; always #(`clk_period/2) clk=~clk; initial begin rst_n=1'b0; #(`clk_period*20+1); rst_n=1'b1; end //tb_cnt:按键过程计数器,通过该计数器的计数时间来模拟按键的抖动过程 always@(posedge clk or negedge rst_n) if(rst_n == 1'b0) tb_cnt <= 22'b0; else if(tb_cnt == CNT_60MS) tb_cnt <= 22'b0; else tb_cnt <= tb_cnt + 1'b1; //key_in:产生输入随机数,模拟按键的输入情况 always@(posedge clk or negedge rst_n) if(rst_n == 1'b0) key_in <= 1'b1; else if((tb_cnt >= CNT_1MS && tb_cnt <= CNT_11MS) || (tb_cnt >= CNT_41MS && tb_cnt <= CNT_51MS)) key_in <= {$random} % 2; else if(tb_cnt >= CNT_11MS && tb_cnt <= CNT_41MS) key_in <= 1'b0; else key_in <= 1'b1; always@(posedge clk or negedge rst_n) if(rst_n == 1'b0) cnt_key <= 2'd0; else if(tb_cnt == CNT_60MS) cnt_key <= cnt_key + 1'b1; else cnt_key <= cnt_key; always@(posedge clk or negedge rst_n) if(rst_n == 1'b0) key <= 4'b1111; else case(cnt_key) 0: key <= {3'b111,key_in}; 1: key <= {2'b11,key_in,1'b1}; 2: key <= {1'b1,key_in,2'b11}; 3: key <= {key_in,3'b111}; default:key <= 4'b1111; endcase endmodule
可以看到,第一部分波形为正弦波,第二部分为方波,第三部分为三角波,第四部分为锯齿波,设计成功。
可以通过dds代码中频率字与相位字的改变来实现更多的波形变化。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。