Multisim数电课设-乒乓球游戏实现-设计分享

题目要求

设计题目

乒乓球游戏机。用LED表示乒乓球位置和球拍。控制球拍在合适的时机击球。一方失球另外一方得分。

期望功能

1).设置8个LED表示球的位置,球可以往复运动

2).球运动到最边缘时,检测到按键按下,模拟将球击回向另外一侧运动。

3).设置发球机制。设置预备阶段,预备阶段时将球归位在中间,按下发球按钮后球开始向一侧开始运动。

4).按键在非边缘处按下(抢球),或者到边缘时不按下(丢球),则回到预备阶段,并且另外一方得分(以LED二进制表示)首先拿到三分的一方胜利。

意义

进一步掌握常用数字电路元件的使用(如计数器、译码器等),了解数字电路设计的基本流程。

设计软件选择

选择Multisim软件设计电路设计。Multisim是美国国家仪器(NI)有限公司推出的以Windows为基础的仿真工具,适用于板级的模拟/数字电路板的设计工作。它包含了电路原理图的图形输入、电路硬件描述语言输入方式,具有丰富的仿真分析能力。Multisim提炼了SPICE仿真的复杂内容,这样我们无需懂得深入的SPICE技术就可以很快地进行捕获、仿真和分析新的设计,比较简洁好用。

图 1 使用的电路设计软件:Multisim

电路设计基本原理及分析

基础准备

使用器件

根据实验要求,需要预先构思好需要使用的器件。

  • 基础器件:发光二极管、电阻、按键、时钟源、偏置电源与地(仿真)
  • 组合逻辑器件:基础的与或非门,选用了74LS08D(与门)、74LS32D(或门)和74LS04D(非门)
  • 时序逻辑器件:需要控制LED,因此需要使用3-8译码器,选用型号为74LS138D;需要控制LED跳变(小球按节拍运动),因此需要计数器,选用型号为74LS191D;此外,预想需要控制计数器的复位与置位来实现功能,因此加入D触发器,时钟管脚悬空,只接CLR与PR端作为置位复位器,选用型号为74LS74D。
  • 输出器件:选用LED进行输出得分,因此需要74LS160D进行输出控制(驱动)。

图 2 使用器件一览

基本小球运动功能实现

小球显示模拟

小球使用LED进行模拟。如图:

图 3 小球显示模拟

使用共阳级LED组,通过控制阴极电平高低实现LED的亮灭。因为用LED灯模拟小球,需要lED的编码是8位独热码编码形式,因此需要3-8译码器将二进制值转为独热码形式,即可以通过二进制的值控制LED小球的位置,如图:

图 4 小球位置控制

通过74LS138D,将CBA二进制数转为Y0-Y7,控制单个LED亮灭。电阻的作用是限流,防止LED击穿。

小球运动模拟

经过3-8译码器后,小球的运动本质是二进制码的递增与递减,而让小球以一定的速度匀速运动,就是跟随着时钟的节拍对二进制码计数。因此我们需要使用计数器,这里选用74LS191D进行计数控制,搭建好电路如图:

图 5 小球运动模拟

因为74LS191D为16进制计数器,即4位二进制数,我们只需要3位二进制数据即可控制LED,因此将74LS191D低3位接入3-8译码器。这样,通过控制74LS191D的功能端口,就可以控制小球的运动方式。其中74LS191D的功能端口还未接线,查阅74LS191D的真值表,如图:

图 6 同步十六进制可逆计数器74LS191的图形符号及功能表

图6表中LD‘即为图5中LOAD管脚。根据功能表,我们知道可以通过LD’置0,同时ABCD接固定电平,让小球停在指定位置;通过LD‘置1,U’/D置0或1可以让小球向右运动或向左运动。由期望功能可知,电路中很多操作均为按键操作,即只产生电平脉冲。想要通过脉冲信号实现对74LS191D的功能端口置1、置0,考虑使用D触发器实现。查阅D触发器74LS74D功能表如图:

因为只需要单纯实现置位复位,因此D触发器时钟引脚悬空,只接入反置位PR、反复位CLR和输出Q三个管脚。连接如图:

图 7 D触发器控制计数器示意图

这样就可以初步实现,将脉冲信号转化为置位复位电平信号来驱动74LS191D的功能引脚,进而驱动LED的运动。

裁判发球机制

