FPGA之DDS信号发生器

                                                           DDS信号发生器

     本文主要涉及以下几个问题

1:频率控制字如何得到

2:DDS的框图

3:用MATLAB得到正弦波的数字量化

4:设计代码

5:仿真代码

6:仿真图

首先将正弦波信号离散化,离散成多少位的根据自己的设计精度要求来定,但最高位一定是符号位,负数用补码来表示;然后用rom或者ram来存储离散后的数据;再由频率控制字的累加来给出地址用于读出ROM或者ram中的数据。

1:相位累加器的位宽设为n,fc/(2^n)称作频率分辨率,这是能分辨出的最小频率,提高相位累加器位宽可以调高频率分辨率。目标频率f=M*fc/2^n ,fc是采样频率,M是频率控制字,由此可以得到频率控制字。

       2:DDS框图其中输入到ram中的w是来自相位累加器的值作为ram的地址读取离散化的正弦波数据。

3:八位量化其中最高位是符号位,用MATLAB产生数据并生成mif文件

clc;
clear all;
N=2^8;
s_p=0:255;%正弦波一个周期的采样点数
sin_data=sin(2*pi*s_p/N);
%定点化
fix_p_sin_data=fix(sin_data*127);
for i=1:N
    if fix_p_sin_data(i)<0
        fix_p_sin_data(i)=N+fix_p_sin_data(i);%记住这里是负数用加号即可
    else
        fix_p_sin_data(i)=fix_p_sin_data(i);
    end
end
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:N
fprintf(fid,'%d:%d; \n',i-1,fix_p_sin_data(i));
end
fprintf(fid,'END; \n');
fclose(fid);

4:这里加上了1MH和10M正弦波的混合和上下变频其实就是两个波形相乘然后是积化和差的结果

module dds(
		input		sclk,
		input		rst_n,
		output	[7:0]	owave_1m,
		output	[7:0]	owave_10m,
		output	[15:0]	owave_mix,
		output	[7:0]	wave,
		output	[7:0]	wave_1a10
);
parameter	FRQ_W_1m=32'd85899346;
parameter	FRQ_W_10m=32'd858993460;

wire	[7:0]	addr_1m;
wire	[7:0]	addr_10m;	
reg		[7:0]	addr;
reg		[31:0]	phase_sum_1m;
reg		[31:0]	phase_sum_10m;
wire	[8:0]	oo;
assign	addr_1m = phase_sum_1m[31:24];
assign	addr_10m = phase_sum_10m[31:24];

assign oo={owave_1m[7],owave_1m} + {owave_10m[7],owave_10m};
assign	wave_1a10 = oo[8:1];
always @(posedge sclk or negedge rst_n)
	if(rst_n == 1'b0)
		addr <= 'd0;
	else 
		addr <= addr + 1'b1;

always @(posedge sclk or negedge rst_n)
		if(rst_n == 1'b0)
		 phase_sum_1m <= 'd0;
		 else
		 phase_sum_1m <= phase_sum_1m + FRQ_W_1m;
		 
always @(posedge sclk or negedge rst_n)
		if(rst_n == 1'b0)
			phase_sum_10m <= 'd0;
		else
			phase_sum_10m <= phase_sum_10m + FRQ_W_10m;
			
sp_ram_256x8	sp_ram_256x8_inst_1m (
	.address (addr_1m),
	.clock (sclk),
	.data (8'd0),
	.wren (1'b0),
	.q (owave_1m)
	);

sp_ram_256x8	sp_ram_256x8_inst_10m (
	.address (addr_10m),
	.clock (sclk),
	.data (8'd0),
	.wren (1'b0),
	.q (owave_10m)
	);
	
	sp_ram_256x8	sp_ram_256x8_inst (
	.address (addr),
	.clock (sclk),
	.data (8'd0),
	.wren (1'b0),
	.q (wave)
	);

mult_8x8	mult_8x8_inst (
	.dataa ( owave_1m),
	.datab (owave_10m),
	.result (owave_mix )
	);

endmodule

5:仿真代码

`timescale 1ns/1ns
module tb_dds;
reg		sclk;
reg		rst_n;
wire	[7:0]	owave_1m;
wire	[7:0]	owave_10m;
wire	[15:0]	owave_mix;
wire	[7:0]	wave;
initial	begin
	rst_n = 0;
	sclk = 0;
	#100
	rst_n = 1;
end


always #10 sclk = ~sclk;

dds dds_inst(
		.sclk		(sclk),
		.rst_n		(rst_n),
		.owave_1m	(owave_1m),
		.owave_10m	(owave_10m),
		.owave_mix	(owave_mix),
		.wave		(wave),
		.wave_1a10	()
);      

endmodule

6:仿真结果

猜你喜欢

转载自blog.csdn.net/qq_41754003/article/details/107444161