《俄罗斯方块》的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。该项目基于Xilinx公司的EGO1平台,利用现场可编程门阵列FPGA设计了俄罗斯方块小游戏,并且通过VGA接口来实现对屏幕的控制。整个系统由六个模块组成,分别是键盘输入模块、按键输入处理模块、控制模块、数据路径模块、VGA显示模块以及数码管计分模块。玩家通过键盘上的WASD实现对方块的移动和旋转,并且每消除一行就会进行加分。基本原理是将整个显示屏分为10*20的矩阵,不断对矩阵进行更新和判断是否能消除。俄罗斯方块是一个休闲游戏,它面对的是那些没有精力或兴趣玩大型游戏的玩家,这些人需要一类简单好玩的游戏,拿起来就能进入状态,在忙碌的生活中寻求片刻放松。
整个系统采用自上向下的层次化设计方法,顶层模块调用键盘控制模块、按键处理模块、控制模块、数据路径模块、VGA显示模块以及玩家计分模块。系统的总体结构如图图 2‑1 RTL顶层逻辑图所示,其中最左侧的为键盘输入模块,将键盘上面的WASD和空格键数据导入。第二级和第三级为按键输入处理模块,对于输入的信号进行消抖和输出上升沿处理。第四级为信号控制模块也就是最主要的状态机模块,即将输入进来的信号进行区分,并且输出状态的控制信号到下一级。第五级为数据控制信号,接受来自状态机的各种状态输出的信号,对背景矩阵进行不断地判断和更新。第六极第一层为数据输出模块,所要输出的数据为背景矩阵要显示的数据。后面几级分别是数码管显示模块和计分模块。

