基于FPGA的波形发生器.docx
- 文档编号:10236471
- 上传时间:2023-02-09
- 格式:DOCX
- 页数:28
- 大小:471.96KB
基于FPGA的波形发生器.docx
《基于FPGA的波形发生器.docx》由会员分享,可在线阅读,更多相关《基于FPGA的波形发生器.docx(28页珍藏版)》请在冰豆网上搜索。
基于FPGA的波形发生器
课程设计报告
目:
波形发生器
日期:
2015年1月19日
课程设计目的
1)巩固和加深所学电子技术课程的基本知识,提高综合运用所
学知识的能力;
2)培养学生根据课题需要选用参考书、查阅手册、图表和文献资料的能力,提咼学生独立解决工程实际问题的能力
3)通过设计方案的分析比较、设计计算、元件选绎及电路安装调试等环节.初步掌握单实用电路的工程设计方法.
4)提高学生的动手能力.掌握常用仪器设备的正确使用方法,学会对简单实用电路的实验调试和对整机指标的测试方法,
5)了解与课题有关的电路以及元器件的工程技术规范,能按课程设计任务书的要求编写设计说明书,能正确反映设计和实验成果,能正确绘制电路固等.
二、设计任务与要求
)任务:
•数码管显示学号
•设计基于FPGA波形发生器
二)设计要求:
1.显示学号
a•用四位数码管显示
b.循环显示同组2人的学号后四位
2.根据按键输入产生波形
a)根据标准键盘输入不同,分别输出正弦波、方波、三角
波(频率=1KHz)
b)根据标准键盘改变频率(频率变化范围:
1KHz-10KHz,每
次频率变化1KHz)
c)输出频率在数码管上显示
三、方案设计与论证
首先是对设计要求的分析,然后说明本次课程设计采用的方
案,并给出总体设计方框原理图。
(1)对设计要求的总体分析:
电路总体由四个模块组成:
键盘模块:
实现对按键信号输入及处理,生成频率控制字与波形控制
字
数码管显示:
将频率控制字输入进行显示
波形发生模块:
对于要求的三种波形建立ROM阵列储存点列数据,
建立i2c协议定义,控制字输入实现波形筛选与控制
波形选择模块:
根据输入选择波形种类的输出
(2)实现方案:
实验一:
学号循环显示
设计思想:
对系统50MHz的时钟信号进行分频,由时钟得到一个num值,通过对num值0或1的判断来选择显示不同的学号,从而使学号得以循环。
实验二:
波形发生器
设计过程由上而下,先建立各个模块之间的联系,然后针对各自模块功能进行内部编程。
再对出现的问题进行修改。
我们的核心模块是波形发生模块,首先将三种波形发生器分别得
到,通过内部12c协议使得波形在示波器上得以实现;
键盘模块负责提供控制信号,编写内部程序,使得按键动作作为
信号输出;输出的控制字在波形发生模块中根据代码进行筛选及其控制
数码管显示:
仅仅将键盘输出的频率字进行码制转换即可。
波形选择过程:
由键盘输入值来定义一个数值,根据其值不同,输出波形不同。
总体电路的RTL视图
四、单元电路设计与参数计算
学号的循环显示模块•选择elk频率为50Mhz,周期20ns。
•上升沿翻转,ent=ent+1,经实验尝试,ent计满需要的次数取225。
因此其周期为225x20ns。
•当ent计满时,定义num为变量,通过复位信号实现num的取值为0或1。
•给num取0或1时(使用ease语句)分别赋予两个人的学号,从而使学号得以循环。
波形发生器部分:
1)键盘模块
键盘包括数据线、时钟线、vcc和gnd,采用第二套扫描码,按键按下时,键盘将相应的通码数据发送到FPGA,根据第二套扫描码集可以确定哪个键被按下。
clkl>ps2k_clkrps2k_dataI>
rstr>
2)数码管输出模块
用parameter定义字符数据,使用always@()定义敏感变量,当时钟序列的上升沿到来时,触发case函数,从而选择正确的数值进输出。
seg:
U5
otjeg_ifrq
n館卩一1]命g_z卩一q
3)
^^>seg_0[7..0]
p.0]
<>;eq_2r..Ol
<~^seq_3T7..Ol
波形发生器和波形选择模块
Wave1,2,3负责波形的产生,包含i2c协议,输出sda和scl,内部如下:
FPGA中的波形发生器控制电路通过外部控制信号、高速时钟来产生控制ROM波形数据表的地址,输出信号的频率由ROM地址的变化速率决定,变化越快,输出频率越高。
波形数据表ROM用于存放波形数据,可以存放正弦波、矩形波、三角波。
本实验中存放波形数据的ROM是8位宽度,256个数据深度。
五、遇到问题的解决方法
问题1.对于波形的取样点问题:
一开始我们学习使用代码进行编程实现采样点赋值,然而在观察波形的时候发现精度太差,于是我们花费了整整一天的时间进行优化,最后使用rom文件实现更高精度的调用
问题2.对于i2c协议的定义
通过短暂的学习了解,我们初步认识了i2c协议,一开始我们将协议独立为一个模块,但是由于不了解接口定义,所以验证无法通过,我们只好学习别人照猫画虎,将12c直接
写入波形发生模块,得到了正确结果
问题3.对于频率控制的问题
我们提出了三个设想:
A.通过控制改变键盘控制字,通过一个分频模块来得
到基准频率,根据控制字得到理想频率
B.通过改变i2c协议中的频率代码实现波形显示的频率改
变
C.通过改变采样点的采样个数来改变频率输出,我们采样点256个,如果全部逐点扫描得到基础频率,当我们隔点扫描的时候,便会实现分频效果,但是不能按要求实现1KHZ的逐步变化
经过分析,我们认为第一种方法最好,但是在处理接口方面出了一点问题导致控制不能实现;然后我们尝试对第二种方法进行修改,效果同样不理想,所以最终我们的频率模块不能得到实现。
六、收获与体会:
通过本次课程设计我们第一次接触到了VerilogHDL
语言,因为有了c语言的基础对于编程内容的理解相对不困难,对于我们最大的挑战是对于语言的规范,例如,当我们想定义乘法运算的时候,尝试了直接的(*)运算式,结果
出现了错误,后来我们采用了累加器实现了特定功能。
在整个课设过程中,我们查阅了很多的资料,从教科书,网上的论文一直到其他同学的成果,我们都很虚心地进行了借鉴,可能代码不是我们全部自己输入的,但是我们通过亲自设计顶层模块然后根据需求调用,很好的实现了不同程序的修改兼容,这是我们的成果,感到高兴,也有些许遗憾,本次课程设计时间仓促,没能详尽了解语言知识。
在与同学的合作中,我们彼此学习到了对方的长处,在设计过程中发挥各自长处,是我们的设计过程事半功倍。
希望今后有机会进一步学习代码语言,实现软硬件的应用,不断提升自己的能力。
附录:
一、顶层模块
11=====================顶层模块===============================
modulewaveform(clk,rst,ps2k_clk,ps2k_data,ps2_byte,ps2_sel,seg_0,seg_1,seg_2,seg
_3,
ps2_0,ps2_1,ps2_2,SCL1,SDA1,SCL2,SDA2,SCL3,SDA3,SCL,SDA);
inputclk;
inputrst;
inputps2k_clk;//ps2接口时钟
inputps2k_data;//ps2数据信号
output[7:
0]ps2_byte;//频率值
output[1:
0]ps2_sel;//选择波形
outputps2_0,ps2_1,ps2_2;
wire[7:
0]ps2_byte;////1byte键值
wireps2_state;//按键状态标志位
wire[1:
0]ps2_sel;
wire[7:
0]dout;
outputSCL1,SDA1;
outputSCL2,SDA2;
outputSCL3,SDA3;
outputSCL,SDA;
output[7:
0]seg_0;
output[7:
0]seg_1;
output[7:
0]seg_2;
output[7:
0]seg_3;
ps2scanU4(//按键扫描模块
•clk(clk),
.rst(rst),
.ps2k_clk(ps2k_clk),
.ps2k_data(ps2k_data),
.ps2_byte(ps2_byte),
.ps2_state(ps2_state),
.ps2_sel(ps2_sel),
.ps2_0(ps2_0),
.ps2_1(ps2_1),
.ps2_2(ps2_2),
);
segU5(
.clk(clk),
.Res(ps2_byte),
.seg_0(seg_0),
.seg_1(seg_1),
.seg_2(seg_2),
.seg_3(seg_3),
);
wave1U1(clk,rst,SCL1,SDA1);
wave2U2(clk,rst,SCL2,SDA2);
wave3U3(clk,rst,SCL3,SDA3);
wireps2_0;
wireps2_1;
wireps2_2;
selU6(ps2_0,ps2_1,ps2_2,clk,rst,SCL1,SDA1,SCL2,SDA2,SCL3,SDA3,SDA,SCL);
endmodule
//:
、键盘模块
:
键盘接收模块===================================
/*当按键A时选择正弦波,LED0亮当按键S时选择正弦波,LED1亮当按键D时选择正弦波,LED2亮
当重新选择波形时,频率改为默认值*/module
ps2scan(clk,rst,ps2k_clk,ps2k_data,ps2_byte,ps2_sel,ps2_state,led,ps2_0,ps2_1,ps2_2);
inputclk;
inputrst;
inputps2k_clk;
inputps2k_data;
regps20,ps21,ps22;
outputps2_0,ps2_1,ps2_2;
outputled;
output[7:
0]ps2_byte;//ps2数据信号
output[1:
0]ps2_sel;
outputps2_state;//标注键盘当前状态,1表示有按键按下
regled;
reg[15:
0]count;
integernum1,a,b;
initialbegin
num1=0;
a=0;
b=0;
end
always@(posedgeclkornegedgerst)
if(!
rst)
count<=16'b0;
elsebegin
count<=count+1'b1;
if(count==16'hffff)
begin
count<=16'b0;
num1<=num1+1;
if(num1==4)
num1<=0;
end
状态寄存器
end
regps2k_clk_r0,ps2k_clk_r1,ps2k_clk_r2;//ps2k_clkwireneg_ps2k_clk;//ps2k_clk下沿标志位
always@(posedgeclkornegedgerst)beginif(!
rst)begin
ps2k_clk_r0<=1'b0;
ps2k_clk_r1<=1'bO;
ps2k_clk_r2<=1'b0;
end
elsebegin
ps2k_clk_r0<=ps2k_clk;〃锁存状态,进行滤波
ps2k_clk_r1<=ps2k_clk_r0;
ps2k_clk_r2<=ps2k_clk_r1;
end
end
assignneg_ps2k_clk=~ps2k_clk_r1&ps2k_clk_r2;
reg[7:
0]ps2_byte_r;//PC接收来自ps2的一个字节数据寄存器
reg[7:
0]temp_data;//当前接收数据寄存器
reg[3:
0]num;//计数寄存器
always@(posedgeclkornegedgerst)begin
if(!
rst)begin
num<=4'd0;
temp_data<=8'd0;
end
elseif(neg_ps2k_clk)begin
case(num)
4'd0:
num<=num+1'b1;
4'd1:
begin
num<=num+1'b1;
temp_data[0]<=ps2k_data;
end
4'd2:
begin
num<=num+1'b1;
temp_data[1]<=ps2k_data;
end
4'd3:
begin
num<=num+1'b1;
temp_data[2]<=ps2k_data;
end
4'd4:
begin
num<=num+1'b1;
temp_data[3]<=ps2k_data;
end
4'd5:
begin
num<=num+1'b1;
temp_data[4]<=ps2k_data;
end
4'd6:
begin
num<=num+1'b1;temp_data[5]<=ps2k_data;
end
4'd7:
begin
num<=num+1'b1;temp_data[6]<=ps2k_data;
end
4'd8:
begin
num<=num+1'b1;temp_data[7]<=ps2k_data;
end
4'd9:
begin
num<=num+1'b1;
end
4'd10:
begin
num<=4'dO;
end
default:
;
endcase
end
end
regkey_fO;〃松键标志位,1表示收到数据8f0;
regps2_state_r;〃键盘当前状态,1表示按下
always@(posedgeclkornegedgerst)beginif(!
rst)begin
key_f0<=1'bO;
ps2_state_r<=1'bO;
end
elseif(num==4'd10)〃传送完一个字节
begin
if(temp_data==8'hf0)begin
key_f0<=1'b1;
led<=0;
end
elsebegin
if(!
key_f0)begin〃
ps2_state_r<=1'b1;
led<=1;
ps2_byte_r<=temp_data;
end
elsebegin
ps2_state_r<=1'b0;
key_fO<=1'bO;
end
end
end
endreg[1:
0]ps2_asci_1;
reg[7:
0]ps2_asci;
always@(ps2_byte_r)begin
case(ps2_byte_r)
8'h16
:
ps2_asci<=8'hf9;//1
8'h1E
:
ps2_asci<=8'ha4;//2
8'h26
:
ps2_asci<=8'hb0;//3
8'h25
:
ps2_asci<=8'h99;//4
8'h2E
:
ps2_asci<=8'h92;//5
8'h36
:
ps2_asci<=8'h82;//6
8'h3D
:
ps2_asci<=8'hf8;//7
8'h3E
:
ps2_asci<=8'h80;//8
8'h46
:
ps2_asci<=8'h90;//9
8'h45
:
ps2_asci<=8'hc0;//0
8'h1c
:
beginps2_asci_1<=2'b00;ps20<=1'b1;ps21<=1'b0;ps22<=1'b0;end//A
8'h1b
:
beginps2_asci_1<=2'b01;ps20<=1'b0;ps21<=1'b1;ps22<=1'b0;end//S
8'h23
:
beginps2_asci_1<=2'b10;ps20<=1'b0;ps21<=1'b0;ps22<=1'b1;end//D
/*8'h55:
begincase(ps2_asci)//+
8'h90,8'hc0:
ps2_asci<=8'hc0;//0
8'hf9,8'ha4,8'hb0,8'h99,8'h92,8'h82,8'hf8,8'h80:
ps2_asci<=ps2_asci+1'h01;
default;
endcase
end
8'h4E:
begincase(ps2_asci)〃-
8'hc0:
ps2_asci<=8'h90;//9
8'hf9:
ps2_asci<=8'hf9;//1
8'ha4,8'hb0,8'h99,8'h92,8'h82,8'hf8,8'h80,8'h90:
ps2_asci<=ps2_asci-1'h01;
default;
endcase
end*/
default:
ps2_asci<=8'hf9;
endcase
end
assignps2_byte=ps2_asci;
assignps2_0=ps20;
assignps2_1=ps21;
assignps2_2=ps22;
assignps2_sel=ps2_asci_1;
assignps2_state=ps2_state_r;endmodule
三、数码管显示模块
inputclk;
input[7:
0]Res;
outputreg[7:
0]seg_0;outputreg[7:
0]seg_1;
outputreg[7:
0]seg_2;
outputreg[7:
0]seg_3;
parameter
seg0=8'hcO,seg1=8'hf9,seg2=8'ha4,
seg3=8'hbO,
seg4=8'h99,
seg5=8'h92,
seg6=8'h82,
seg7=8'hf8,
seg8=8'h80,
seg9=8'h90;
always@(posedgeclk)begin
case(Res)
8'hc0:
beginseg_0<=seg0;seg_1<=seg1;seg_2<=seg0;seg_3<=seg0;end8'hf9:
beginseg_0<=seg1;seg_1<=seg0;seg_2<=seg0;seg_3<=seg0;end8'ha4:
beginseg_0<=seg2;seg_1<=seg0;seg_2<=seg0;seg_3<=seg0;end8'hb0:
beginseg_0<=seg3;seg_1<=seg0;seg_2<=seg0;seg_3<=seg0;end8'h99:
beginseg_0<=seg4;seg_1<=seg0;seg_2<=seg0;seg_3<=seg0;end8'h92:
beginseg_0<=seg5;seg_1<=seg0;seg_2<=seg0;seg_3<=seg0;end8'h82:
beginseg_0<=seg6;seg_1<=seg0;seg_2<=seg0;seg_3<=seg0;end8'hf8:
beginseg_0<=seg7;seg_1<=seg0;seg_2<=seg0;seg_3<=seg0;end8'h80:
beginseg_0<=seg8;seg_1<=seg0;seg_2<=seg0;seg_3<=seg0;end
8'h90:
beginseg_0<=seg9;seg_1<=seg0;seg_2<=seg0;seg_3<=seg0;endendcase
end
子模块一
moduleRomAddressCtrl1(Done_Sig,clock,reset,isStart,RomAddress);
inputDone_Sig;
inputclock;
inputreset;
//input[7:
0]FreqChoose;
reg[1O:
O]RegRomAddress;
always@(posedgeclockornegedgereset)if(!
reset)
begin
//Regl2CAddress<=8'dO;
RegisStart<=2'b00;
end
else
case(i)
0:
if(Done_Sig)beginRegisStart<=2'b00;i<=i+
1'b1;RegRomAddress<=RegRomAddress+8'd41;end
elsebeginRegisStart<=2'b01;end
1:
if(Done_Sig)beginRegisStart<=2'b00;i<=4'dO;
RegRomAddress<=RegRomAddress+8'd41;end
elsebeginRegisStart<=2'b01;end
endcase
endmodule
子模块二
moduleiic1
(
inputCLK,
inputRSTn,
input[1:
0]Start_Sig,input[7:
0]WrData,output[7:
0]RdData,outputDone_Sig,outputSCL,inoutSDA
);
parameterFREQ14=11'd85;parameterFREQ24=11'd170;
parameterFREQ34=11'd255;
parameterFREQ=11'd341;
*********************
reg[4:
0]i;
reg[4:
0]Go;
reg[10:
0]C1;
reg[7:
0]rData;
regrSCL;
regrSDA;
regisAck;
regisDone;
regisOut;
always@(posedgeCLKornegedgeRSTn)
if(!
RSTn)
begin
i<=5'dO;
Go<=5'd0;
C1<=11'd0;
rData<=8'dO;
rSCL<=1'b1;
rSDA<=1'b1;
isAck<=1'b1;
isDone<=1'b0;
isOut<=1'b1;
end
elseif(Start_Sig[0])
case(i)
0:
//Start
begin
isOut=1;
rSCL<=1'b1;
if(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 FPGA 波形 发生器