现在设计裁判发球机制。期望功能为:有一个预备状态,按下发球按钮后脱离预备状态,小球开始运动。根据上述推理,只需要通过D触发器,给计数器的LD’管脚置0让计数器一直处于置位状态,同时设置合适的预置数使小球在中间位置,即可设置好预备状态。经过计算,预置数为0100时可使小球位于中间。将裁判按键接入D触发器的CLR端,当按下按键时,产生高电平脉冲,经过反复位CLR端在Q处产生置1信号,从而使计数器脱离置位状态,进入计数状态,小球即开始运动。D触发器的变化如图:

图 8 裁判按键按下后电平变化示意图

打球机制(成功接球、丢球、抢球与得分)

以上,时序逻辑已经设计完毕,我们设计打球逻辑,打球逻辑的本质是组合逻辑,即采集电路的状态与按键输入,输入到组合逻辑(门电路)进行计算,组合逻辑计算出相应的输出,将输出信号给到74LS160D和D触发器,进行相应操作。由于是使用按键打球,因此产生的输出信号基本为脉冲信号,在之前的时序设计已经通过D触发器进行处理。

成功接球:

首先是成功接球的判定,我们认为当最边缘的LED亮起的一段时间,对应方的按键按下,判定为成功接球。需要的现象为“球被打回去”,即让计数器反向计数,可通过对\overline{U}/D管脚翻转实现。

    设置布尔变量完成组合逻辑。已知Y0为最左侧LED对应阴极电平,Y7为最右侧LED对应阴极电平,当Y0、Y7为0时LED亮起。设左侧按键为K_1,右侧按键为K_2,左右按键按下时K1K2均为1。设接入计数器\overline{U}/D管脚的D触发器的反置位、反复位引脚为PR1CLR1,则只需令:


PR_1=K_1Y_0^\prime

CLR_1=K_2Y_7^\prime

即可实现接球逻辑。原理为:满足K_1Y_0^\prime=1时认为左边接到球,球从左向右“打回去”,则计数器应向右计数,即加法计数,\overline{U}/D管脚复位,将PR1管脚接到K_1Y_0^\prime,产生高电平脉冲即可。满足K_2Y_7^\prime=1时认为右边接到球,球从右向左“打回去”,则计数器应向左计数,即减法计数,\overline{U}/D管脚置位,将CLR1管脚接到K_2Y_7^\prime,产生高电平脉冲即可。实际实现逻辑电路如图:

图 9 成功接球部分组合逻辑(绿线)

此时,经过仿真验证,我们已经可以玩起来乒乓球了,即不丢球的情况下,每次都成功接球,左右两边可以打的“有来有回”。

丢球、抢球逻辑

接下来设计失误时的逻辑。我们希望:当有一方没接住球(丢球,即球已经走过去还没接球)、或者提前接球(抢球,即在边缘LED灯没亮时接球)时,球桌回复预备状态,球静止在中间等待发球,并且对面的得分加一分(在得分逻辑中叙述)。

由前所述,预备状态的打破(发球)由接入L'D的D触发器CLR2引脚实现,相应的,预备状态的建立则可以由其PR2引脚实现。类似发球逻辑中的分析,当PR2引脚输入高电平脉冲,经过D触发器在Q处产生置0信号,从而使计数器脱离计数状态,进入置位状态即预备状态,LED的位置锁定在中间,等待下一次发球。

因此,我们需要做的工作即:收集失误的信号,经过组合逻辑计算最终输出到PR2引脚,使得失误时在PR2引脚产生高电平脉冲,进入预备状态。

我们用布尔代数设计组合逻辑。不妨设R0表示右侧失误,L0表示左侧失误。首先看抢球,借用之前设计“成功接球”的布尔变量,若将抢球定义为:边缘一侧灯还没亮(球还没到)时,就按下了按钮。则容易得出K2Y7就表示右侧抢球,K1Y0就表示左侧抢球。

之后我们看丢球。我们将丢球定义为:当LED到达边缘时,那一侧的按键未按下。此时成功接球,让计数方向翻转的逻辑将不会运行,即小球将“飞出球桌”。由之前“小球运动模拟”的叙述,此时计数器仍然在继续计数(加法计数是向高位进1后继续计数,减法计数是减到0000后从1111继续计数),将二进制值跳转到了下一个数。因此我们可以根据计数器的计数值是否越界判断是否丢球,如图:

图 10 丢球时计数器的越界示意图

通过布尔代数描述丢球逻辑。由图易知,当QDQC=1时,发生左越界,左侧丢球;当QDQ'C=1时,发生右越界,右侧丢球;

由于丢球与抢球均为失误,任何一方发生任意一项均重新开始比赛,回到预备状态,因此事件之间使用与门连接。完整的输出表达式为

PR_2=R_0+L_0

R_0=K_2Y_7+Q_D{Q\prime}_C

L_0=K_1Y_0+Q_DQ_C

