引言
FPGA是作为专用集成电路ASIC领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。使用FPGA来开发数字电路,可以大大缩短设计时间,减少PCB的面积,提高电路的可靠性。
我们小组用XILINX的FPGA,设计了FPGA 键控图片大小变化与数码显示的电路,领略了FPGA强大的功能和开发的便捷性。
实验内容介绍
顶层模块:

系统的电路原理图

子模块功能说明
获取扫描码/Keyboard_ScanCode模块
功能:用来获得按键的八位扫描码;即实现串并转换的功能。
PS/2键盘接口技术背景:PS/2键盘采取双向串行同步传输方式,串行指的是每次数据线上发送一位数据也要在时钟线上发一个脉冲数据才能被读入,如下图所示:

键盘收发数据格式
起始位:以0来标示一帧数据的开始;
数据位:低位D0在前,高位D7在后;
校验位:错误检测;
应答位:只用在主机发送数据给键盘;
该模块实现机理
1. 单向通信:只实现了键盘到主机的通信过程,没有对处理主机到设备的通信过程;
2. 部分键位:只实现了部分按键的扫描码的转换,这是因为要考虑通码,断码,不同键的数据格式有很大区别,再有我们设计的功能相对简单,用的只是一小部分键位,故我们只实现了数字从0-9,字母A-F的扫描码转换;
3. 串并转换:由于键盘的有效端口为一个数据和一个键盘时钟。功能模块要接收键盘的时钟和数据,并进行串并转换把它转换成键盘要发送的扫描码。
4. 记数移位:要实现串并转换采用的方法有很多,比如移位寄存器等,在这里我们采用一个随着键盘时钟变化的模11的计数器,在键盘时钟的下降沿,首先把采样数据值赋给相应的并行数据的某一位(具体哪一位根据计数器的值确定),然后计数器自增。并且可以在变成8位扫描码时移去一帧数据的起始位,校验位和停止位(一帧数据中有11位,我们需要的只是其中的8位数据位)。
设计中碰到的困难
刚开始设计键盘功能模块时大致思路与上面一致,但是在刚开始时我没有加系统时钟,只用键盘时钟来进行处理,结果扫描码一直传不到我下一个功能模块,其原因是很显然的:我的其它模块都是在系统时钟下工作的,即只有在系统时钟脉冲变化时才采样数据,而我的扫描码模块却不在系统时钟下工作,这样很显然扫描码不会传入其他模块中的。
经验教训
时序电路中的所有模块最好在一个系统时钟下统一协调工作,不要用分立的不同时钟来控制不同的功能模块,这样可以尽量避免数据传输的不同步,保证采样数据按时序要求到达。
控制信号产生模块/Control_Display_signal 模块
功能:根据输入的扫描码来产生与按键相关的控制信号。
1. 产生用于控制四个数码管中哪些灯亮的信号;
2. 产生用于控制7段数码管显示数字/字母的信号;
3. 产生用于控制显示图片大小的控制信号;
功能一:控制灯亮

功能二:控制数码管显示数字/字母
通过扫描码用CASE语句来判定输出:

功能三:控制图片大小的信号

该模块实现机理:该模块实现起来比较容易,主要是根据输入的键盘扫描码来产生控制信号,主要用到CASE语句和if条件分支语句。
图形显示模块/SCH 模块
功能:控制显示器在给定位置上显示图片,并能根据输入的Change_image信号来变换图形的大小。
模块:包括三个小功能模块
子模块一:产生VGA所需的行信号和列信号标准的VGA(640×480,60Hz)
VGA时序技术背景:

实现的难点:
1. Buffer信号的设置:
行信号(HS)用来触发竖直计数器,行信号(HS)在该功能模块里既是输入信号又是输出信号;
前后肩信号的去除:

实现方法:
设置两个计数器,模800的行计数器和模525的列计数器,系统时钟25MHZ来控制行计数器,通过计数器的值来控制行信号HS,在通过行信号HS来控制列计数器,通过计数器的值来控制列信号VS。
子模块二:用IP核生成单端口的ROM
实现难点:
1.图片信息比较大,BASYS板上的资源是很有限的,这就要求我们所能显示的图片不能太大,否则会报错,通过实验和找资料发现图片容量大小在8192byte内的图片可以显示。
2.利用Core Generator产生块存储的时候,还需要输入一个为.COE文件来初始化存储器的内容,如何产生图片的.COE文件是摆在我面前的一个难题。
3.一般的.JPG的图片,其RGB各8位,而在我们这里R是3位,G是3位,B是两位,所以要想显示照片还需对照片信息进行处理,这也是摆在我面前的一个难题。
4.利用MATLAB对图象进行处理生成.COE文件,利用MATLAB对图象的强大处理功能来实现图象处理,并按照.COE文件的格式生成图象初始化文件。(程序附录)
图片信息:
大小为:122*67 *8 =8174*8bit

利用Core Generator产生8位的深度为8192(地址线数为13)的块rom来存放上面的图片数据。
子模块三:读取ROM中的数据,并通过Chang_image信号来控制图片的大小
实现难点:
1. 读取rom,通过行列信号来控制图片的显示位置,可参考前面前后肩信号的去除。
2. 图片变大如何实现,我们这里采用对图象象素点进行n位重写(n表示放大的倍数),可见看见显示的图象会出现马赛克的效应,图象质量明显下降。
图形显示模块设计中碰到的困难:
1. VGA时序
前后肩信号时序要搞清楚,否则图片是不容易显示出来的;
经验教训:在进行设计前一定要把相关的技术背景资料准备好,否则很容易出现差错。
2. 显示图象的位置
我们产生的控制信号是640*480标准模式的,而我们用来做实验的CRT和液晶显示器的分辨率远超过了这个范围,所以我们可以看到有些地方是不能显示图片的,如果把图片位置设定在这些地方,是看不到图片的,刚开始,有好几次碰到这种情况,起初我们还以为是我们设计的时序有问题,不停地修改还是解决不了,最后把显示位置改了一下就好了,要是当初把这个问题,考虑好了,也就不会走这么多的弯路了。
3. 液晶与CRT显示的不同
在实验过程中我们发现,我们设计的VGA时序,如果LCD液晶显示器能显示图片那么CRT一定能显示,反之则不成立,我们刚开始用CRT做实验,效果很好,可是换成LCD时,却显示不出来,也就把图片位置改了一下才又显示出来了。针对这个问题,我们现在也不能搞的不是很清楚,希望老师能指导一下。
总结
这次活动让我们学到了很多知识,也碰到了很多问题,极大地丰富了我们实际解决问题的能力,锻炼了我们实际动手操作的能力。在实验过程中,经常碰到仿真没有错误,但下载到硬件电路板上却达不到预想的效果,然后不停地修改电路,查阅相关资料,经过三番五次的努力,终于得到所需结果了,我们无不为之欢喜雀跃。
事实胜于雄辩,实际操作胜于理论知识!


