状态机是一种带有条件判断的顺序执行。
状态机分为
Mealy型:输出不仅与当前状态有关,还与输入有关。(马尔可夫)
Moore型:输出至于当前状态有关。
状态机设计:
一段式:一个always块时序逻辑既描述状态转移,又描述数据输出。
二段式:一个always块时序逻辑描述状态转移,另一个always块组合逻辑描述数据输出。
三段式:一个always块时序逻辑描述状态转移,一个always块描述组合逻辑判断状态转移条件,另一个always块时序逻辑或组合逻辑描述数据输出。
面试常见的手撕代码,自动售货机:售货机商品3元每件,每次只能投入1元硬币,每满3元自动售出一件商品。
状态转移图:
一段式状态机:
module zidongshouhuoji_yiduanshi(
input wire clk ,
input wire rst_n ,
input wire money_flag ,
output reg thing_out
);
//定义状态变量
reg [1:0] state ;
//一段式状态机
always @(posedge clk or negedge rst_n)begin
if (rst_n == 1'b0)begin
state <= 2'b00 ;
thing_out <= 1'b0 ;
end
else begin
case(state)
2'b00: begin
if(money_flag == 1'b1)begin
state <= 2'b01 ;
thing_out <= 1'b0 ;
end
else begin
state <= 2'b00 ;
thing_out <= 1'b0 ;
end
end
2'b01: begin
if(money_flag == 1'b1)begin
state <= 2'b10 ;
thing_out <= 1'b0 ;
end
else begin
state <= 2'b01 ;
thing_out <= 1'b0 ;
end
end
2'b10: begin
if(money_flag == 1'b1)begin
state <= 2'b00 ;
thing_out <= 1'b1 ;
end
else begin
state <= 2'b10 ;
thing_out <= 1'b0 ;
end
end
default: begin
state <= 2'b00 ;
thing_out <= 1'b0 ;
end
endcase
end
end
endmodule
两段式状态机:
//两段式状态机
//第一段描述状态转移
always @(posedge clk or negedge rst_n)begin
if (rst_n == 1'b0)begin
state <= 2'b00 ;
end
else begin
case(state)
2'b00: begin
if(money_flag == 1'b1)begin
state <= 2'b01 ;
end
else begin
state <= 2'b00 ;
end
end
2'b01: begin
if(money_flag == 1'b1)begin
state <= 2'b10 ;
end
else begin
state <= 2'b01 ;
end
end
2'b10: begin
if(money_flag == 1'b1)begin
state <= 2'b00 ;
end
else begin
state <= 2'b10 ;
end
end
default: begin
state <= 2'b00 ;
end
endcase
end
end
//第二段状态机描述输出
always @(posedge clk or negedge rst_n)begin
if (rst_n == 1'b0)begin
thing_out <= 1'b0 ;
end
else if((state == 2'b10) && (money_flag == 1'b1)) begin
thing_out <= 1'b1 ;
end
else begin
thing_out <= 1'b0 ;
end
end
仿真:
`timescale 1ns/1ns
module shouhuoji_tb();
reg clk ;
reg rst_n ;
reg money_flag ;
wire thing_out ;
initial begin
rst_n = 0 ;
clk = 0 ;
// money_flag = 0 ;
#100 ;
rst_n = 1 ;
end
always #10 clk = ~clk ;
always #20 money_flag <= {$random} ;
zidongshouhuoji_liangduanshi zidongshouhuoji_yiduanshi(
. clk (clk) ,
. rst_n (rst_n) ,
. money_flag (money_flag) ,
. thing_out (thing_out)
);
endmodule
仿真结果: