基于Verilog的DDS设计与显示综述.docx
《基于Verilog的DDS设计与显示综述.docx》由会员分享,可在线阅读,更多相关《基于Verilog的DDS设计与显示综述.docx(15页珍藏版)》请在冰豆网上搜索。
基于Verilog的DDS设计与显示综述
硬件描述语言课程设计
题目:
基于Verilog的DDS设计与显示
学院:
自动化工程学院
专业:
信号与信息处理
年级:
2012级
姓名:
黄山
2013年1月19日
1.设计要求
设计一个DDS信号发生器,能够产生三角波,要求频率、相位可调。
实现VGA显示波形和参数。
要求用DE2-70开发板完成。
设计要求:
一、DDS信号发生器设计要求:
(1)频率两档可调;
(2)峰峰值两档可调;
二、VGA波形和字符显示设计要求:
(1)用红色显示2个周期波形;
(2)在屏幕下方显示字符库。
2.设计原理及分析
一)DDS原理(以正弦信号为例)
对于正弦信号发生器,它的输出可以用下式来描述:
(1)
其中,SOUT是指该信号发生器的输出信号波形,fOUT指输出信号对应的频率。
上式的表述对于时间t是连续的,为了用数字逻辑实现该表达式,必须进行离散化处理,用基准时钟clk进行抽样,令正弦信号的相位θ为
(2)
在一个clk周期Tclk,相位的变化量为
(3)
为了对进行数字量化,把2π切割为2N由此,每份clk周期的相位增量用量化值
(4)
且为整数。
(5)
显然,信号发生器的输出可描述为:
(6)
其中θK-1指前一个clk周期的相位值,同样得出
(7)
由上面的推导可以看出,只要对相位的量化值进行简单的累加运算,就可以得到正弦信号的当前相位值,为用于累加的相位增量量化值决定了信号的输出频率fOUT,并呈现简单的线性关系。
直接数字合成器DDS就是根据上述原理而设计的数控频率合成器,主要由相位累加器、相位调制器、正弦ROM查找表、和DAC构成。
如图1中相位累加器、相位调制器、正弦ROM查找表是DDS结构中的数字部分,由于具有数控频率合成的功能,可称为NOC(NumericallyControlledOscillators)。
图1DDS信号发生器结构
二)VGA显示原理
常见的计算机显示器有CRT(CathodeRayTube,阴极射线管)显示器和液晶显示器,本次设计针对CRT显示。
CRT中的阴极射线枪发出电子束打在涂有荧光粉的荧光屏上,产生RGB三基色,合成一个彩色像素。
用逐行扫描的方式显示图像。
扫描从屏幕左上方开始,从左到右,从上到下,进行扫描。
每扫完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT对电子束进行消隐,每行结束时,用行同步信号进行行同步;扫描完所有行,用场同步信号进行场同步,并使扫描回到屏幕的左上方,同时进行场消隐,预备下一场的扫描。
图2扫描轨迹
其中蓝色–行正程,红色–行逆程;正程显示(实线),逆程消隐(虚线)
1.VGA显示标准
VGA标准共有5个信号:
R(红色)、G(绿色)、B(蓝色)、HS(行同步)、VS(场同步)
支持640*480分辨率
图3VGA显示标准(行)
表1行扫描时序
行扫描时序(单位:
像素,即输出一个像素的时间)
Ta
Tb
Tc
Td
Te
Tf
Tg
时间
96
40
8
640
8
8
800
图4VGA显示标准(场)
表2场扫描时序
场扫描时序(单位:
行,即输出一行的时间)
Ta
Tb
Tc
Td
Te
Tf
Tg
时间
2
25
8
480
8
2
525
VGA显示标准
时钟频率:
25.175MHz(输出像素的频率)
行频:
31469Hz
场频:
59.94Hz(每秒图像刷新频率,约60Hz)
2.时序处理
分别将场同步信号和行同步信号做时间近似处理
表3对行同步做近似处理
行扫描时序(单位:
us)
Ta
Tb
Tc
Td
Te
Tf
Tg
时间
3.8
1.6
0.3
25.4
0.3
0.3
前项之和
5.7us
26us
表4对场同步做近似处理
场扫描时序(单位:
行)
Ta
Tb
Tc
Td
Te
Tf
Tg
时间
2
25
8
480
8
2
525
作近似处理
2
忽略
480
忽略
482
这样,便可通过计数分频得到行同步信号和场同步信号。
下面以开发板的50Mhz时钟信号为例,得到32Khz的行同步信号和64hz的长同步信号
图5时序处理图
三)波形显示原理
要显示波形,需要将波形数据存入存储器(简称wave_RAM)。
wave_RAM中可以写入读出波形数据。
下面将以幅值为256的正弦波为例,阐明波形显示原理。
图6波形显示结构图
每个时钟沿到来,从存储器中读出一个数,通过判断x_cnt与addr的关系以及y_cnt与data的关系是否满足条件,控制屏幕上以x_cnt和y_cnt为坐标的像素点的颜色值。
其中,x_cnt与addr的关系以及y_cnt与data的关系如下图7所示。
图7波形显示像素位置与存储器地址之间关系
x_cnt与存储器地址对应;若高度等于数据值,则该处颜色为红色。
关键算法如下:
若在(m,n)处开始显示波形
当x_cnt=m时,addr=0
若y_cnt=n-data,则rgb=010;
当x_cnt=m+1时,addr=1
若y_cnt=n-data,则rgb=010;
……
当x_cnt=m+i时,addr=i
若y_cnt=n-data,则rgb=010;
四)字符显示原理
要显示字母、数字、符号、汉字等,需要自建字库(以后简称Char_ROM)。
Char_ROM中存放字模数据。
字模尺寸自行设定,例如英文字母、数字等可设置为16行*8列像素,汉字可设置为16行*16列像素。
图8字符库端口图
1.字模库设计
以16行*8列的字模1的设计及存储为例。
图9字模库设计举例
字库容量:
地址线与所有字符所占列数(决定于字符数量)有关,数据线与一个字符所占行数有关。
该例中数据线位数为16bit,地址为2bit。
2.字符显示思路:
1)确定屏幕显示起始位置,屏幕显示起始位置由行列计数值决定。
2)求Char_ROM地址
Char_ROM起始地址由所要显示的字符决定(可将地址用宏定义的方法与字符关联)。
3)读取该地址对应的数据
4)确定数据位和像素位置的关系
数据位和像素位置的关系由行计数值、起始行数、字符所占行数决定。
5)显示颜色,RGB赋值
若数据为1,则对应位置上的RGB赋值为字符色,否则RGB值赋值为背景色。
至此,DDS及VGA显示的原理介绍结束,下面开始进行系统设计及程序编写仿真。
三、系统设计实现
由于实验时间有限,在实际设计时并未对所生成波形做移相与改变幅值的处理,整体设计思路如下图10所示。
图10系统设计思路
一)参数设计
本次实验中所生成的正弦波共采样256个点,存储器采用8位地址线,数据为16bit。
设N为18位,M为地址线位数为8位,频率字=(000000010000000000)2,则当输入时钟为vga_clk=25Mhz时,由DDS原理部分公式可推知当输出DDS输出频率fOUT=100Khz。
由于显示屏幕大小为640*480,需要显示两个周期的波形共256*2=512个点,设置屏幕显示横向范围为50到561,纵向范围为100到300;字符显示范围为横向50到305,纵向310到325。
二)各模块实现程序及仿真结果
1.DDS模块
程序如下:
moduleDDS1(CLK,CTR,Q);
inputCLK;
inputCTR;
//input[17:
0]BK0;//频率设置字
//input[3:
0]A;//幅值设置字
//input[2:
0]BKI0;//初相位设置字
output[7:
0]Q;//DDS数字量输出
wire[17:
0]BK0;
wire[17:
0]BK1;
wire[17:
0]BK2;
wire[17:
0]BK3;
wire[7:
0]addr;
wire[7:
0]Q0;
wire[7:
0]Q1;
reg[7:
0]Q2;
assignBK0=17'b000000010000000000;
assignBKI2=BK2[17:
10];//取N位的高M位
DFF32DDF1(CLK,BK0,BK1);
ADDADD1(CLK,BK1,BK2,BK3);
DFF32DDF2(CLK,BK3,BK2);//相位累加器
ROM10ROM1(BKI2,CLK,Q0);//正弦ROM查找表
ROM10triROM2(BKI2,CLK,Q1);
always@(posedgeCLK)
if(CTR)Q2<=Q0;
elseQ2<=Q1;
assignQ=Q2;
endmodule
仿真结果如下图11所示
图11DDS模块仿真结果
2.vga显示模块
moduleddsvga(vga_clk,clk,hs,vs,blank_n,red,green,blue,sync_n);
inputclk;
outpuths,vs;
outputblank_n;
output[9:
0]red;
output[9:
0]green;
output[9:
0]blue;
outputsync_n;
outputvga_clk;
wirer,g,b;
wire[3:
1]grb;
wirevs,hs,sync_n_r;
wirefclk,cclk;
wireclk_div;
wire[7:
0]addr;
wire[7:
0]data;
wire[4:
0]addrchar;
wire[15:
0]datachar;
integeri;
reg[7:
0]addr1;
reg[4:
0]addr1char;
reghs1,vs1;
wire[8:
0]y_cnt;
reg[9:
0]xcc;
reg[5:
0]fs;
reg[4:
0]cc;//hangtongbu
reg[8:
0]ll;//changtongbu
reg[3:
1]grbp;
div_2div_2(clk,clk_div);
ROMsinROM(addr,clk,data);
//testchartestchar(addrchar,clk,datachar);
assignvga_clk=clk_div;
assigngrb[2]=(grbp[2])&hs1&vs1;
assigngrb[3]=(grbp[3])&hs1&vs1;
assigngrb[1]=(grbp[1])&hs1&vs1;
always