实际电路连接实现组合逻辑电路如图:

图 11 丢球、抢球组合逻辑电路图(绿框)

得分逻辑

当一方失误时,另一方得分。最后分数显示一方各使用两个LED,由74LS160D驱动。之前已经算出失误时产生的R0,L0,将74LS160D功能端均接高电平,设为计数模式,将R0,L0分别接入左侧与右侧的74LS160D的CLK接口,实现得分计数并输出到LED,如图:

综上,完整的仿真电路图如图:

图 12 完整的仿真电路图

经过仿真验证,可以成功实现打乒乓球的功能。

结语

这篇文章其实是之前数电课设的设计报告截取的一部分(还有设计心得之类的一些废话hhh),报告完全原创,电路原理参考了一些资料,不过这门课最后拿的分数倒不太理想(可能是心得写少了XD)。现在看挺适合作为教程,贴出来给以后要做数电课设的同学作参考。

### 乒乓球游戏设计 Verilog 实现方案 #### 设计概述 乒乓球游戏机的设计旨在创建一个能够模拟真实乒乓球运动的小型化备。该游戏通过LED矩阵展示虚拟球台和球的位置变化,并利用码管显示当前的比赛分。整个系统由多个子模块构成,包括但不限于分频器、随机发生器以及用于控制游戏流程的状态机。 #### 系统架构 系统的总体结构可以被划分为两大主要部分:一是负责处理游戏逻辑并驱动视觉反馈的游戏主控单元;二是专门用来管理得分统计及其可视化呈现的记分板组件[^2]。 #### 关键模块解析 ##### 分频模块 (5Hz) 为了确保游戏中物体的动作频率适合人类观察者感知,在顶层文件中集成了一个特定频率下的时钟脉冲生成装置——即所谓的“分频模块”。此部件的作用在于接收来自外部晶振所提供的高速周期波形作为输入源,经过内部算法转换后输出较低速率却稳定可靠的同步信号供后续环节调用[^1]。 ```verilog module clock_divider ( input wire clk_in, output reg clk_out ); parameter DIVIDER = 50_000_00; // Adjust based on the desired frequency and system clock rate. integer count; always @(posedge clk_in) begin if(count >= DIVIDER - 1) begin count <= 0; clk_out <= ~clk_out; end else begin count <= count + 1; end end endmodule ``` ##### 随机生成 为了让每次发球都具备不可预测性,引入了一个伪随机序列生产函。该机制能够在不影响整体性能的前提下赋予游戏更多变,增加娱乐性和挑战度。 ```verilog // Example of a simple Linear Feedback Shift Register (LFSR) for random number generation module lfsr_random_generator( input wire clk, input wire reset, output reg [7:0] rand_num ); reg [7:0] state; always @(posedge clk or posedge reset) begin if(reset) state <= 8'b1; else state <= {state[6], state[7]^state[4], state[5:1]}; end assign rand_num = state; endmodule ``` ##### 核心状态机 核心状态机是整个项目的核心所在,它决定了如何响应用户的按键操作以及何时更新屏幕上的图像元素。根据预规则评估每一帧内发生的事件(比如是否成功接住了飞来的球),进而决定下一步的操作方向[^5]。 ```verilog typedef enum logic [2:0] { IDLE, SERVE_BALL, MOVE_BALL, CHECK_HIT, UPDATE_SCORES } game_state_t; module pong_game_controller( input wire clk, input wire rst_n, input wire player_hit_btn, ... ); game_state_t current_state, next_state; always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) current_state <= IDLE; else current_state <= next_state; end always_comb begin case(current_state) IDLE: /* Initialization code */ next_state = SERVE_BALL; SERVE_BALL: /* Serve ball initialization */ next_state = MOVE_BALL; MOVE_BALL: /* Ball movement update */ if(/* condition to check hit */) next_state = CHECK_HIT; CHECK_HIT: /* Check whether players have successfully hit the ball */ if(player_hit_btn && /* valid hit conditions */ ) next_state = UPDATE_SCORES; else if(/* miss conditions*/) next_state = UPDATE_SCORES; else next_state = MOVE_BALL; UPDATE_SCORES: /* Update scores after each round ends */ next_state = SERVE_BALL; default: next_state = IDLE; endcase end ... endmodule ``` #### 测试与验证 在整个开发过程中建立完善的测试环境至关重要。这不仅有助于发现潜在缺陷,还能提高最终产品的质量。通常会借助ModelSim这样的工具来进行详尽的功能仿真,同时配合Quartus II完成必要的综合布局布线工作,最后部署至目标FPGA器件上运行实际测试案例.
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值