这是一篇适用于P0,P1状态机的做题思路分享

写在开头

在度过Pre通过的快乐或是不通过的悲伤之后,很快我们会迎来真正的考验,从P0开始一直到P1,我们将要面对的一个主要问题就是状态机,而状态机一般在P0中占据两题的位置,P1中占据三题的位置,所以我们可以说,状态机这一关过不去,我们的实验将止步于P0。
但是,在笔者看来,状态机反而是最为简单,最为模板化的一类题,一旦掌握,则成竹在胸,很难出现意外。今天我们就来聊一聊状态机的是是非非。
虽然笔者也极力反对这种刻板化做题的行为,但不得不说,对于状态机而言,一直用一直爽!

状态机基础知识

Moore型状态机

关键点:输出信号与当前状态相关
Moore型状态机

Mealy型状态机

关键点:输出信号与当前状态输入信号有关
Mealy型状态机
没错,做题只需要知道这么多,两句话两个图!

做题模板

Logisim

状态机示例1
状态机示例2
仔细观察笔者每一道题,细心的大家一定会发现,笔者的搭建完全按照状态机基础知识中的那两个图进行搭建,线多也只是因为笔者图方便,每一条线代表一位,而基础知识中的那几个图一条线代表很多位,经此而已,所以,搭建:输入-状态转移模块-寄存器-输出模块-输出的框架,这便是第一步。
第二步也很简单:根据题意分析出状态转移,直接使用Logisim分析电路,利用真值表建立两个模块,游戏结束。
分析电路
第三步就是考虑题目的特殊组合电路,即有些题目会不仅仅考虑状态机的事情,可能会有一些额外的输出,这些就是利用电路的组合即可解出,比如第一张图中的Hit输出(不属于状态机的内容)

Verilog

如果说Logsim或许由于大家不熟悉这种手搓电路的形式感觉有一点点难度,那么Verilog作为一个用代码描述电路的语言,学了一年C语言的我们将会更加得心应手

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
`timescale 1ns / 1ps
`define S0 2'b00 //宏定义状态便于后续描述
`define S1 2'b01
`define S2 2'b10
module id_fsm(
input [7:0] char, //输入
input clk,
output out
);
reg [1:0] status=2'b00; //寄存器
always @(posedge clk) begin //输入和状态转移模块
case (status)
`S0: begin
if(char >= 8'd48 && char <= 8'd57) begin
status <= `S0; end
else if(char >= 8'd65 && char <=8'd90) begin
status <= `S1; end
else if(char >= 8'd97 && char <=8'd122) begin
status <= `S1; end
else begin
status <= `S0; end
end
`S1: begin
if(char >= 8'd48 && char <= 8'd57) begin
status <= `S2; end
else if(char >= 8'd65 && char <=8'd90) begin
status <= `S1; end
else if(char >= 8'd97 && char <=8'd122) begin
status <= `S1; end
else begin
status <= `S0; end
end
`S2: begin
if(char >= 8'd48 && char <= 8'd57) begin
status <= `S2; end
else if(char >= 8'd65 && char <=8'd90) begin
status <= `S1; end
else if(char >= 8'd97 && char <=8'd122) begin
status <= `S1; end
else begin
status <= `S0; end
end
endcase
end
assign out = (status==`S2)? 1'b1:1'b0; //输出模块和输出(Moore型)
assign out = (status==`S2 && char == "A") //输出模块和输出(Mealy型)
endmodule

笔者做题感觉,在P1中对于Moore状态机的考察会比Mealy多一些,但在Verilog下这些都大差不差,都可以分解为定义+always块+assign语句(输出)
定义:输入和状态寄存器。
always块:状态转移,无脑Switch+if else语句判断即可,在笔者看来比Logisim都简单。
assign:输出电路,根据不同状态机类型选择不一样的判断条件。
若该题有特殊输出,则可考虑新建立信号,并继续用assign语句输出

练习方式

当然,笔者这里所说可能对于刚入门的大家不太能理解,所以我们需要在练习中感受思路,这里提供一下当时笔者练习的方式。

Logisim:

1.上机前一天将课下重做一遍,保持手感。
2.见前一篇文章,获取白金版CSCore

Verilog:

1.上机前一天将课下重做一遍,保持手感。
2.HDLBits,这是一个Verilog练习网站,类似于大一的OJ,洛谷。学有余力可以做一做这里的题,可能会有小惊喜。

(笔者只在这里做了一道题,然而这道题就成为了笔者的P1上机第三题,真是世事难预料!)
HDLBits