状态机中主要包含三个对象:
-现态 current state CS
-次态 next state NS
-输出逻辑 out logic OL
描述方式:
①三段式描述:CS、NS、OL各自采用一个always语句块描述。
②两段式描述:CS+NS采用一个always语句块描述,OL采用一个always语句块描述。or CS采用一个always语句块描述,NS+OL采用一个always语句块描述。
③单段式描述:CS+NS+OL都放在一个always语句块描述。
应该选择哪一种状态机 ?
Moore机和Mealy机区分:
//moore三段式状态机 采用独热码编码模式
module cola_3_moore(
input clk,
input rst,
input money,
output reg cola
);
/*定义寄存器现态、次态*/
reg[3:0]state,next_state;
/*定义状态编码*/
localparam IDLE = 4'b0001,
ONE = 4'b0010,
TWO = 4'b0100,
THREE = 4'b1000;
/*============状态机第一段:同步时序描述状态转移==============*/
always @(posedge clk , negedge rst) begin
if(!rst) state <= IDLE;
else state <= next_state;
end
/*============状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律============*/
always @(state , money) begin
case (state)
IDLE:begin
if(money) next_state<=ONE;
else next_state<=IDLE;
end
ONE:begin
if(money) next_state<=TWO;
else next_state<=ONE;
end
TWO:begin
if(money) next_state<=THREE;
else next_state<=TWO;
end
THREE:begin
if(money) next_state<=ONE;
else next_state<=IDLE;
end
default: begin/*默认状态同IDLE*/
if(money) next_state<=ONE;
else next_state<=IDLE;
end
endcase
end
/*============--状态机第三段:时序逻辑描述输出============*/
always @(posedge clk ,negedge rst) begin
if(!rst)
cola <= 1'b0;
else begin
case(state)
IDLE: cola <=1'b0;
ONE: cola <=1'b0;
TWO: cola <=1'b0;
THREE: cola <=1'b1;
default:cola <=1'b0;
endcase
end
end
endmodule
②两段式:
//moore两段式状态机 采用独热码编码模式
module cola_2_moore(
input clk,
input rst,
input money,
output reg cola
);
/*定义寄存器现态、次态*/
reg[3:0]state,next_state;
/*定义状态编码*/
localparam IDLE = 4'b0001,
ONE = 4'b0010,
TWO = 4'b0100,
THREE = 4'b1000;
/*============状态机第一段:同步时序描述状态转移==============*/
always @(posedge clk , negedge rst) begin
if(!rst) state <= IDLE;
else state <= next_state;
end
/*============状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律及输出============*/
always @(state , money) begin
case (state)
IDLE:begin
if(money) begin
next_state<=ONE;
cola <=1'b0;
end
else begin
next_state<=IDLE;
cola <=1'b0;
end
end
ONE:begin
if(money) begin
next_state<=TWO;
cola <=1'b0;
end
else begin
next_state<=ONE;
cola <=1'b0;
end
end
TWO:begin
if(money) begin
next_state<=THREE;
cola <=1'b0;
end
else begin next_state<=TWO;
cola <=1'b0;
end
end
THREE:begin
if(money) begin
next_state<=ONE;
cola <=1'b1;
end
else begin
next_state<=IDLE;
cola <=1'b1;
end
end
default: begin
if(money) begin
next_state<=ONE;
cola <=1'b0;
end
else begin
next_state<=IDLE;
cola <=1'b0;
end
end
endcase
end
endmodule
//mealy三段式状态机 采用独热码编码模式
module cola_3_mealy(
input clk,
input rst,
input money,
output reg cola
);
/*定义寄存器现态、次态*/
reg[2:0]state,next_state;
/*定义状态编码*/
localparam IDLE = 3'b001,
ONE = 3'b010,
TWO = 3'b100;
/*============状态机第一段:同步时序描述状态转移==============*/
always @(posedge clk , negedge rst) begin
if(!rst) state <= IDLE;
else state <= next_state;
end
/*============状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律============*/
always @(state , money) begin
case (state)
IDLE:begin
if(money) next_state<=ONE;
else next_state<=IDLE;
end
ONE:begin
if(money) next_state<=TWO;
else next_state<=ONE;
end
TWO:begin
if(money) next_state<=IDLE;
else next_state<=TWO;
end
default: begin/*默认状态同IDLE*/
if(money) next_state<=ONE;
else next_state<=IDLE;
end
endcase
end
/*============--状态机第三段:时序逻辑描述输出============*/
always @(posedge clk ,negedge rst) begin
if(!rst)
cola <= 1'b0;
else begin
case(state)
IDLE: cola <=1'b0;
ONE: cola <=1'b0;
TWO:begin
if(money) cola <=1'b1;
else cola <=1'b0;
end
default:cola <=1'b0;
endcase
end
end
endmodule
②两段式:
//mealy两段式状态机 采用独热码编码模式
module cola_2_mealy(
input clk,
input rst,
input money,
output reg cola
);
/*定义寄存器现态、次态*/
reg[2:0]state,next_state;
/*定义状态编码*/
localparam IDLE = 3'b001,
ONE = 3'b010,
TWO = 3'b100;
/*============状态机第一段:同步时序描述状态转移==============*/
always @(posedge clk , negedge rst) begin
if(!rst) state <= IDLE;
else state <= next_state;
end
/*============状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出============*/
always @(state , money) begin
case (state)
IDLE:begin
if(money) begin
next_state<=ONE;
cola <=1'b0;
end
else begin
next_state<=IDLE;
cola <=1'b0;
end
end
ONE:begin
if(money) begin
next_state<=TWO;
cola <=1'b0;
end
else begin
next_state<=ONE;
cola <=1'b0;
end
end
TWO:begin
if(money) begin
next_state<=IDLE;
if(money) cola <=1'b1;
end
else begin
next_state<=TWO;
cola <=1'b0;
end
end
default:begin
if(money) begin
next_state<=ONE;
cola <=1'b0;
end
else begin
next_state<=IDLE;
cola <=1'b0;
end
end
endcase
end
endmodule
eg2:以“101序列检测器”为例:
可重叠和不可重叠区分:
可重叠moore机:
①三段式
//moore 三段式 可重叠 101序列检测
module moore_101_seq_3(
input clk,
input rst,
input i,
output reg dec_101
);
/*===============状态寄存器===============*/
reg [3:0]state,next_state;
/*===============状态参数===============*/
localparam IDLE =4'b0001,
S1 =4'b0010,
S2 =4'b0100,
S3 =4'b1000;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
if(!rst)
state <= IDLE;
else
state <= next_state;
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
case (state)
IDLE:if(i==1)next_state <= S1;
else next_state <= IDLE;
S1:if(i==0)next_state <= S2;
else next_state <= S1;
S2:if(i==1)next_state <= S3;
else next_state <= IDLE;
S3:if(i==0)next_state <= S2;
else next_state <= S1;
default: if(i==1)next_state <= S1;//与IDLE状态相同
else next_state <= IDLE;
endcase
end
/*===============第三段状态机:时序逻辑定义输出===============*/
always @(posedge clk,negedge rst) begin
case (state)
IDLE: dec_101 <= 1'b0;
S1: dec_101 <= 1'b0;
S2: dec_101 <= 1'b0;
S3: dec_101 <= 1'b1;
default: dec_101 <= 1'b0;
endcase
end
endmodule
②两段式:
//moore 两段式 可重叠 101序列检测
module moore_101_seq_2(
input clk,
input rst,
input i,
output reg dec_101
);
/*===============状态寄存器===============*/
reg [3:0]state,next_state;
/*===============状态参数===============*/
localparam IDLE =4'b0001,
S1 =4'b0010,
S2 =4'b0100,
S3 =4'b1000;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
if(!rst)
state <= IDLE;
else
state <= next_state;
end
/*===============第二段状态机:组合逻辑定义参数及输出===============*/
always @(*) begin
case (state)
IDLE:begin
dec_101 <= 1'b0;
if(i==1)next_state <= S1;
else next_state <= IDLE;
end
S1:begin
dec_101 <= 1'b0;
if(i==0)next_state <= S2;
else next_state <= S1;
end
S2:begin
dec_101 <= 1'b0;
if(i==1)next_state <= S3;
else next_state <= IDLE;
end
S3:begin
dec_101 <= 1'b1;
if(i==0)next_state <= S2;
else next_state <= S1;
end
default: begin
dec_101 <= 1'b0;
if(i==1)next_state <= S1;//与IDLE状态相同
else next_state <= IDLE;
end
endcase
end
endmodule
testbench中状态机名称查看器的编写方法:
让当前状态不以进制01方式显示,而直接显示state名称。
解决思路:在Testbench构造一个reg变量,这个变量显示ASCII值,然后想办法让这个值等于state。这样的话我们就算没办法直接将state用字符显示,但我们可以用字符显示一个与其值一致的变量。
具体步骤:
//testbench 101sequence
`timescale 1ns/1ns
/*==========模块及端口声明==========*/
module tb_moore_101_seq();
reg clk;
reg rst;
reg i;
wire dec_101;
/*==========例化被测试模块==========*/
moore_101_seq_3 U1(
.clk(clk),
.rst(rst),
.i(i),
.dec_101(dec_101)
);
/*==========设置初始化条件==========*/
initial begin
clk = 1'b0;
rst = 1'b0;
i <= 1'b0;
#5 rst = 1'b1;i <= 1'b1;
#20 i <= 1'b1;
#20 i <= 1'b0;
#20 i <= 1'b1;
#20 i <= 1'b0;
#20 i <= 1'b1;
#20 i <= 1'b0;
#20 i <= 1'b1;
#20 i <= 1'b1;
#20 i <= 1'b1;
#20 i <= 1'b0;
#20 rst = 1'b0;
end
/*==========设置时钟==========*/
always #10 clk =~clk;//系统时钟周期20ns
/*==========状态机名称查看器==========*/
//每个字符8位宽,此处最多的THREE=40位宽
reg [39:0]state_name;
reg [39:0]next_state_name;
always @(*) begin
case (U1.state)
4'b0001: state_name <="IDLE";
4'b0010: state_name <="S1";
4'b0100: state_name <="S2";
4'b1000: state_name <="S3";
default: state_name <="IDLE";
endcase
end
always @(*) begin
case (U1.next_state)
4'b0001: next_state_name <="IDLE";
4'b0010: next_state_name <="S1";
4'b0100: next_state_name <="S2";
4'b1000: next_state_name <="S3";
default: next_state_name <="IDLE";
endcase
end
endmodule
(moore 三段式 可重叠 101序列检测)
mealy型FSM testbench:
`timescale 1ns/1ns
module tb_fsm_101_seq_mealy();
//端口声明
reg clk;
reg rst;
reg i;
wire dec_101;
//模块例化
mealy_101_seq_3 U1(
.clk(clk),
.rst(rst),
.i(i),
.dec_101(dec_101)
);
//初始化信号
initial begin
clk = 1'b0;
rst = 1'b0;
i <= 1'b0;
#5 rst = 1'b1;i <= 1'b1;
#20 i <= 1'b1;
#20 i <= 1'b0;
#20 i <= 1'b1;
#20 i <= 1'b0;
#20 i <= 1'b1;
#20 i <= 1'b0;
#20 i <= 1'b1;
#20 i <= 1'b1;
#20 i <= 1'b1;
#20 i <= 1'b0;
#20 rst = 1'b0;
end
//产生时钟
always #10 clk <= ~clk;
//状态机名称显示器
reg [31:0] state_name;
reg [31:0] next_state_name;
always @(*) begin
case(U1.state)
3'b001:state_name <= "IDLE";
3'b010:state_name <= "S1";
3'b100:state_name <= "S2";
default:state_name <= "IDLE";
endcase
end
always @(*) begin
case(U1.next_state)
3'b001:next_state_name <= "IDLE";
3'b010:next_state_name <= "S1";
3'b100:next_state_name <= "S2";
default:next_state_name <= "IDLE";
endcase
end
endmodule
可重叠mealy机:
①三段式
//mealy 三段式 可重叠 101序列检测
module mealy_101_seq_3(
input clk,
input rst,
input i,
output reg dec_101
);
/*===============状态寄存器===============*/
reg [2:0]state,next_state;
/*===============状态参数===============*/
localparam IDLE =3'b001,
S1 =3'b010,
S2 =3'b100;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
if(!rst)
state <= IDLE;
else
state <= next_state;
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
case (state)
IDLE:if(i==1)next_state <= S1;
else next_state <= IDLE;
S1:if(i==0)next_state <= S2;
else next_state <= S1;
S2:if(i==1)next_state <= S1;
else next_state <= IDLE;
default: if(i==1)next_state <= S1;//与IDLE状态相同
else next_state <= IDLE;
endcase
end
/*===============第三段状态机:时序逻辑定义输出===============*/
always @(posedge clk,negedge rst) begin
case (state)
IDLE: dec_101 <= 1'b0;
S1: dec_101 <= 1'b0;
S2:begin
if(i==1)dec_101 <= 1'b1;
else dec_101 <= 1'b0;
end
default: dec_101 <= 1'b0;
endcase
end
endmodule
②两段式:
//mealy 两段式 可重叠 101序列检测
module mealy_101_seq_2(
input clk,
input rst,
input i,
output reg dec_101
);
/*===============状态寄存器===============*/
reg [2:0]state,next_state;
/*===============状态参数===============*/
localparam IDLE =3'b001,
S1 =3'b010,
S2 =3'b100;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
if(!rst)
state <= IDLE;
else
state <= next_state;
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
case (state)
IDLE:begin
dec_101 <= 1'b0;
if(i==1)next_state <= S1;
else next_state <= IDLE;
end
S1:begin
dec_101 <= 1'b0;
if(i==0)next_state <= S2;
else next_state <= S1;
end
S2:begin
if(i==1)begin
next_state <= S1;
dec_101 <= 1'b1;
end
else begin
dec_101 <= 1'b0;
next_state <= IDLE;
end
end
default: begin//同IDLE状态相同
dec_101 <= 1'b0;
if(i==1)next_state <= S1;
else next_state <= IDLE;
end
endcase
end
endmodule
不可重叠moore机:
①三段式
//moore 三段式 不可重叠 101序列检测
module moore_101_seq_3_not_overlap(
input clk,
input rst,
input i,
output reg dec_101
);
/*===============状态寄存器===============*/
reg [3:0]state,next_state;
/*===============状态参数===============*/
localparam IDLE =4'b0001,
S1 =4'b0010,
S2 =4'b0100,
S3 =4'b1000;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
if(!rst)
state <= IDLE;
else
state <= next_state;
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
case (state)
IDLE:if(i==1)next_state <= S1;
else next_state <= IDLE;
S1:if(i==0)next_state <= S2;
else next_state <= S1;
S2:if(i==1)next_state <= S3;
else next_state <= IDLE;
S3:if(i==0)next_state <= IDLE;
else next_state <= S1;
default: if(i==1)next_state <= S1;//与IDLE状态相同
else next_state <= IDLE;
endcase
end
/*===============第三段状态机:时序逻辑定义输出===============*/
always @(posedge clk,negedge rst) begin
case (state)
IDLE: dec_101 <= 1'b0;
S1: dec_101 <= 1'b0;
S2: dec_101 <= 1'b0;
S3: dec_101 <= 1'b1;
default: dec_101 <= 1'b0;
endcase
end
endmodule
②两段式:
//mealy 两段式 不可重叠 101序列检测
module mealy_101_seq_2_not_overlap(
input clk,
input rst,
input i,
output reg dec_101
);
/*===============状态寄存器===============*/
reg [2:0]state,next_state;
/*===============状态参数===============*/
localparam IDLE =3'b001,
S1 =3'b010,
S2 =3'b100;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
if(!rst)
state <= IDLE;
else
state <= next_state;
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
case (state)
IDLE:begin
dec_101 <= 1'b0;
if(i==1)next_state <= S1;
else next_state <= IDLE;
end
S1:begin
dec_101 <= 1'b0;
if(i==0)next_state <= S2;
else next_state <= S1;
end
S2:begin
if(i==1)begin
next_state <= IDLE;
dec_101 <= 1'b1;
end
else begin
dec_101 <= 1'b0;
next_state <= IDLE;
end
end
default: begin//同IDLE状态相同
dec_101 <= 1'b0;
if(i==1)next_state <= S1;
else next_state <= IDLE;
end
endcase
end
endmodule
不可重叠mealy机:
①三段式:
//mealy 三段式 不可重叠 101序列检测
module mealy_101_seq_3_not_overlap(
input clk,
input rst,
input i,
output reg dec_101
);
/*===============状态寄存器===============*/
reg [2:0]state,next_state;
/*===============状态参数===============*/
localparam IDLE =3'b001,
S1 =3'b010,
S2 =3'b100;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
if(!rst)
state <= IDLE;
else
state <= next_state;
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
case (state)
IDLE:if(i==1)next_state <= S1;
else next_state <= IDLE;
S1:if(i==0)next_state <= S2;
else next_state <= S1;
S2:next_state <= IDLE;
default: if(i==1)next_state <= S1;//与IDLE状态相同
else next_state <= IDLE;
endcase
end
/*===============第三段状态机:时序逻辑定义输出===============*/
always @(posedge clk,negedge rst) begin
case (state)
IDLE: dec_101 <= 1'b0;
S1: dec_101 <= 1'b0;
S2:begin
if(i==1)dec_101 <= 1'b1;
else dec_101 <= 1'b0;
end
default: dec_101 <= 1'b0;
endcase
end
endmodule
②两段式:
//mealy 两段式 不可重叠 101序列检测
module mealy_101_seq_2_not_overlap(
input clk,
input rst,
input i,
output reg dec_101
);
/*===============状态寄存器===============*/
reg [2:0]state,next_state;
/*===============状态参数===============*/
localparam IDLE =3'b001,
S1 =3'b010,
S2 =3'b100;
/*===============第一段状态机:时序逻辑初始化===============*/
always @(posedge clk,negedge rst) begin
if(!rst)
state <= IDLE;
else
state <= next_state;
end
/*===============第二段状态机:组合逻辑定义参数===============*/
always @(*) begin
case (state)
IDLE:begin
dec_101 <= 1'b0;
if(i==1)next_state <= S1;
else next_state <= IDLE;
end
S1:begin
dec_101 <= 1'b0;
if(i==0)next_state <= S2;
else next_state <= S1;
end
S2:begin
if(i==1)begin
next_state <= IDLE;
dec_101 <= 1'b1;
end
else begin
dec_101 <= 1'b0;
next_state <= IDLE;
end
end
default: begin//同IDLE状态相同
dec_101 <= 1'b0;
if(i==1)next_state <= S1;
else next_state <= IDLE;
end
endcase
end
endmodule
参考文章:
原文链接:https://blog.csdn.net/wuzhikaidetb/article/details/121206908
原文链接:https://blog.csdn.net/wuzhikaidetb/article/details/119421783