有限状态机简介
电路结构
由组合逻辑电路和存储电路组成。组合逻辑可以分为C1和C2部分。
经典状态机结构示意图
'111’序列检测器
设计一个“111”序列检测器,当输入三个或三个以上的“1”时,电路输出为1,否则为0。
Moore状态机
Moore状态机的输出仅依赖于当前状态而与输入无关。
有限状态机的结构
状态转移图
代码实现
功能模块:
三段式
// seqdata_moore
module seqdata_moore (
output reg dout,
input wire clk,
input wire rst,
input wire din
);
reg [1:0] curr_state;
reg [1:0] next_state;
parameter IDLE = 2'b 00;
parameter S1 = 2'b 01;
parameter S2 = 2'b 10;
parameter S3 = 2'b 11;
always @ (posedge clk or negedge rst) begin
if (!rst)
curr_state <= IDLE;
else
curr_state <= next_state;
end
always @ (*) begin
case (curr_state)
IDLE:
if (din == 1) next_state <= S1;
else next_state <= IDLE;
S1:
if (din == 1) next_state <= S2;
else next_state <= IDLE;
S2:
if (din == 1) next_state <= S3;
else next_state <= IDLE;
S3:
if (din == 1) next_state <= S3;
else next_state <= IDLE;
default:
next_state <= IDLE;
endcase
end
// 体现了Moore机的特点:输出由当前状态决定
always @ (*) begin
if (curr_state == S3) dout <= 1;
else dout <= 0;
end
endmodule
两段式
// seqdata_moore
module seqdata_moore (
output reg dout,
input wire clk,
input wire rst,
input wire din
);
reg [1:0] curr_state;
reg [1:0] next_state;
parameter IDLE = 2'b 00;
parameter S1 = 2'b 01;
parameter S2 = 2'b 10;
parameter S3 = 2'b 11;
always @ (posedge clk or negedge rst) begin
if (!rst)
curr_state <= IDLE;
else
curr_state <= next_state;
end
// 将组合逻辑合成一段
always @ (*) begin
case (curr_state)
IDLE:
if (din == 1) begin next_state <= S1; dout <= 0; end
else begin next_state <= IDLE; dout <= 0; end
S1:
if (din == 1) begin next_state <= S2; dout <= 0; end
else begin next_state <= IDLE; dout <= 0; end
S2:
if (din == 1) begin next_state <= S3; dout <= 0; end
else begin next_state <= IDLE; dout <= 0; end
S3:
if (din == 1) begin next_state <= S3; dout <= 1; end
else begin next_state <= IDLE; dout <= 1; end
default: begin next_state <= IDLE; dout <= 0; end
endcase
end
endmodule
测试模块:
// testbench of 'seqdata_moore'
module seqdata_tb ();
wire dout;
reg clk;
reg rst;
reg din;
seqdata_moore seqdata_moore0 (.dout(dout), .clk(clk), .rst(rst), .din(din));
always #10 clk = ~clk;
initial begin
clk = 0;
rst = 0;
din = 0;
#50 rst = 1;
#20 din = 1;
#20 din = 0;
#20 din = 1;
#40 din = 0;
#20 din = 1;
#60 din = 0;
#20 din = 1;
end
endmodule
仿真波形:
Mealy状态机
Mealy状态机的输出与当前状态和输入有关。
有限状态机的结构
状态转移图
代码实现
功能代码:
module seqdata_mealy (
output reg dout,
input wire clk,
input wire rst,
input wire din
);
reg [1:0] curr_state;
reg [1:0] next_state;
parameter IDLE = 2'b 00;
parameter S1 = 2'b 01;
parameter S2 = 2'b 11;
always @ (posedge clk or negedge rst) begin
if (!rst)
curr_state <= IDLE;
else
curr_state <= next_state;
end
always @ (*) begin
case (curr_state)
IDLE:
if (din == 1) begin next_state <= S1; dout <= 0; end
else begin next_state <= IDLE; dout <= 0; end
S1:
if (din == 1) begin next_state <= S2; dout <= 0; end
else begin next_state <= IDLE; dout <= 0; end
S2:
if (din == 1) begin next_state <= S2; dout <= 1; end
else begin next_state <= IDLE; dout <= 0; end
default: begin next_state <= IDLE; dout <= 0; end
endcase
end
endmodule
测试代码同Moore
有关三段式和两段式的对比
- 三段式:状态转移由一个always块实现,根据当前状态来确定输出有另一个always块实现
- 两段式:状态转移和输出在一个always块中实现
- 三段式并不是一定要写三个always块。如果状态机更为复杂,always块也会相应增加
(例如交通灯状态机:交通灯状态机)
有关可重叠和不可重叠序列的对比
- 该处"111"序列检测的摩尔机和米利机都是可重叠序列检测
(有关不可重叠和可重叠的举例:链接: 101序列检测器.)