数字频率合成器 - 图文 下载本文

武汉科技大学中南分校2008届毕业设计(论文)

fp clk1clkinst图3.1 分频器

模块程序:

module fp(clk1,clk); input clk1; output clk; reg clk; reg [7:0] i;

always @(posedge clk1) begin i=i+1;

if(i==8'd122)

begin clk<=clk+1;i<=0; end

end endmodule

§3.2相位累加器

它由一个加法器和一个位相位寄存器组成,每来一个时钟,相位寄存器以步

fclkfclkf??K长增加,设计要求频率步进为10Hz,根据 ,得:=10,因要求输outNN22出频率范围为10Hz~10kHz,则1?k?1000。由于基准频率

f0?160KHz, 则有

2N=fclk/10≈20000,取N=11,当K=1000时,在正弦波一个周期内基本上可以取16点,即可达到无失真要求。相位累加器图如图 3.2所示:

第7页 共20页

xx:<数字频率合成器>

addclkk[9..0]db[11..0]ph[13..0]inst1 图3.2 相位累加器

输入端分别是160KHZ的基准频率和频率控制字K,输出端是:12位的地址和14位的相位,之所以选择2个输出是因为在波形ROM中只存储了1/4的波形,为了能最后的波形合成所以需要输出相位。 模块程序:

module add(clk,db,ph,k); input clk; input [9:0] k; output [13:0] ph; output [11:0] db; reg [13:0] ph; reg [11:0] db;

always @(posedge clk) begin ph<=ph+k; db<=db+k; end endmodule

§3.3波形转换

相位累加器输出的地址是0-T/4的之间循环的,因此必须把相位累加器输出地址根据相位将其转换成0-1/2周期的波形,使之正弦波的半波。具体操作是:将0-T/4内波形关于T/4处对称,通过编程实现后生成元件如图3.3所示

第8页 共20页

武汉科技大学中南分校2008届毕业设计(论文)

zhph[13..0]db[11..0]clkq[11..0]inst2图3.3 相位控制模块

模块程序:

module zh (ph,db,clk,q); input clk; input[13:0] ph; input[11:0] db; output[11:0] q; reg[11:0] q;

always@(posedge clk) begin

if(ph<4096) q<=db;

else if(ph>4095&&ph<8192) q<=4096-db; else if(ph>8191&&ph<12288) q<=db; else if(ph>12287) q=4096-db; end endmodule

§3.4波形ROM

波形ROM的模块图如图3.4所示。波形存储器中的数值是按照一定顺序存储的波形幅值,我们通过输入的地址有顺序的将这些值读出就可以得到我们所需要的波形的离散波形。,理论上通过这个技术可以得到我们所需要的任何波形,但在该技术中一个关键点就是ROM的大小,设计人员要做的就是要在还原波形的前提下最大的节省存储波形所占用的ROM。

第9页 共20页

xx:<数字频率合成器>

在本系统中将相位累加器输出的数据作为波形存储器的取样地址,进行波形的相位/幅度转换,即可在给定时间上确定输出波形的抽样幅值。N位的寻址ROM相当于把0°~360°的正弦信号离散成具有2N个样值序列。本设计波形ROM使用

214个存储单元存储1/4个周期的波形这样节省了3/4的存储空间。其中214个样值的幅度以8位二进制数值存在ROM中,所取的地址不同,输出对应正弦信号的幅度。这些8位的幅值数据的的范围是从127到255的,既是在0到127的范围上整体提高127,原因是D/A转化器要求输出是正值,所以将波形的整体向上抬高了A/2(A为正弦波的)。

波形存储器(ROM)通过调用rom元件实现,其rom的值rom.mif是一个存放波形幅值的文件

romaddress[11..0]8 bits4096 wordsq[7..0]clockinst4Block type: AUTO图3.4 波形ROM

波形数据文件是通过MATLAB编程生成MIF文件,再将该文件导入到Quartus

II 8.0中即可生成存储了所需要波形的ROM。MATLAB程序如下:

程序:

function data=makedata index = linspace(0,2*pi,2^12); sin_value = sin(index);

sin_value = sin_value * (2^11 -1 ); sin_value = fix(sin_value); sin_value =abs(sin_value); for i=1:1024

sin_value(i)=sin_value(i)+512;

第10页 共20页