深圳大学考试答题纸
(以论文、报告等形式考核专用)
二○ **~二○ ** 学年度第 1 学期
课程编号 1602080002 课程名称 硬件描述语言与逻辑综合 主讲教师 刘**
评分
学
号 20**16****
姓名 林**
专业年级
20**级电子一班
教师评语:
题目:
波形发生器设计
一.实验目的
通过 verilog语言编写程序,实现可变频率的任意波形的发生器的源代码,
并用 modelsim 软件进行仿真测试,从而加深学生对硬件语言的掌握与综合运用,
使学生将课堂所学的知识和实践有机结合起来,初步掌握计算机应用系统设计的
步骤和接口设计的方法,提高分析和解决实际问题的能力。
二.功能介绍与逻辑分析
本实验是完成一个可变频率的任意波形的发生器。在可变频率的功能上,我
扩展为一定范围内的任意频率,由于 DE2板上数码管数量的限制,故我在频率
范围上设为 1~99999Hz,占用了 5个数码管的显示(其余 3个数码管用于波形
的选择的显示 1个,占空比数值的显示 2个)。在任意波形输出上,我设有三种
基础波形,有正弦波,方波,三角波,其中方波有不同占空比的选择(占空比为
1/32到 31/32共 31种选择),而三角波也有不同斜率的选择(按三角波峰值的
位置也可分为 31种选择)。在波形选择上,采用一个波形选择键控制波形的转
换;在占空比数值的选择上,由于按键的数量有限,且占空比数值最大才 32,
故只采用一个数值加数键进行控制;在频率数值的选择上,由于数值是五位数,
故采用一个频率片选键和一个频率加数键实现频率的精准输入,为了知道片选位
都是哪一位,还加入了片选数码管的闪烁功能。
具体功能可以总结为:
1. 在 1~99999Hz的频率范围内可实现任意频率的输出。测试精确度为 2
位。
2. 可实现正弦波,任意占空比的方波,任意斜率的三角波的输出。
3. 通过 1个波形选择键控制波形的转换,通过 1个数值加数键实现占空比
数值的输入,通过一个频率片选键和一个频率加数键控制波形频率的输入。
4. 通过 1个数码管显示选择的波形类型(0为正弦波,1为方波,2为三角
波)通过 5个数码管显示选择频率,通过 2个数码管显示占空比数值。
5. 在调频模式下,片选位数码管具有闪烁功能。
流程原理与基本的逻辑关系如下图:
Start=0
frechoice 片
addfre加数
调频
模块
hz频率数值
频率信号产生模块
outhz频率信号
模 32计数器
频率数值显示模块
波形类型显示模块
wavechoos
e
波形选择位
Start=1
count地址位
正弦波产生模块
占空比数值显示模
块
num 占空比数值
波形输出模块
方波产生模块
Uout波形输出
num 占空比数值
三角波产生模块
三.程序代码与注释
/********************************顶层模块********************************/
module
wave(Uout,numoneout,numtenout,deconeout,dectenout,dechunout,decthouout,
dectenthouout,clk,decwaveout,wavechoice,addnum,frechoice,addfre,start);
output[7:0]Uout;
output[6:0]decwaveout;
output[6:0]
numoneout,numtenout,deconeout,dectenout,dechunout,decthouout,dectenthouout;
inputclk,start,wavechoice,addnum,frechoice,addfre;
wire[3:0]numone,numten,oneout,tenout,hunout,thouout,tenthouout;
wire[16:0]hz;
wire[4:0]num;
wire[1:0]wavechoose;
wiresecond,outhz;
wire[4:0]count;
wire[7:0]sinout,squareout,triangularout;
divider_1hzonehz(second,start,clk); //调用秒信号模块,用于应用于调频时数值的
闪烁
//产生所需频率的信号
//模 32计数
//占空比选择模块
dividerdiv(outhz,start,clk,hz);
countclockcount0(count,outhz,start);
changnum cn(num,numone,numten,addnum);
changeHzch(hz,oneout,tenout,hunout,thouout,tenthouout,frechoice,addfre,start,seco
nd);
//调频模块,频率可选范围 1Hz~99999Hz,精确位为前两位
sinsinwave(count,sinout);
squaresquarewave(count,squareout,num);
triangulartriangularwave(count,triangularout,num);//三角波产生模块
changewavecw(wavechoose,wavechoice,start); //波形选择数值
chooseOutchoosewave(Uout,wavechoose,sinout,squareout,triangularout);
//输出选择模块
//正弦波产生模块
//方波产生模块
decode4_7dwave(decwaveout,wavechoose); //数码管显示模块,0代表输出正弦
波,
//1代表输出方波,2代表输出三角波
decode4_7none(numoneout,numone); //数码管显示模块,显示占空比的个位
decode4_7nten(numtenout,numten);
//数码管显示模块,显示占空比的十位
decode4_7one(deconeout,oneout); //数码管显示模块,显示选择频率的个位
decode4_7ten(dectenout,tenout);
//数码管显示模块,显示选择频率的十位
decode4_7hun(dechunout,hunout); //数码管显示模块,显示选择频率的百位
decode4_7thou(decthouout,thouout);
//数码管显示模块,显示选择频率的千
decode4_7tenthou(dectenthouout,tenthouout);//数码管显示模块,显示选择频率的万
位
位
endmodule
/********************************顶层模块********************************/
/********************************调频模块********************************/
module
changeHz(hz,oneout,tenout,hunout,thouout,tenthouout,frechoice,addfre,start,second)
;
output[16:0]hz;//选择频率
outputreg[3:0]oneout,tenout,hunout,thouout,tenthouout;//频率数码管输出
inputfrechoice,addfre,start,second;//频率片选键,频率加数键,调频开启开关,秒信
号
reg[2:0]hzchoice;//片选位,0代表个位,1代表十位,以此类推,4代表万位
reg[3:0]one=0,ten=0,hun=0,thou=1,tenthou=0;//频率数值位,初始设为 1000Hz
assignhz=10000*tenthou+1000*thou+100*hun+10*ten+one;//输出频率整体数值
always@(posedgefrechoice)//当按下频率片选键
begin
if(start==1)hzchoice=0;//start=1时片选位置为 0,此时波形输出,无法调频
else
begin
//start=0时片选位加一,超过 4置回 0
if(hzchoice==4)hzchoice=0;
elsehzchoice=hzchoice+1;
end
end
always@(posedgeaddfre)//当按下频率加数键
begin
if(start==0)
begin
//如果 start=0,片选位代表的位数数值加 1,超过 9置为 0
if(hzchoice==0)
begin
if(one==9)one=0;
elseone=one+1;
end
if(hzchoice==1)
begin
if(ten==9)ten=0;
elseten=ten+1;
end
if(hzchoice==2)
begin
if(hun==9)hun=0;
elsehun=hun+1;
end
if(hzchoice==3)
begin
if(thou==9)thou=0;
elsethou=thou+1;
end
if(hzchoice==4)
begin
if(tenthou==9)tenthou=0;
elsetenthou=tenthou+1;
end
end
End
对
always
begin//start=0时,秒信号为 1则使片选位数码管输出暗状态,为 0输出对应数值,实
//现调频模式时的片选位的闪烁功能,start=1时,即波形输出模式时数码管显示
//应的频率
oneout=(hzchoice==0&second==1&start==0)?(4'd10):one;
tenout=(hzchoice==1&second==1&start==0)?(4'd10):ten;
hunout=(hzchoice==2&second==1&start==0)?(4'd10):hun;
thouout=(hzchoice==3&second==1&start==0)?(4'd10):thou;
tenthouout=(hzchoice==4&second==1&start==0)?(4'd10):tenthou;
end
endmodule
/********************************调频模块********************************/
/******************************波形选择按键******************************/
modulechangewave(wavechoose,wavechoice,start);
outputreg[1:0]wavechoose;//波形选择位,0代表输出正弦波,1代表输出方波
//2代表输出三角波
inputwavechoice,start;//波形选择键,波形输出开关
always@(posedgewavechoice)//当按下波形选择键
Begin
//波形选择位加 1,超过 2置为 0
if(wavechoose==2)wavechoose=0;
elsewavechoose=wavechoose+1;
end
endmodule
/******************************波形选择按键******************************/
/*****************************占空比选择按键*****************************/
modulechangnum(num,numone,numten,addnum);
outputreg[4:0]num=16;
//占 空 比 数 值 , 占 空 比 为 num/32, 初 始 设 为
16/32=50%
outputreg[3:0]numone,numten;//占空比数值的个位和十位,用于数码管输出
inputaddnum;
always@(posedgeaddnum) //按下加数键
Begin
//占空比数值加数键,
//num 加 1,超过 31则置为 1(num 不等于 0和 32)
if(num==31)num=1;
elsenum=num+1;
end
always
begin
numone=num%10;//分离出 num 的个位
numten=num/10;//分离 num 的十位
end
endmodule
/*****************************占空比选择按键*****************************/
/******************************计数时钟模块******************************/
modulecountclock(count,clk,start);
outputreg[4:0]count=0;//计数位
inputclk,start;//时钟信号(选择频率的 32倍,计数到 32所需刚好为选择频率的周期)
//波形输出开关
always@(posedgeclk)
begin
//当时钟信号上升沿
if(start==0)count=0; //关闭开关则计数位置 0
elseif(count==31)count=0;//开关打开则计数位加 1,超过 31则置 0
elsecount=count+1;
end
endmodule
/******************************计数时钟模块******************************/
/******************************输出波形选择******************************/
modulechooseOut(Uout,wavechoose,sinout,squareout,triangularout);
outputreg[7:0]Uout;
input[7:0]sinout,squareout,triangularout;//正弦波输出,方波输出,三角波输出
input[1:0]wavechoose;
//波形选择位
//输出波形
always
begin//波形选择位为 0,则输出正弦波,1则输出方波,2作为输出三角波
if(wavechoose==0)Uout=sinout;
elseif(wavechoose==1)Uout=squareout;
elseUout=triangularout;
end
endmodule
/******************************输出波形选择******************************/
/******************************正弦波数值表******************************/
modulesin(addr,data);
input[4:0]addr; //地址位,即计数数值
outputreg[7:0]data;//输出数据
always
case(addr)
0:data=120;
1:data=143;
2:data=166;
//查表输出
3:data=187;
4:data=205;
5:data=220;
6:data=231;
7:data=238;
8:data=240;
9:data=238;
10:data=231;
11:data=220;
12:data=205;
13:data=187;
14:data=166;
15:data=143;
16:data=120;
17:data=97;
18:data=74;
19:data=53;
20:data=35;
21:data=20;
22:data=9;
23:data=2;
24:data=0;
25:data=2;
26:data=9;
27:data=20;
28:data=35;
29:data=53;
30:data=74;
31:data=97;
default:data=8'hxx;
endcase
endmodule
/******************************正弦波数值表******************************/
/******************************方波数值计算******************************/
modulesquare(addr,data,num);
input[4:0]addr; //地址位,即计数数值
input[4:0]num; //占空比数值
outputreg[7:0]data;//输出数值
always
begin
//计数数值大于占空比数值则输出高电平,否则输出低电平
if(addr
endmodule
/******************************方波数值计算******************************/
/*****************************三角波数值计算*****************************/
moduletriangular(addr,data,num);
input[4:0]addr; //地址位,即计数数值
input[4:0]num; //占空比数值
outputreg[7:0]data;//输出数值
always
begin
//计数数值小于占空比数值时,输出数值则随 addr增长而线性增长
//大于占空比数值,输出数值则随 addr增长而从最大值线性减小
//从而实现任意斜率的三角波的输出
if(addr<=num)data=240*addr/num;
elsedata=240-(addr-num)*240/(32-num);
end
endmodule
/*****************************三角波数值计算*****************************/
/*******************************秒信号模块*******************************/
moduledivider_1hz(second,start,clk);
outputsecond;
inputstart,clk;
regsecond;
reg[25:0]count;
always@(posedgeclk)
begin
//开关打开时,即波形输出时关闭秒信号
if(start)
begin
count<=0;
second<=0;
end
elseif(count==13599999)//开关关闭时,即调频模式时提供闪烁功能需要的秒信
号
begin
count<=0;
second<=!second;
end
else
begin
count<=count+1;
end
end
endmodule
/*******************************秒信号模块*******************************/