前言
之前的那个讲解配的是一个八位串行输入,总感觉怪怪的,这次我们看一个并行输入的例子。
检测一个不定长度的串中01011字串的个数并在一个数码管上显示。
我们有一个控制输入的按键开关,还有一个异步清零&状态归零的复位键。
分析
一位数码管最大显示数也就是0Fh,相当于十六进制的15,所以我们需要一个四位数的计数器。
将计数部分拿出来作为一个单独的模块,将四位数使用数码管显示的模块也单独拿出来当然这里的数码管显示没有之前那么复杂。
信号还需要一个除颤模块(点击查看之前的讲解),我也尝试过没有除颤,状态会发生跳动,确实是不稳定。(除颤还需要一个1KHZ的分频子模块)
主模块只需要将这些模块串起来,然后调整中间变量即可。
另外我们这个例子是不可覆盖的,如果是101这样的序列我们还需要考虑一下是否是覆盖的
(10101算几个?)
所以主要的部分还是计数的状态机。
这里先使用Moore来进行。(主模块还添加一个led灯判断状态正确与否)
Moore实现
之前说了,上一篇讲状态机的博客采用的是单个状态变量,其实我们也可以用两个变量来实现,即现态和次态分开,但是在输入的过程中因为我们的状态受输入的控制,所以现态是比输入晚一拍的,所以我们不需要两个状态即可实现。
白嫖上一篇博客的状态转换:

首先我们还是采用三段式来描述:
- 处理输入的模块
- 每次读入一个数据,我们进行一次状态转化,记住只有一次
- 如果状态正确,我们就将个数加一
我们也说过正经的状态机都是一个时序部分(状态转换),两个组合(输入输出),但是我们这老不当人的,因为是拨码开关的输入,所以我们还是需要将拨码开关信号作为时钟信号来进行处理。
题外话
我们是可以将任意信号作为时钟端进行处理,但是如果是像这样的将输入控制使能端作为always块唯一的posedge,那么就会显示一个报错:
[fil[Place 30-574] Poor placement for routing between an IO pin and BUFG. If this sub optimal condition is acceptable for this design, you may use the CLOCK_DEDICATED_ROUTE constraint in the .xdc file to demote this message to a WARNING. However, the use of this override is highly discouraged. These examples can be used directly in the .xdc file to override this clock rule.
< set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets set_i_IBUF] >
set_i_IBUF_inst (IBUF.O) is locked to IOB_X1Y34
and set_i_IBUF_BUFG_inst (BUFG.I) is provisionally placed by clockplacer on BUFGCTRL_X0Y0
每一个人的报错可能不一样,但是内容相差不大,原因就是因为将信号作为了时钟信号,所以我们需要在约束文件中添加尖括号里面的内容:
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets set_i_IBUF]

上代码:(计数部分)
`timescale 1ns / 1ps
module count(
input clk_i, //时钟信号
input rst_i, //重置使能,高有效
input set_i, //输入使能
input data_i,
output [3:0]number, //输出的个数
output [2:0]state_o //led灯,判断一下状态转换
);
reg in = 1'b1; //读入的数据,初始化为1防止1011
reg if_in1 = 1'b0; //输入端使能
reg if_in2 = 1'b0;
reg if_add1 = 1'b0; //自增使能
reg if_add2 = 1'b0;
reg [3:0]counter = 4'b0000; //下面四句为处理输出变量赋初值问题的
reg [2:0]state = 3'b001

最低0.47元/天 解锁文章
5214

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



