基于FPGA的波形发生器.docx

上传人:b****8 文档编号:10236471 上传时间:2023-02-09 格式:DOCX 页数:28 大小:471.96KB
下载 相关 举报
基于FPGA的波形发生器.docx_第1页
第1页 / 共28页
基于FPGA的波形发生器.docx_第2页
第2页 / 共28页
基于FPGA的波形发生器.docx_第3页
第3页 / 共28页
基于FPGA的波形发生器.docx_第4页
第4页 / 共28页
基于FPGA的波形发生器.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

基于FPGA的波形发生器.docx

《基于FPGA的波形发生器.docx》由会员分享,可在线阅读,更多相关《基于FPGA的波形发生器.docx(28页珍藏版)》请在冰豆网上搜索。

基于FPGA的波形发生器.docx

基于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(

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 文学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1