状态机
Mealy状态机:输出不但取决于状态还取决于输入。
Moore状态机:输出只取决于当前状态
设计题目:将下列状态图分别用一段式、二段式、三段式状态机实现
如下图用verilog实现
1、一段状态机
一个模块既包含状态转移,又包含组合逻辑输入/输出。
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2018/12/05 21:04:31
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module test(
clk,rst_n, z_o,a_i,current_state
);
//数据声明部分
input clk,rst_n;
input a_i;
output reg z_o;
output current_state;
//参数声明
parameter S0= 3'd0;
parameter S1 = 3'd1;
parameter S2 = 3'd2;
parameter S3 = 3'd3;
parameter S4 = 3'd4;
parameter S5 = 3'd5;
//内部信号声明
reg[2:0] current_state;
//状态跳转逻辑程序设计
always @(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
z_o<= 0;
current_state <= S0;
end
else begin
case(current_state)
S0: begin
if(a_i) begin
current_state <= S1;
end
else begin
current_state <= S0;
end
z_o<=0;
end
S1: begin
if(a_i) begin
current_state <= S1;
end
else begin
current_state <= S2;
end
z_o<=0;
end
S2: begin
if(a_i) begin
current_state <= S1;
end
else begin
current_state <= S3;
end
z_o<=0;
end
S3: begin
if(a_i) begin
current_state <= S4;
end
else begin
current_state <= S0;
end
z_o<=0;
end
S4: begin
if(a_i) begin
current_state <= S1;
end
else begin
current_state <= S5;
end
z_o<=0;
end
S5: begin
if(a_i) begin
current_state <= S1;
end
else begin
current_state <= S3;
end
z_o<=1;
end
endcase
end
end
endmodule
2、两段式状态机
一个always语句实现时序逻辑,一个always语句实现组合逻辑。提高了代码的可读性和可维护性,它需要定义一个两个状态---现态和次态。通过现态和次态的转换来实现逻辑。
module test(
clk,rst_n, z_o,a_i,current_state
);
//数据声明部分
input clk,rst_n;
input a_i;
output reg z_o;
output current_state;
//参数声明
parameter S0= 3'd0;
parameter S1 = 3'd1;
parameter S2 = 3'd2;
parameter S3 = 3'd3;
parameter S4 = 3'd4;
parameter S5 = 3'd5;
//内部信号声明
reg[2:0] current_state;
reg[2:0] next_state;
//状态跳转逻辑程序设计
always @(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
current_state<= S0;
end
else
current_state<= next_state;
end
//状态输出逻辑设计
always @(current_state)
begin
case(current_state)
S0: begin
if(a_i) begin
next_state <= S1;
end
else begin
next_state <= S0;
end
z_o<=0;
end
S1: begin
if(a_i) begin
next_state <= S1;
end
else begin
next_state <= S2;
end
z_o<=0;
end
S2: begin
if(a_i) begin
next_state <= S1;
end
else begin
next_state <= S3;
end
z_o<=0;
end
S3: begin
if(a_i) begin
next_state<= S4;
end
else begin
next_state<= S0;
end
z_o<=0;
end
S4: begin
if(a_i) begin
next_state <= S1;
end
else begin
next_state <= S5;
end
z_o<=0;
end
S5: begin
if(a_i) begin
next_state<= S1;
end
else begin
next_state<= S3;
end
z_o<=1;
end
endcase
end
endmodule
3、三段式状态机程
在FPGA逻辑设计中,如果状态机比较大,需要的状态转移、信号等的处理比较复杂,建议使用三段式状态机来完成设计。
优点:
(1)将组合逻辑和时序逻辑分开,利于综合器分析优化和程序维护;
(2)更符合设计的思维习惯;
(3)代码少,比一段式状态机更简洁。
module finite_fsm(
z_o,
clk,
Rst_n,
a_i
);
//输出端口
output z_o;
//输入端口
input clk;
input Rst_n;
input a_i;
//输出端口类型声明
reg z_o;
//参数声明
parameter S0= 3'd0;
parameter S1 = 3'd1;
parameter S2 = 3'd2;
parameter S3 = 3'd3;
parameter S4 = 3'd4;
parameter S5 = 3'd5;
//内部信号声明
reg[2:0] current_state;
reg[2:0] next_state;
//状态寄存器
always @ (posedge clk or negedge Rst_n) begin
if(!Rst_n)
current_state <= S0;
else
current_state <= next_state;//控制次态
//次态的组合逻辑
always @ (a_i or current_state) begin
case(current_state)
S0:begin
if(a_i) next_state = S1;
else next_state = S0;
end
S1: begin
if(a_i) next_state = S1;
else next_state = S2;
end
S2: begin
if(a_i) next_state = S1;
else next_state = S3;
end
S3: begin
if(a_i) next_state = S4;
else next_state = S0;
end
S4: begin
if(a_i) next_state = S1;
else next_state =S5;
end
S5: begin
if(a_i) next_state = S1;
else next_state = S3;
end
default : next_state = 3'bxx;
endcase
end
//输出逻辑
always @ (*) beign
case(current_state)
S0: z_o = 1'b0;
S1: z_o = 1'b0;
S2: z_o = 1'b0;
S3: z_o = 1'b0;
S4: z_o = 1'b0;
S5: z_o = 1'b1;
default: z_0 = 1'b0;
endcase
end
endmodule