在Verilog中,有限状态机(Finite State Machine, FSM)是一种用于描述系统行为的模型,通常用于控制逻辑的设计。FSM由一组状态、状态之间的转换条件以及每个状态下的输出组成。
FSM可以分为两种类型:
FSM的基本组成部分:
Verilog实现FSM的步骤:
示例:简单的Moore型FSM
假设我们要设计一个简单的FSM,它有三个状态:IDLE、STATE1、STATE2,并且根据输入信号input_signal进行状态转移。
module moore_fsm (
input wire clk,
input wire reset,
input wire input_signal,
output reg output_signal
);
// 定义状态
typedef enum reg [1:0] {
IDLE = 2'b00,
STATE1 = 2'b01,
STATE2 = 2'b10
} state_t;
// 状态寄存器和下一个状态变量
state_t current_state, next_state;
// 状态转移逻辑
always @(posedge clk or posedge reset) begin
if (reset) begin
current_state <= IDLE;
end else begin
current_state <= next_state;
end
end
// 下一个状态逻辑
always @(*) begin
case (current_state)
IDLE: begin
if (input_signal) begin
next_state = STATE1;
end else begin
next_state = IDLE;
end
end
STATE1: begin
if (input_signal) begin
next_state = STATE2;
end else begin
next_state = IDLE;
end
end
STATE2: begin
if (input_signal) begin
next_state = IDLE;
end else begin
next_state = STATE2;
end
end
default: begin
next_state = IDLE;
end
endcase
end
// 输出逻辑 (Moore型)
always @(*) begin
case (current_state)
IDLE: output_signal = 1'b0;
STATE1: output_signal = 1'b1;
STATE2: output_signal = 1'b0;
default: output_signal = 1'b0;
endcase
end
endmodule
示例:简单的Mealy型FSM
在Mealy型FSM中,输出不仅依赖于当前状态,还依赖于输入信号。
module mealy_fsm (
input wire clk,
input wire reset,
input wire input_signal,
output reg output_signal
);
// 定义状态
typedef enum reg [1:0] {
IDLE = 2'b00,
STATE1 = 2'b01,
STATE2 = 2'b10
} state_t;
// 状态寄存器和下一个状态变量
state_t current_state, next_state;
// 状态转移逻辑
always @(posedge clk or posedge reset) begin
if (reset) begin
current_state <= IDLE;
end else begin
current_state <= next_state;
end
end
// 下一个状态逻辑
always @(*) begin
case (current_state)
IDLE: begin
if (input_signal) begin
next_state = STATE1;
end else begin
next_state = IDLE;
end
end
STATE1: begin
if (input_signal) begin
next_state = STATE2;
end else begin
next_state = IDLE;
end
end
STATE2: begin
if (input_signal) begin
next_state = IDLE;
end else begin
next_state = STATE2;
end
end
default: begin
next_state = IDLE;
end
endcase
end
// 输出逻辑 (Mealy型)
always @(*) begin
case (current_state)
IDLE: output_signal = 1'b0;
STATE1: output_signal = input_signal ? 1'b1 : 1'b0;
STATE2: output_signal = input_signal ? 1'b0 : 1'b1;
default: output_signal = 1'b0;
endcase
end
endmodule
总结
Moore型FSM:输出仅依赖于当前状态。
Mealy型FSM:输出依赖于当前状态和输入信号。
在Verilog中,FSM的实现通常包括状态定义、状态寄存器、状态转移逻辑和输出逻辑。
通过合理设计FSM,可以实现复杂的控制逻辑,适用于各种数字电路设计场景。
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);//
parameter A=0, B=1;
reg state, next_state;
always @(*) begin // This is a combinational always block
if(areset) begin
next_state = B;
end else begin
case(state)
A: next_state = (in==1'b1) ? A : B;
B: next_state = (in==1'b1) ? B : A;
default: ;
endcase
end
end
always @(posedge clk, posedge areset) begin // This is a sequential always block
// State flip-flops with asynchronous reset
if(areset) begin
state <= B;
end else begin
state <= next_state;
end
end
// Output logic
// assign out = (state == ...);
assign out = (state==B);
endmodule
module top_module(
input clk,
input areset, // Asynchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=0, ON=1;
reg state, next_state;
always @(*) begin
// State transition logic
if(areset) begin
next_state = OFF;
end
case(state)
OFF: begin
next_state = (j==1'b1) ? ON :OFF;
end
ON: begin
next_state = (k==1'b1) ? OFF : ON;
end
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if(areset) begin
state <= OFF;
end else begin
state <= next_state;
end
end
// Output logic
// assign out = (state == ...);
assign out = (state==ON);
endmodule
//====synchronous reset
module top_module(
input clk,
input reset, // Synchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=0, ON=1;
reg state, next_state;
always @(*) begin
// State transition logic
if(reset) begin
next_state = OFF;
end
case(state)
OFF: begin
next_state = (j==1'b1) ? ON :OFF;
end
ON: begin
next_state = (k==1'b1) ? OFF : ON;
end
endcase
end
always @(posedge clk) begin
// State flip-flops with asynchronous reset
if(reset) begin
state <= OFF;
end else begin
state <= next_state;
end
end
// Output logic
// assign out = (state == ...);
assign out = (state==ON);
endmodule
仅实现该状态机的状态转换逻辑和输出逻辑(组合逻辑部分)。 给定当前状态(state),根据状态转换表计算next_state和输出(out)。
module top_module(
input in,
input [1:0] state,
output [1:0] next_state,
output out); //
parameter A=0, B=1, C=2, D=3;
// State transition logic: next_state = f(state, in)
always @(*) begin
case(state)
A: next_state = (in==1'b0) ? A : B;
B: next_state = (in==1'b0) ? C : B;
C: next_state = (in==1'b0) ? A : D;
D: next_state = (in==1'b0) ? C : B;
endcase
end
// Output logic: out = f(state) for a Moore state machine
always @(*) begin
case(state)
A : out = 1'b0;
B : out = 1'b0;
C : out = 1'b0;
D : out = 1'b1;
endcase
end
endmodule
//=====
module top_module(
input clk,
input in,
input areset,
output out); //
parameter A = 4'b0001;
parameter B = 4'b0010;
parameter C = 4'b0100;
parameter D = 4'b1000;
reg[4 -1:0] cur_sta;
reg[4 -1:0] nxt_sta;
// State transition logic
always @(*) begin
if(areset) begin
nxt_sta = A;
end else begin
case(cur_sta)
A: nxt_sta = (in==0) ? A : B;
B: nxt_sta = (in==0) ? C : B;
C: nxt_sta = (in==0) ? A : D;
D: nxt_sta = (in==0) ? C : B;
default: ;
endcase
end
end
// State flip-flops with asynchronous reset
always @(posedge clk or posedge areset) begin
if(areset) begin
cur_sta <= A;
end else begin
cur_sta <= nxt_sta;
end
end
// Output logic
assign out = (cur_sta==D);
endmodule
module top_module (
input clk,
input reset,
input [3:1] s,
output reg fr3,
output reg fr2,
output reg fr1,
output reg dfr
);
parameter A2=0, B1=1, B2=2, C1=3, C2=4, D1=5;
reg [2:0] state, next; // Make sure these are big enough to hold the state encodings.
// Edge-triggered always block (DFFs) for state flip-flops. Synchronous reset.
always @(posedge clk) begin
if (reset) state <= A2;
else state <= next;
end
// Combinational always block for state transition logic. Given the current state and inputs,
// what should be next state be?
// Combinational always block: Use blocking assignments.
always@(*) begin
case (state)
A2: next = s[1] ? B1 : A2;
B1: next = s[2] ? C1 : (s[1] ? B1 : A2);
B2: next = s[2] ? C1 : (s[1] ? B2 : A2);
C1: next = s[3] ? D1 : (s[2] ? C1 : B2);
C2: next = s[3] ? D1 : (s[2] ? C2 : B2);
D1: next = s[3] ? D1 : C2;
default: next = 'x;
endcase
end
// Combinational output logic. In this problem, a procedural block (combinational always block)
// is more convenient. Be careful not to create a latch.
always@(*) begin
case (state)
A2: {fr3, fr2, fr1, dfr} = 4'b1111;
B1: {fr3, fr2, fr1, dfr} = 4'b0110;
B2: {fr3, fr2, fr1, dfr} = 4'b0111;
C1: {fr3, fr2, fr1, dfr} = 4'b0010;
C2: {fr3, fr2, fr1, dfr} = 4'b0011;
D1: {fr3, fr2, fr1, dfr} = 4'b0000;
default: {fr3, fr2, fr1, dfr} = 'x;
endcase
end
endmodule
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
output walk_left,
output walk_right,
output aaah );
parameter WALK_LEFT = 4'b0001;
parameter WALK_RIGHT= 4'b0010;
parameter FALL_LEFT = 4'b0100;
parameter FALL_RIGHT= 4'b1000;
reg[3:0] cur_sta;
reg[3:0] nxt_sta;
always @(posedge clk or posedge areset) begin
if(areset) begin
cur_sta <= WALK_LEFT;
end else begin
cur_sta <= nxt_sta;
end
end
always @(*) begin
if(areset) begin
nxt_sta = WALK_LEFT;
end else begin
case(cur_sta)
WALK_LEFT: begin
if(~ground) begin
nxt_sta = FALL_LEFT;
end else begin
if(bump_left) begin
nxt_sta = WALK_RIGHT;
end else begin
nxt_sta = WALK_LEFT;
end
end
end
WALK_RIGHT: begin
if(~ground) begin
nxt_sta = FALL_RIGHT;
end else begin
if(bump_right) begin
nxt_sta = WALK_LEFT;
end else begin
nxt_sta = WALK_RIGHT;
end
end
end
FALL_LEFT: begin
if(ground) begin
nxt_sta = WALK_LEFT;
end else begin
nxt_sta = FALL_LEFT;
end
end
FALL_RIGHT: begin
if(ground) begin
nxt_sta = WALK_RIGHT;
end else begin
nxt_sta = FALL_RIGHT;
end
end
endcase
end
end
always @(*) begin
walk_left = 0;
walk_right= 0;
aaah = 0;
case(cur_sta)
WALK_LEFT: walk_left = 1'b1;
WALK_RIGHT:walk_right= 1'b1;
FALL_LEFT: aaah = 1'b1;
FALL_RIGHT:aaah = 1'b1;
endcase
end
endmodule