本次课程设计,将在 BASYS 实验板上实现一个俄罗斯方块的小游戏。整个过程可以分为两个步骤:VGA 的调试,俄罗斯方块的程序的移植。
一 VGA 的调试
要在 BASYS 实验板上作一个俄罗斯方块游戏,要用到 VGA 接口。所以首先要进行 VGA 的调试。
VGA 接口信号类型:模拟。
接口:显示卡端的接口为15 针插座,显示器连线端的接口为15 针插头。里面的针脚有红绿蓝三色的信号线和相应的地线,还有行同步和场同步信号以及各自的地线。
VGA工业标准所要求的频率:
时钟频率: 25.175MHz(像素输出的频率);
行频: 31469Hz ;
场频: 59.94Hz 。
显示器技术规格提供的行频一般在30kHz~45kHz(保守数据),场频一般在50Hz~75Hz(保守数据),针对以上保守数据,30kHz的行频进行扫描时所需时钟频率为:30kHz×800(行周期)=24MHz,则场频为:30kHz÷525(场周期)=57.14Hz 。
本方块游戏采用标准的VGA(640×480,60Hz),接口需要提供以下几组信号:3个RGB模拟信号、行同步信号HS和场同步信号VS。信号时序如图所示

HS为行同步信号,行周期为31.78μs,低电平有效,持续时间为3.77us,后面1.89us的时间是回扫时间,每显示行包括800点,其中640点为有效显示区,160点为行消隐区(非显示区)。
VS为场同步信号,场周期为16.683ms,每场有525行,其中480行为有效显示行,45行为场消隐区,场同步信号每场有一个脉冲,该脉冲的低电平宽度为63μs(2行)。VGA控制器的任务就是按上述要求产生所需要的时序。
DISCLK为视频显示时钟,频率为25MHz,首先输入到模等于800的像素计数器中,输出的计数值与一个预先设好的比较器进行比较,当计数器的值大于160时,输出高电平,反之输出低电平,作为行同步信号;同理,利用一个模等于525的计数器对行同步信号进行计数和一个阈值为45的比较器可以产生所需要的场同步脉冲VS。
产生的行、场同步信号和像素显示时钟分别被送到两个地址发生器中,产生所需要的控制帧存储器(Pixel Ram)的地址信号。

产生了规定的时序信号后,VGA 显示器的屏幕能够被点亮,为了让他显示彩条,必须有一个存储器来保存显示内容。
由于在 BASYS 开发板上没有外加内存,只有 FPGA 上有限的块内存,所以不能在显示器上显示 640*480 像素的图像,但是可以把屏幕分块,比如把物理上的 16*16 像素当成逻辑上的一个像素处理。也就是说,假如有 10bit 宽的行和列的地址信号 hloc 和 vloc。我们可以忽略它的最低 4bit 信号取编号 4 到 7 的信号作为逻辑地址:
y_temp :=vloc(7 downto 4);
x_temp :=hloc(7 downto 4);
这样就不屏幕粗化为 16*16 像素的显示模式,这里所说的像素就是只物理上的 16*16 像素的一块区域,这样就可以以一个 bit 来代表屏幕上 16*16pixel 的内容了,总共需要 256bit 的块存储器就可以了。

在老师课件提供的程序中由于只需要产生彩条,所以用了 ROM 保存图像信息,在俄罗斯方块中,由于需要在程序中不断修改屏幕显示内容,所以必须把 ROM 改成触发器。在代码中可以定义一个 word 类型,它是 16 维的 std_logic 数组,然后再定义一个 memory 类型,是 32 维 word 数组,这样 32*16 个小格的内容可以独立修改和读取。但是在实际程序中没有用到这么多个存储空间,在游戏的界面只有 16*10 个格的内容。
在 BASYS 实验板上,红色信号为 3bit,绿色信号为 3bit,蓝色信号为 2bit,按照 datasheet 上的硬件接线图就可以在ISE 中为各个信号输出分配管脚。

二 简易的方块 的工作流程
在移植别人的俄罗斯方块之前,我自己做了一个简易的方块程序,该程序只是在屏幕上画了一个红色的游戏窗口边界,在这个窗口里面会有一个小方框不断往下掉,在掉的过程中,可以按动 BASYS 开发板上的 BTN0 右移小方块,BTN1 则可以左移小方块,当方块落到下面会慢慢堆积起来。做到这一步可以理解怎么用寄存器更改保存显示区域的内容,怎 么控制方块的移动,怎么判断方块何时停止下落。效果如下图,具体操作可以用 bit 文件下载到 BASYS 上面试验。

点击此处,下载全图![]()
这个简单的方块每次只落一个小块,当然也就不用什么旋转变形功能,也没有做记分以及分数显示,而是移植一个在 D2SB 开发板(外加 DIO4 外围扩展版)上比较成型俄罗斯方块程序。
三 俄罗斯方块的移植
俄罗斯方块的游戏界面如下图:

此方块程序用 PS/2 键盘控制,按照屏幕上的提示,A 是左移,D 是右移,S 是加速键,空格键旋转。
程序的方块显示和上文提到的方式一样,文字的显示见附带的另外一个英文文档。
下页是整个俄罗斯方块的模块图:
点击此处,下载全图![]()
这里只介绍核心控制模块和状态转换图。
核心控制模块控制所有的步骤.
这个模块的作用就是读取键盘扫描码,把扫描码作为控制信号对块存储区进行操作


下面是状态流图:
点击此处,下载全图![]()
点击此处,下载全图![]()
在移植工作中,由于已经有了在 BASYS 上作小方块的经验,移植过程比较简单。
首先加了分频器使整个系统的时钟与原程序的主时钟一致。在原来的程序中,由于 DIO4 的 VGA 信号有些差异,比如,他用的是 3 位表示颜色,开始的时候我也只接了 3 根颜色信号线,发现屏幕上显示的颜色非常的暗淡,后来把 BASYS上的三 bit 红色赋同样的值,三 bit 绿色线也赋同样的值,再把 2 根蓝色信号线赋同样的值,这样颜色就亮了不少。
资源耗费情况如下:
点击此处,下载全图![]()
点击此处,下载全图![]()
从上表看出,这个方块程序差不多把系统资源占完了,能够在 BASYS 上移植这个俄罗斯方块程序很幸运。
四 课程设计的说明:
本来打算用两种方法 (纯 VHDL 的 RTL 级设计,用 system generator 进行系统级的设计)来做一个秒表,比较一下两种设计方法的效率。
但是后来我们觉得这个秒表太简单了,打算再做点什么。不过,我附件里还是附上我做的 VHDL 代码,已经在试验板上调试通过。
后来找到了一个俄罗斯方块程序,我们就打算移植这个程序。我调试成功了 VGA 时序部分,并且作了自己的小方块程序。收集了很多原俄罗斯方
块程序的资料以及 D2SB 开发板和 DIO4 外围板的资料,正是在这些资料的基础上才调通了 BASYS 上的俄罗斯方块程序。另外,为了探索系统级设计,用 labview 和 ise 在一块开发板上作滤波器设计。我们的报告分开做。原始程序代码和报告均已打包送上。
参考资料:
《数字和 DSP 系统平台级设计与实现》课件 郑友泉
《Design of a Tetrix on D2SB》 Fazakas Szabolcs


