VHDL作业题目终稿Word下载.docx
《VHDL作业题目终稿Word下载.docx》由会员分享,可在线阅读,更多相关《VHDL作业题目终稿Word下载.docx(27页珍藏版)》请在冰豆网上搜索。
='
0'
;
elsifgclk'
eventandgclk='
sig_0<
=sig_in;
sig_1<
=sig_0;
sig_2<
=sig_1;
sig_3<
=sig_2;
if((sig_3=sig_2)and(sig_2=sig_1)and(sig_1=sig_0)and(sig_0=sig_in))then
sig_out<
=sig_3;
endif;
endif;
endprocess;
仿真结果如图2:
图2消抖程序仿真图
(b)延时4ms
process(gclk)
begin
ifrst='
signal_out<
psignal<
ppsignal<
signal_cnt<
=0;
elsif(gclk='
)and(gclk'
event)then
ppsignal<
=psignal;
psignal<
=signal_in;
ifpsignal/=ppsignalthen
signal_cnt<
=0;
else
=signal_cnt+1;
ifsignal_cnt>
159999then------消抖时间为4ms------
--ifsignal_cnt>
99then
signal_out<
endif;
endprocess;
仿真结果;
图3延时仿真图
2、测试在不同主频、分频下逻辑处理上的不同,并分析。
分频器是数字系统设计中的基本电路,根据不同设计的需要,我们会遇到偶数分频、奇数分频、半整数分频等,有时要求等占空比,有时要求非等占空比。
在同一个设计中有时要求多种形式的分频。
通常由计数器或计数器的级联构成各种形式的偶数分频及非等占空比的奇数分频,实现较为简单。
但对半整数分频及等占空比的奇数分频实现较为困难。
本文利用VHDL硬件描述语言,可设计了一种能够满足上述各种要求的较为通用的分频器。
现通过设计一个可以实现8.5分频,等占空比的17分频,2、4、8、16、32分频,及占空比为1∶8和4∶5的9分频等多种形式分频的分频器。
分频器由带使能端的异或门、模N计数器和一个2分频器组成,本设计用D触发器来完成2分频的功能,实现方法是:
将触发器的Q反输出端反馈回输入端D,将计数器的一个计数输出端作为D触发器的时钟输入端。
各功能模块的VHDL语言实现如下。
1).模N计数器的实现
一般设计中用到计数器时,我们可以调用lpm库中的计数器模块,也可以采用VHDL语言自己设计一个模N计数器。
本设计采用VHDL语言设计一个最大模值为16的计数器。
输入端口为:
使能信号en,复位信号clr和时钟信号clk;
输出端口为:
qa、qb、qc、qd。
其VHDL语言描述略。
2).带使能控制的异或门的实现
输入端为:
xor_en:
异或使能,a和b:
异或输入;
输出端为:
c:
异或输出。
当xor_en为高电平时,c输出a和b的异或值。
当xor_en为低电平时,c输出信号b。
其VHDL语言略。
3).分频(触发器)的实现
时钟信号clk,输入信号d;
q:
输出信号a,q1:
输出信号a反。
以下是几种分频器的分析:
偶数分频器
频最易于实现,欲实现占空比为50%的偶数N分频,一般来说有两种方案:
,分频器的基础是计数器,设计分频偶数分N/2-1时,将输出电平进行一次翻转,同时给计数器一个复位信号,如此循环下去;
二是当计数器输出为0到N/2-1时,时钟输出为0或1,计数器输出为N/2到N-1时,时钟输出为0或1,计数器输出为N/2到N-1时,时钟输出为0或1,计数器输出为N-1时,复位计数器,如此循环下去。
图4偶数分频仿真结果图
图5偶数分频仿真结果图
奇数分频器
实现非50%占空比的奇数分频,如占空比为20%、40%、60%、80%的5分频器,可以采用类似偶数分频的第二种方案;
但如果实现占空比为50%的奇数分频,就不能使用偶数分频中所采用的方案了。
下面就以实现占空比40%的5分频分频器为例,说明非50%占空比的奇数分频器的实现。
该分频器的实现对于我们实现50%占空比的分频器有一定的借鉴意义。
一下是奇数分频仿真结果图。
图6占空比为40%的5分频仿真波形
半整数分频器
仅仅采用数字分频,不可能获得占空比为50%的N+0.5分频,我们只可以设计出占空比为(M+0.5)/(N+0.5)或者M/(N+0.5)的分频器,M小于N。
这种半整数分频方法是对输入时钟进行操作,让计数器计数到某一个数值时,将输入时钟电平进行一次反转,这样,该计数值只保持了半个时钟周期,因此实现半整数分频。
如上所述,占空比为50%的奇数分频可以帮助我们实现半整数分频,将占空比为50%的奇数分频与待分频时钟异或得到计数脉冲,下面的代码就是依靠占空比为50%的5分频实现2.5分频器的。
仿真结果如图所示。
图72.5分频仿真波形
小数分频器
小数分频是通过可变分频和多次平均的方法实现的。
例如要实现4.7分频,只要在10次分频中,做7次5分频,3次4分频就可以得到。
再如要实现5.67分频,只要在100次分频中,做676分频,33次5分频即可。
考虑到小数分频器要进行多次两种频率的分频,必须设法将两种分频均匀。
表1以2.7分频为例,小数部分进行累加,如果大于等于10,则进行3分频,如果小于10,进行2分频。
仿真波形如图所示,我们可以清楚的看到2.7分频的实现。
按照占空比的定义,该分频器的占空比应为10/27。
图82.7分频仿真波形
分数分频器
将小数分频的方法进行扩展,可以得到形如M*(L/N)的分数分频的方法,例如,2*(7/13)等于分母的,进行分频,只要在13次分频中,进行7次3分频,6次2分频就可以得到。
同样,为了将两种分频均匀,将分子部分累加,小于分母的,进行M分频,大于(M+1)分频。
表2显示了2*(7/13)的分频次序。
仿真波形如图11所示。
显然,该分频器的占空比为13/33。
图933/13分频器仿真波形
积分分频器
积分分频器用于实现形如的分频,例如8/3分频。
我们当然可以使用上面提到的分数分频的方法,但对于这种形式的分频,使用积分分频的方法综合往往占用更少的FPGA资源。
积分分频法基于下述原理:
一个m位的二进制数字每次累加N,假定累加x次累加值最低m位回到0,同时超过次,那么,当前累加的数字应该是;
每越过一次,最高位变化2次,所以,累加x次,最高位变化2y次,得到分频的分频器,例如,取m为4,N为3,当累加16次时,累加值为48,最低m位变回到0,同时越过16三次,最高位变化6次,由此得到16/6=8/3分频的分频器。
分频仿真结果如图所示。
图10积分分频仿真波形
3、写出异步串行通信的发送与接收程序,并分析。
异步串行数据传输具有设计简单、传输稳定等优点。
其两个主要参数是波特率和数据位格式。
数据位格式又称帧格式,一般包含一个起始位(逻辑0),一个终止位(逻辑1)以及校验位。
在发送空闲时,总线一般处于逻辑1状态。
这样当接收端检测到总线上由高到低的电平跳变,即认为是数据开始传输。
波特率是用来约定通信双方的通信速率,一般通过对系统时钟进行分频来实现,RS-232协议中,常用的波特率有115200、9600等,RS-422与RS-232原理基本相同,只是在传输线路上,为了抗干扰,采用了差分方式。
在FPGA应用领域,串行数据传输一般采用422总线。
通过对系统晶振分频,得到对应的波特率,比如对40MHz经行4分频,得到10MBit的传输速率。
解码端会根据预先设定的波特率,对时钟进行分频,每隔相等时间读取总线上的一位数据。
流程如下:
在检测到起始位低电平之后,接收端(即解码端)每隔一位时间,采集总线上的电平,并写入移位寄存器中,直到将一帧数据全部接收,然后判断校验位,如果正确,则接收、编帧,否则,丢弃。
由于受温度等因素的影响,晶振会产生误差,串行数据在传输过程中,可能会受到干扰而产生毛刺。
所以在一些对数据准确度要求比较高的场合,就得考虑串行数据传输的容错能力。
对于这种情况,第一种方法通常会采取对总线上的一位分别采集三次,比较得到的三个电平,进而得到该位可信度更高的值,如图2所示;
第二种方法则会将电平的采集点放在每一位的靠近中间的位置,通过计算晶振的最大误差,则可以计算出系统的最大容错能力。
设晶振误差5%,频率为40MHz,1/40MHz=25ns,25*0.05=1.25ns,设波特率为4Mbit/s,所以对于40bit一帧的串行数据,累积误差最大会有1.25*40*4*50%=100ns,而比特位宽只有100ns,所以有可能会发生错位。
图11多次采样减小误差示意图
部分代码如下
(a)422串行发送
process(pClock,pReset)--惯组信号源控制主进程
ifpReset='
ch_ClearBusyFlag<
='
ch_tx<
ch_send_reg<
="
0000000000000000000000000000000000000000"
ch_st<
ch_clock_fp<
elsif(pClock='
)and(pClock'
ifch_st=0then--监测有无数据发送
if(ch_s_busy_flag='
)then
=ch_send_buf;
--读取要发送的数到寄存器
--置忙标志清零
ch_bit_counter<
ch_st<
=1;
else
elsifch_st=1then--串行发送
=ch_clock_fp+1;
--0-57,每位57个时钟,共12位,1起始,1停止,2空闲
ifch_clock_fp=1then
=ch_send_reg(39-ch_bit_counter);
elsifch_clock_f