游戏功能说明
本次project,由于我们参考了已有的IP核,实现了一个比较常见的游戏Pingball,该游戏的规则很简单:一个小球在空间中移动,空间中存在一些方块,靠控制屏幕底端托杆与小球的碰撞来控制小球的移动。小球与空间中的方块相碰时,方块消失,同时小球反射改变移动方向。所有小方块都消失,游戏结束。游戏由键盘控制并且通过VGA接口现实,键盘实现托杆的左右移动,以及游戏的暂停和重新启动功能。
游戏代码说明
整个project分为三部分:
VGA部分:实现VGA接口的传输
键盘控制部分:实现键盘控制信号的传输
控制部分:实现小球托杆的移动的控制,碰撞,小方块的存在与消失。以及将各部分结合起来
三部分的说明如下:
控制部分
实现功能:实现小菱形的移动,屏幕底端托杆的的移动,菱形的反射以及菱形与方块碰撞的判断。
代码说明:

上面的代码用来判断小的菱形在Y的方向是否有碰撞,碰撞包括与墙壁(屏幕边缘)以及小方块的碰撞,如果有碰撞的话,改变y_add的值,即菱形在Y方向上沿与原先移动方向相反的方向移动。在代码中体现如下:
if (y_add==1)
ypos<=ypos+2;
else if (y_add==0)
ypos<=ypos-2;
判断小方块是否被碰到的代码如下:
if ({xpos_10[9:6],ypos[9:5]}==block_reg)
begin
switch0<=1;
block_reg0<={xpos_10[9:6],ypos[9:5]};
被碰到后,完成方块相应的标记寄存器的设置。
底部托块的移动:根据控制键来完成左右的移动,每次移动4像素。并且考虑到了边界问题
菱形的移动:根据y_add x_add的值的四种组合(0,1)(0,0)(1,0)(1,1)实现菱形的四个方向移动,每个方向都是45度角
VGA部分
VGA原理简介
VGA(Video Graphics Array)是IBM于1987年提出的一个使用类比讯号电脑显示标准
其中端口每个节点的定义如下图:

开发板上FPGA与VGA接口的连接如下图:

从上图中不难看到,标准的VGA(640×480,60Hz)接口需要提供以下几组信号:3个RGB模拟信号、行同步信号HS和场同步信号VS。
VS为场同步信号,场周期为16.683ms,每场有525行,其中480行为有效显示行,45行为场消隐区,场同步信号每场有一个脉冲,该脉冲的低电平宽度为63μs(2行)。行周期为31.78μs,每显示行包括800点,其中640点为有效显示区,160点为行消隐区(非显示区)。行同步信号HS每行有一个脉冲。该脉冲的低电平宽度为3.81μs(即96个脉冲)。因此,VGA控制器的任务就是按要求产生所需要的时序。
DISCLK为视频显示时钟,频率为25MHz,首先输入到模等于800的像素计数器中,输出的计数值与一个预先设好的比较器进行比较,当计数器的值大于160时,输出高电平,反之输出低电平,作为行同步信号;同理,利用一个模等于525的计数器对行同步信号进行计数和一个阈值为45的比较器可以产生所需要的场同步脉冲VS。
产生的行、场同步信号和像素显示时钟分别被送到两个地址发生器中,产生所需要的控制帧存储器的地址信号。
VGA部分代码说明
1
进行行和场的像素计数,水平方向(场)800个像素为一周期,垂直方向(行)525个像素为一个周期,每一个计数周期结束后,计数变量horizontal_counter和vertical_counter清零重新计数。

2
输出行频和场频信号即每完成一个Tdisp周期以及Tfp后,输出一个脉宽为Tpw个像素时钟的HS和VS信号


3
绘制菱形pingball部分,以xpos和 ypos为中心绘制对角线长度为20像素的菱形,其中菱形的颜色会根据坐标改变

4
绘制屏幕底端接方块,原理与菱形相似,代码略
5
绘制待碰的方块,亦即像素扫描到相应的坐标后,如果该块未被碰过(switch_reg[1]==0)绘制方块,共需绘制20个,其中一个的代码如下图:

PS2键盘控制部分
PS2键盘原理简介
键盘的功能:及时发现被按下的键,并将该按键的信息送入主机。
键盘之所以可以识别按键信息,是因为键盘内部具有扫描电路、产生被按下键代码的编码电路、将代码送入主机的接口电路。当一个键被按下时,控制电路根据其位置,将字符信号转换成二进制码,传给主机。键盘的处理器扫描按键矩阵。如果发现有键被按下、释放或按住,键盘将发送相应的扫描码的信息包到主机。
扫描码有两种不同的类型:通码和断码。当一个键被按下或按住就发送通码,当一个键被释放就发送断码,每个按键被分配了唯一的通码和断码,这样主机通过查找唯一的扫描码就可以测定是哪个按键。每个键的通断码组成了扫描码集。有三套标准的扫描码集,所有现代的键盘默认使用第二套扫描码。只要一个键被按下,这个键的通码就被发送到计算机。多数第二套通码只有一个字节宽,但也有少数扩展按键的通码是两字节或四字节宽,这类通码的第一个字节总是E0h。只要键一释放,断码就会被发送。每个键都有它自己唯一的通码和唯一的断码。多数第二套断码有两字节长,它们的第一个字节是F0h 第二个字节是这个键的通码。扩展按键的断码通常有三个字节,它们前两个字节是E0h,F0h ,最后一个字节是这个按键通码的最后一个字节。
如果按了一个键,这个键的通码被发送到计算机;当你按下并按住这个键,则键盘将一直发送这个键的通码直到它被释放或者其他键被按下。在第一第二套扫描码里没Pause/Break 键的断码,当这个键按下时,发送它的通码;当它释放时,什么都不发送。
PS2接口的6个引脚:

本次project实现功能仅限于键盘与主机的通信,原理如下:
PS/2 鼠标和键盘履行一种双向同步串行协议,换句话说每次数据线上发送一位数据并且每在时钟线上发一个脉冲就被读入,键盘/鼠标可以发送数据到主机而主机也可以发送数据到设备,但主机总是在总线上有优先权它可以在任何时候抑制来自于键盘/鼠标的通讯,只要把时钟拉低即可。
从键盘/鼠标发送到主机的数据在时钟信号的下降沿当时钟从高变到低的时候被读取,从主机发送到键盘/鼠标的数据在上升沿当时钟从低变到高的时候被读取,不管通讯的方向怎样键盘/鼠标总是产生时钟信号。
数据和时钟线都是集电极开路结构(正常保持高电平)当键盘或鼠标等待发送数据时它首先检查时钟以确认它是否是高电平,如果不是那么是主机抑制了通讯设备必须缓冲任何要发送的数据直到重新获得总线的控制权,键盘有16 字节的缓冲区而鼠标的缓冲区仅存储最后一个要发送的数据包如果时钟线是高电平设备就可以开始传送数据。
键盘和鼠标使用一种每帧包含11 位的串行协议:1 个起始位总是为0,8 个数据位低位在前,1 个校验位奇校验,1 个停止位总是为1。每位在时钟的下降沿被主机读入。

时钟频率为10 16.7kHz ,从时钟脉冲的上升沿到一个数据转变的时间至少要有5 微秒数据变化到时钟脉冲的下降沿的时间至少要有5 微秒,并且不大于25 微秒。主机可以在第11 个时钟脉冲停止位之前把线拉低,导致设备放弃发送当前字节。在停止位发送后,设备在发送下个包前至少应该等待50 毫秒,这将给主机时间当它处理接收到的字节时抑制发送,主机在收到每个包时通常自动做这个在主机释放抑制后设备至少应该在发送任何数据前等50 毫秒。
一. 开发板上与PS2接口相关引脚

如图,开发板pin96对应键盘的clk输入,即PS2口的pin1,开发板的pin97对应键盘的data输入,即PS2口的pin2。

上图是键盘扫描码,本次project用到的是Z,X,C,V四个键,分别控制pingball的接球板左移和右移,以及游戏暂停和重新开始。
代码说明





其它说明
由于时间以及FPGA可用资源的限制,我们实现的这个游戏的功能不是很强大,原本我们计划做的俄罗斯方块也因为上面的原因被迫放弃。
通过这次Project ,我们的收获还是很大的,特别是VGA以及PS2接口的使用和实现上。