同步状态机的作用与结构
1.作用:
用于实现复杂的时序逻辑电路;
2.结构:
由状态寄存器(触发器)作为状态记忆部件(常用正跳边沿触发的D触发器);
仅当触发信号到达时刻才可能发生状态改变;
状态寄存器如果有n个触发器,状态机最多有2^n个状态。
3.同步状态机三要素:
1.状态:状态变量,划分逻辑顺序;
2.输出:某一状态时完成的事;
3.输入:进入某个状态的条件。
4.同步状态机的类型:
米勒型状态机(mealy状态机):下一个输出是当前状态和输入的函数/下一个状态是当前状态的输入的函数;
摩尔型状态机(Moore状态机):下一个输出是当前状态的函数/下一个状态是当前状态和输入的函数;
同步状态机的实现
1.状态分配
二进制表示状态的状态机:(连续的压缩状态的编码)
2'b00; 2'b01; 2'b10; 2'b11
格雷码表示状态的状态机:(降低系统功耗)
2'b00; 2'b01; 2'b11; 2'b10;
独热码表示状态的状态机:(n个状态需要n个寄存器)
4'b0001; 4'b0010; 4'b0100; 4'b1000;
2.有限状态机的描述风格
一段式风格(仅用一个always块实现状态即所有的功能,包括状态的产生,状态的跳转,输出逻辑的生成);
二段式风格(二个always块实现1.下一个状态到当前状态的产生;2.状态的跳转,输出逻辑的生成);
三段式风格(三个always块实现1.下一个状态到当前状态的产生;2.状态的跳转;3.输出逻辑的生成);推荐
由输出指定的码表示状态的状态机;
3.有限状态机的HDL描述
wire,reg,状态编码用reg型。
parameter用于描述状态名称,易读。
always:
根据主时钟沿完成同步时序的状态转移;
根据信号敏感表完成组合逻辑输出;
根据时钟沿完成同步时序逻辑的输出;
case/endcase:
完成进入每个状态的操作 default
4.有限状态机的Verilog描述
1.定义模块名和输入输出信号;
2.定义输入输出变量和寄存器;
3.定义时钟和复位信号;
4.定义状态变量和状态寄存器;
5.用时钟沿触发always块进行状态转移;
6.在复位信号有效时给状态寄存器赋初值;
7.描述状态的转换过程:符合条件,词能够一个状态带另一个状态,否则保留原有状态;
8.验证状态转移的正确性,必须完整和全面。
module fsm(
input clk,
input rstn,
input in,
output out0,
output out1
); //信号说明,引脚
reg out0,out1;
reg [1:0] current_state,next_state;
parameter
idle = 2'b00,
start = 2'b01,
stop = 2'b11,
clear = 2'b10; //变量和常量
endmodule
5.同步状态机的实现
状态转移图:状态,转移条件和逻辑开关
实现功能是检测一个5位二进制序列“10010”。可实现循环检测。
设计文件:
module check(
input clk,
input rstn,
input num,
output hold,
output [3:0] num_cnt,
output result
);
reg hold;
reg [3:0] num_cnt;
reg [3:0] num_cnt_nxt;
reg result;
parameter [2:0] idle = 3'b000;
parameter [2:0] s1 = 3'b001;
parameter [2:0] s2 = 3'b011;
parameter [2:0] s3 = 3'b010;
parameter [2:0] s4 = 3'b110;
parameter [2:0] s5 = 3'b111;
reg [2:0] current_state, next_state;
//state define
always@(posedge clk or negedge rstn)
if(!rstn)
current_state <= idle;
else
current_state <= next_state;
//状态转移
always@(num or current_state)
case(current_state)
idle: if(num)
next_state = s1;
else
next_state = idle;
s1: if(num)
next_state = s1;
else
next_state = s2;
s2: if(num)
next_state = s1;
else
next_state = s3;
s3: if(num)
next_state = s4;
else
next_state = idle;
s4: if(num)
next_state = s1;
else
next_state = s5;
s5: if(num)
next_state = s1;
else
next_state = s3;
default:
next_state = idle;
endcase
//输出逻辑
always@(current_state)
if(current_state == idle)
hold =1'b0;
else
hold =1'b1;
always@(current_state)
if(current_state == s5)
begin
result = 1'b1;
num_cnt_nxt = num_cnt+1;
end
else
begin
result = 1'b0;
num_cnt_nxt = num_cnt;
end
always@(posedge clk or negedge rstn)
if(!rstn)
num_cnt <= 4'h0;
else
num_cnt <= num_cnt_nxt;
endmodule
测试文件:
`include "fsm.v"
`timescale 1ns/1ps
module tb();
reg clk,rstn,mun;
wire hold,result;
wire [3:0] num_cnt;
always #5 clk=~clk;
initial
begin
clk = 0;
rstn = 0;
mun = 0;
#10
rstn = 1;
repeat(2000)
begin
#10
mun={$random}%2;
end
end
initial
#5000 $finish;
check inst_check(clk,rstn,mun,hold,num_cnt,result);
endmodule
波形: