前言
之前的第一篇博客讲到了我们这个小游戏的内容和分工,前几个博客也谈到了几个重要的子模块,到现在我们已经实现了所有的底层模块,剩下的还有输出显示模块和顶层模块了。
为什么说这两个模块是顶层模块呢?我们对顶层模块的定义为实现多个模块交互的模块
这可不是简单的调用模块,输入一个时钟信号,得到一个时钟信号(指除颤或者分频),我们需要通过读入使能信号来实现不同的数码管输出方式。
(如果到这里并不清楚数码管的工作逻辑,看这篇博客)
分析
我们在最开始希望构建的输出显示模块就是简单的输8个四位二进制数,然后按照使能端判断主模块的状态来实现输出即可。这里我们也是采用这样的逻辑。
- 既然是4位的数据,我们就需要进行译码,转换成数码管能显示的8位数据。
- 分频是一定要有的模块了,这个不必多说,上面的链接中有完整代码。
- 因为主模块是按照状态来的,所以我们就一个个状态来分析,首先是产生随机数部分,我们的使能端是if_finish,(是在random模块判断读入结束后开始,在按下S1结束的信号)。
这里我们只需要使用5位,第一组数码管的最后一位和第二组数码管的全部,所以前面一组使能端锁定0001,输入数据赋值为out3(从左到右第四个数码管的数据),第二组正常; - 下一个状态是按下S1输入地址,主模块传入的使能端是从按下S1到按下S2之间有效的一个使能端。
我们只需要按照读入地址模块传入的内容进行输出即可,不论是地址有误还是地址正确,模块中都进行了输出数据的赋值,比较良心; - 然后是数据读入的状态,因为有匹配正确和错误两个大状态(这些我们在匹配模块中都进行了使能端的输出来控制)
如果是错误我们还有闪烁的使能端,使能端有效则输出8个0,无效直接将数码管的使能端置零;
正确的情况下,我们只需要七位,所以我们还需要在之前的显示中做一点小处理;另外有一个横的输出,我们创建了变量来进行处理。 - 我们虽然没有复位信号的控制,但是我们因为需要在开机和复位先显示8个常亮的0,所以我将状态外的情况都置为0
上代码
`timescale 1ns / 1ps
//负责亮灯,开机不用管,顶层有初始化
module light(
//输入的内容
input clk,
input s_one,
input s_two,
input flash,
input if_right,
input if_finish,
input [3:0]number1,
input [3:0]number2,
input [3:0]number3,
input [3:0]number4,
input [3:0]number5,
input [3:0]number6,
input [3:0]number7,
input [3:0]number8,
//输出的内容
output reg [7:0]leda,
output reg [7:0]ledb,
output reg [3:0]dn0,
output reg [3:0]dn1
);
reg [7:0]out0; //存放译码结果的寄存器
reg [7:0]out1;
reg [7:0]out2;
reg [7:0]out3;
reg [7:0]out4;
reg [7:0]out5;
reg [7:0]out6;
reg [7:0]out7;
wire clk_o; //分频信号和模块调用
light_divider div1(clk,clk_o);
reg [1:0]count=2'b00; //使能端控制器
reg [7:0]heng = 8'b0000_0010; //没错人家就是那个“横”
//译码部分
always@(number1,number2,number3,number4,number5,number6,number7,number8)
begin
case(number1)
4'b0000: out0 = 8'b1111_1100;
4'b0001: out0 = 8'b0110_0000;
4'b0010: out0 = 8'

本文详细介绍了游戏开发中输出显示模块和顶层模块的设计,包括如何通过使能信号控制数码管的译码输出,以及在不同状态下的逻辑处理,如随机数显示、地址输入和数据匹配。代码实例展示了复杂模块间的交互与简化优化的重要性。
最低0.47元/天 解锁文章
1272

被折叠的 条评论
为什么被折叠?