图 2‑1 RTL顶层逻辑图
基于基本的俄罗斯方块设计方法,设计的俄罗斯方块小游戏可以实现方块的下落、旋转、方块行的消除以及玩家得分的显示。用户通过键盘上面的空格键进行游戏的开始。并通过键盘上面的WASD控制键来实现方块的移动和旋转。当玩家完整的消除一行俄罗斯方块后,数码管上会显示出玩家当前的分数,以供玩家进行参考。如图 2‑2 功能设计展示所示。
图 2‑2 功能设计展示
关于输入输出设计,这部分在总模块会有体现。这里介绍一下。
输入设计,我们使用了FPGA板子上面的100MHz模块clk(P17),用来分频产生脉冲。然后就是复位信号rst(P5)的输入,这里我们使用一个开关,当复位信号有效时,游戏回归初始状态。下面就是5个按键,其中FPGA板子中间的按键用来控制游戏的开始,键盘上面WASD按键控制方块的移动和旋转。
输出设计,我们使用了FPGA板子上面的数码管,所以输出有两个四位的位选信号,还有两个七位的数据信号。除了这些输出,还有控制VGA显示的输出,输出有行同步信号(hsync_r)、场同步信号(vsync_r)、红色变量信号(OutRed)、蓝色变量信号(OutBlue)还有绿色变量信号(OutGreen)。
模块的划分,分别是键盘输入模块、按键输入处理模块、控制模块、数据路径模块、VGA显示模块以及数码管计分模块,展示如图 2‑1 RTL顶层逻辑图所示。
系统的RTL顶层逻辑图如图 2‑1 RTL顶层逻辑图所示,该图展示出了各个模块以及各个模块之间的连线以及输入输出功能。在层次化的设计当中,常常将比较复杂的电路进行模块划分,分成一个个的子模块,然后在顶层模块中通过实例化连接这些子模块。
接收键盘传来的数据相对简单,如图 2‑3 键盘信号所示。当时钟Clock的下降沿时,侦测到数据Data也拉低,代表一个数据包传送出来,之后的10个时钟下降沿,分别收到从最低位LSB到MSB的八位数据,1位的奇偶校验(1表示八位数据中1的位数为偶数,0是奇数),最后1位高电平表示数据包结束。时钟信号由K5检测输入,数据Data由L4检测输入。
图 2‑3 键盘信号
对键盘来说,它用的是扫描码,每个按键对应一个代码,当一个按键被按下,每100ms会重复发送一次;当这个按键被松开,一个0xF0被发出,跟着是那个被松开的按键。那些可以被shift的按键,比如大小写字母和可以代表符号的数字键,它的扫描码后面会跟着shift码,FPGA需要根据这个来决定用哪个ASCII字符。有些按键,比如Ctrl和Alt被按下时,会在扫描码前先发一个E0,当它们被松开时,会发E0F0,并跟随着相应按键的扫描码。
键盘按键主要分为三类,图 2‑4 键盘按键码中展示了它们的通码和断码。
图 2‑4 键盘按键码
俄罗斯方块采用的按键均为第一类按键,通码为1字节,断码为0xF0+通码形式。如A键,其通码为 0x1C,断码为0xF0或0x1C。通过寄存输入的通码或者断码来达到输出W/A/S/D/Space的信号目的。
模块在识别到断码时,保持低电平输出,在检测到通码后进行对应的按键高电平输出。
按键处理模块的主要功能是对输入系统的up,down,left,right四个控制信号进行消抖处理,并对其进行上升沿检测。为了简化控制系统,在本系统的设计过程中,不考虑长时间按键产生连按效果。因而,需要对按键进行上升沿检测。上升沿检测的基本实现方案是加入一组寄存器,对前一个的按键信号进行暂存,将暂存的值与当前值进行比较,当上一个值为0而当前值为1时,即认为其检测到了一个上升沿。
图 2‑5 按键处理模块
控制模块采用有限状态机的方式进行控制,在控制模块中定义了10个状态:
S_idle:空状态,即屏幕显示为空白
S_new:用于产生新的俄罗斯方块。
S_hold:保持状态。在这个状态中进行计时,当时间到达一定间隔时,转到下落状态(S_down);或者等待输入信号(up,down,left,right)时,转到下落状态(S_down)或者(up,left,right)状态。
S_down:判断当前俄罗斯块能否下移一格。如果可以,则转到更新状态,如果不行,则转到更新状态状态。
S_move:判断当前俄罗斯块能够按照按键信号指定的指令进行移动,如果可以,则转到更新状态(S_shift),如果不可以,则转到消除状态1状态(S_remove_1)。
S_shift:更新俄罗斯方块的坐标信息。返回保持状态(S_hold)。
S_remove_1:更新整个屏幕的矩阵信息。转移到消除状态2状态(S_remove_2)。
S_remove_2:判断是否可以消除,将可以消除的行消除,并将上面的行下移一行。重复此过程,直到没有可消除的行为止。跳转判定状态(S_isdie)
S_isdie:判断是否游戏结束。如果结束,则跳转到停止状态(S_stop)。如果没有,则跳转到产生俄罗斯方块状态,生成新的俄罗斯方块。
S_stop:清楚整个屏幕,并跳转到判断状态(S_isdie)。
图 2‑6 状态机总模块
方块分为非活动方块与活动方块。非活动方块为:(1)之前下落的方块;(2)下落后方块消除之后的结果。由背景矩阵表示。活动方块为当前下落中的方块,由活动方块坐标与方块类型表示。
reg [9:0] Background [23:0];
背景矩阵Background是20行10列的reg型数组,负责保存非活动方块坐标,生成20*10的背景矩阵,当背景矩阵某一位置为1时,屏幕显示为白色,否则为黑色。
output reg [4:0] n,
output reg [3:0] m,
n, m分别为当前活动方块的行、列指针,指向方块固定点位置。因为我们要通过W键对方块实现旋转。所以方块固定点为方块旋转时不变的格点,依据方块种类决定。不同的种类有着不同的旋转点。
俄罗斯方块共有7中形状的方块,每种方块有至少一种,至多四种不同的旋转变形方式。为方便起见,将方块和旋转类型分别编号,可以得到一共十九种方块。方块类型如图 2‑3 方块展示列表所示。
图 2‑7 方块展示列表
系统使用计数器产生随机数进入新状态,这里的随机数是一种伪随机,旧状态的值被新状态覆盖。同时,根据计数器,状态值的值刷新为未旋转的俄罗斯方块中的一种中的一种,作为下一次方块。
方块的移动分为四种:分别是旋转,下落,左移,右移。由键盘来控制,方块的移动主要分为两部分:(1)判断;(2)转换
判断分两步:首先,判断变换后方块坐标是否合法,即变换后是否会造成方块越界。然后,判断变换后方块可能占据的新位置是否有背景矩阵方块存在。两步判断通过后返回成功信号,否则失败。
转换过程进行方块的移动或变形。根据KEYBOARD,移动时,改变方块坐标;变形时,方块按类别变换。
方块消除由两个状态来实现,分别是remove1和remove2.
在remove1状态中,将活动方块位置覆盖至R,变为非活动方块。
在remove2状态中,根据满行状态,进行行的消除与平移。
R中的0-3行位于屏幕上方,不进行显示,仅有新生成的方块坐标会进入这一区域。因而,当消除完成后,如R[3]不为空,游戏结束。
VGA 的英文全称是Video Graphic Array,即显示绘图阵列。VGA 支持在
640X480 的较高分辨率下同时显示16种色彩或256 种灰度,同时在320X240 分辨率下可以同时显示256 种颜色。肉眼对颜色的敏感远大于分辨率,所以即使分辨率较低图像依然生动鲜明。计算机内部以数字方式生成的显示图像信息,被显卡中的数字/模拟转换器转变为R、 G、B三原色信号和行、场同步信号,信号通过电缆传输到显示设备中。
这里我们首先对系统自带时钟100MHz进行分频,由于显示屏的参数为640*480*60Hz,所以我们近似处理为25MHz。为了实现发送端与接受端图像各点一一正确对应,发送端与接收端的扫描必须同步。同步脉冲是周期稳定,边沿陡峭的脉冲。按我国电视标准,行同步脉冲的频率等于行频为15.625KHZ,行周期为64us。在电视技术中常以64us 作为时间单位,并以H 表示,即1H=64us。场同步脉冲频率等于场频为50HZ,场周期为 20ms,即312.5H。行同步脉冲宽度为4.7us 左右,场同步脉冲宽度为2.5~3H。
图 2‑8 VGA显示模块
我们利用数码管来显示玩家的得分情况。当判定到某一行信号全部为1可以消除的时候,玩家的分数可以提高并且在数码管上显示出来,数码管前五位显示SCORE,后面三位显示得分,所以得分上限为999分。由于内部原理的设置,每次玩家消除奇数行加23分,偶数行加22分。
图 2‑9 玩家计分模块
| 现态 | 触发条件 | 次态 |
|
|
|
|
| 空状态(S_idle) | Start=1 | 新俄罗斯方块(S_new) |
|
|
|
|
| 新俄罗斯方块(S_new) | 无 | 保持状态(S_hold) |
|
|
|
|
|
| time_cnt = time_val | 下降状态(S_down) |
| 保持状态(S_hold) | (down_reg = 0) (down =1) | 下降状态(S_down) |
|
| 控制信号为1 | 移动状态(S_move) |
|
|
|
|
| 移动状态(S_move) | move_comp=1 | 更新状态(S_shift) |
|
|
|
|
| 更新状态(S_shift) | 无 | 保持状态(S_hold) |
|
|
|
|
| 下降状态(S_down) | down_comp=1 | 更新状态(S_shift) |
|
|
|
|
| 更新矩阵状态(S_remove_1) | 无 | 更新矩阵状态(S_remove_2) |
|
|
|
|
| 更新矩阵状态(S_remove_2) | remove_2_finish=1 | 判断结束状态(S_isdie) |
|
|
|
|
| 判断结束状态(S_isdie) | die = 1 | 清除状态(S_stop) |
|
|
|
|
| 清除状态(S_stop) | 无 | 空状态(S_idle) |
|
|
|
|
1)基本俄罗斯方块功能:方块下落、随机方块的产生、方块能否消除的判断。
2)键盘控制游戏的开始和方块的移动。上升键(W)控制方块的旋转。
3)数码管显示玩家当前的得分情况。
用户主要通过键盘上面的按键来进行操控。
当想要开始进行游戏的时候,按下键盘上面的空格键,游戏开始。玩家通过A和D来控制方块的左移和右移,W键来控制方块的旋转。从而进行俄罗斯方块游戏的使用。
系统的模块化设计流程一般分为设计思路确定、代码编写、RTL逻辑图分析、行为仿真、添加设计约束、设计综合、设计实现和比特流文件生成。
对于已有系统的调试一般在三方面,首先分析设计思路的缺陷,是否存在信号的有效利用,是否存在信号之间的冲突状况等,其次分析代码编写的部分,检查是否有遗漏的部分,对于每种情况下变量能否做到全部赋值,或者在.条件选择的顺序上是否将条件多者放在最前面。最后便是输出输入端口检查,通过RTL顶层逻辑图进行检查信号输出的端口是否符合要求,输入的信号是否通过有效端口进入。
在俄罗斯方块设计过程中曾出现过两个问题:
首先,在键盘检测模块输出的信号不能有效进入状态机当中。具体的原因在于键盘发送的信号仅会在通断码变化时有效区别,因此检测模块的信号持续时间很短。具体分析如下:由于在键盘输入处理的模块当中,只会在键盘通码变化为断码时,在一个clk周期内输出一个按键信号到后面的模块当中,因此由于按键的有效信号很短,因此在后面的按键处理模块当中难以采用相同周期的clk信号采样识别到,因此需要适当延长有效信号输出的时间,帮助后续模块正常检测采样。
因此解决的方法分为两种,首先是引入状态机模块,将短暂的有效信号看作状态的触发信号,从而切换状态,通过不同的状态下重新输出有效信号,并在内部采用计数器,在计数时间结束之后切换回初始状态。其次是利用模块将有效信号延长至可识别的范围之内。从繁琐程度上考虑我们采用了第二种方法,在信号检测模块之后输出进一个信号延时模块当中,通过内部计数器工作,将有效信号延长至0.1s长度,即有效信号输入之后开始计数,此时对应的按键信号输出有效高电平,当达到阈值10000000之后停止计数,此时对应的按键信号输出低电平恢复,然后对应的信号传入后续模块当中,便有效地解决了有效信号持续时间很短的问题。
其次,在设计计分模块当中,由于对于每一次消除方块的操作,状态机的清零信号激活的类别不同,激活的次数也不同,因此难以输出有效的记数信号或分数。原因在于对于消除信号的检测产生了重复,并且在计分器模块当中,进位语句未使用标准的编写方式,产生了寄存现象,从而使得整个计分系统产生了错误。解决的方法是,对于消除信号,偶数行的消除是进行22次行消除,奇数行进行23次行消除,从而对于计数器而言,行数的奇偶不同时,采用的计分规则就不同,并且在进位方面使用标准的计数器语句格式,最终解决了计分结果有误的问题。
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:
我正在尝试创建密码规则来设计可恢复的密码更改。我通过passwords_controller.rb做了一个父类(superclass),但我需要在应用规则之前检查用户角色,但我所拥有的只是reset_password_token。 最佳答案 假设您的模型是用户:User.with_reset_password_token(your_token_here)Source 关于ruby-on-rails-设计通过reset_password_token获取用户,我们在StackOverflow
我已经使用Apartment设置了一个Rails5应用程序(1.2.0)和Devise(4.2.0)。由于某些DDNS问题,应用只能在app.myapp.com下访问(请注意子域app)。myapp.com重定向到app.myapp.com。我的用例是每个注册该应用的用户(租户)都应该通过他们的子域(例如tenant.myapp.com)访问他们的特定数据。用户不应限定在其子域内。基本上应该可以从任何子域登录。重定向到租户的正确子域由ApplicationController处理。根据Devise标准,登录页面位于app.myapp.com/users/sign_in。这就是问题开始的