博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
FPGA之DDS信号发生器
阅读量:3914 次
发布时间:2019-05-23

本文共 2683 字,大约阅读时间需要 8 分钟。

                                                           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);    endendfid=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));endfprintf(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/1nsmodule 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;endalways #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:仿真结果

 

转载地址:http://ixbrn.baihongyu.com/

你可能感兴趣的文章
一位10年Java工作经验的架构师聊Java和工作经验
查看>>
Java架构师学习路线
查看>>
号称精通Java的你,是否真的名副其实
查看>>
你可以把编程当做一项托付终身的职业
查看>>
细思极恐——你真的会写Java吗?
查看>>
Java并发面试,幸亏有点道行,不然又被忽悠了
查看>>
Java基础面试题收集整理
查看>>
SpringBoot基础篇Bean之条件注入@Condition使用姿势
查看>>
让你秒懂线程和线程安全,只需5步!
查看>>
Spring Boot学习之Logback和Log4j2集成与日志发展史
查看>>
Java注解(annotation)机制
查看>>
volatile关键字全面解析
查看>>
Java如何实现哈夫曼编码
查看>>
从源代码的角度理解Java设计模式的装饰模式
查看>>
系统架构中为什么要引入消息中间件?
查看>>
Java内存模型详解
查看>>
Java NIO之Selector
查看>>
SLF4J源码解析(一)
查看>>
Spring AOP用法详解
查看>>
记一位朋友斩获BAT技术专家Offer的面试经历
查看>>