当前位置:网站首页>【数字IC验证快速入门】9、Verilog RTL设计必会的有限状态机(FSM)
【数字IC验证快速入门】9、Verilog RTL设计必会的有限状态机(FSM)
2022-07-05 20:06:00 【luoganttcc】
导读:作者有幸在中国电子信息领域的排头兵院校“电子科技大学”攻读研究生期间,接触到前沿的数字IC验证知识,旁听到诸如华为海思、清华紫光、联发科技等业界顶尖集成电路相关企业面授课程,对数字IC验证有了一些知识积累和学习心得。为帮助想入门前端IC验证的朋友,思忱一二后,特开此专栏,以期花最短的时间,走最少的弯路,学最多的IC验证技术知识。
文章目录
一、基础理论
状态机简写为 FSM( Finite State Machine),也称为同步有限状态机,我们一般简称为状态机,之所以说“同步”是因为状态机中所有的状态跳转都是在时钟的作用下进行的,而“有限”则是说状态的个数是有限的。状态机根据影响输出的原因分为两大类,即Moore 型状态机和 Mealy 型状态机,其共同点是:状态的跳转都只和输入有关。区别主要是在输出的时候:若最后的输出只和当前状态有关而与输入无关则称为 Moore 型状态机;若最后的输出不仅和当前状态有关还和输入有关则称为 Mealy 型状态机。状态机是时序逻辑电路中非常重要的一个应用,常在大型复杂的系统中使用较多。
二、自动售饮料机
2.1、问题描述
设计一个自动售饮料机,设饮料售价2.5元,可使用5角和1元硬币,具有找零功能。
注:同一时刻只能投1元或者5角,不能两个同时投。
2.2、功能框图和接口定义
接口信号定义
- clk:时钟输入
- reset:系统复位信号
- half:投入5角硬币
- one:投入1元硬币
- cout:找零信号
- out:机器售出饮料
2.3、状态转换图 - moore FSM
注:Moore FSM 特点:输出只与当前的状态有关系,与输入没有关系!
Moore FSM 的 RTL代码
module drink_status_moore(
input wire clk,
input wire reset,
input wire half,
input wire one,
output wire out,
output wire cout
);
parameter [2:0] S0 = 3'b000,
S1 = 3'b001,
S2 = 3'b010,
S3 = 3'b011,
S4 = 3'b100,
S5 = 3'b101,
S6 = 3'b110;
reg [2:0] curr_state;
reg [2:0] next_state;
//first segment:state transfer
[email protected](posedge clk or negedge reset)
if(!reset)
curr_state <= S0;
else
curr_state <= next_state;
//second segment:transfer condition
[email protected](*)
case(curr_state)
S0 : if(half == 1'b1) next_state = S1;
else if(one == 1'b1) next_state = S2;
else next_state = S0;
S1 : if(half == 1'b1) next_state = S2;
else if(one == 1'b1) next_state = S3;
else next_state = S1;
S2 : if(half == 1'b1) next_state = S3;
else if(one == 1'b1) next_state = S4;
else next_state = S2;
S3 : if(half == 1'b1) next_state = S4;
else if(one == 1'b1) next_state = S5;
else next_state = S3;
S4 : if(half == 1'b1) next_state = S5;
else if(one == 1'b1) next_state = S6;
else next_state = S4;
S5 : next_state = S0;
S6 : next_state = S0;
default : next_state = S0;
endcase
//third segment:state output
//moore type FSM
assign out = ((curr_state == S5) || (curr_state == S6) ) ? 1'b1 : 1'b0;
assign cout = (curr_state == S6) ? 1'b1 : 1'b0;
endmodule
FSM 三段式写法:
- 良好的编码风格
- 逻辑综合
- 可阅读星
2.4、状态转换图 - Mealy FSM
注:Mealy FSM 特点:输出不仅与当前的状态有关系,与输入也有关系!
- Mealy 只用了5种状态,但是输出控制会变复杂!
Mealy FSM 的 RTL代码
module drink_status_mealy(
input wire clk,
input wire reset,
input wire half,
input wire one,
output wire out,
output wire cout
);
parameter [2:0] S0 = 3'b000,
S1 = 3'b001,
S2 = 3'b010,
S3 = 3'b011,
S4 = 3'b100,
S5 = 3'b101,
S6 = 3'b110;
reg [2:0] curr_state;
reg [2:0] next_state;
//first segment:state transfer
[email protected](posedge clk or negedge reset)
if(!reset)
curr_state <= S0;
else
curr_state <= next_state;
//second segment:transfer condition
[email protected](*)
case(curr_state)
S0 : if(half == 1'b1) next_state = S1;
else if(one == 1'b1) next_state = S2;
else next_state = S0;
S1 : if(half == 1'b1) next_state = S2;
else if(one == 1'b1) next_state = S3;
else next_state = S1;
S2 : if(half == 1'b1) next_state = S3;
else if(one == 1'b1) next_state = S4;
else next_state = S2;
S3 : if(half == 1'b1) next_state = S4;
else if(one == 1'b1) next_state = S0;
else next_state = S3;
S4 : if(half == 1'b1) next_state = S0;
else if(one == 1'b1) next_state = S0;
else next_state = S4;
default : next_state = S0;
endcase
//third segment:state output
//mealy type FSM
assign out = ((curr_state == S3 && one == 1'b1) || (curr_state == S4 && (half==1'b1 || one==1'b1)) ) ? 1'b1 : 1'b0;
assign cout = (curr_state == S4 && one == 1'b1) ? 1'b1 : 1'b0;
endmodule
2.5、有限状态机电路逻辑图
2.6、有限状态机小结
- FSM有限状态机的设计步骤
- 接口定义
- 状态定义和编码
- 状态的转换图
- 按照三段式编码风格实现RTL代码
- 编写TestBench代码
- 使用Questasim进行编译和仿真
- 通过波形工具查看输入激励、状态信号和输出信号
常见面试题:有限状态机分类?
- 答:Moore 型状态机:状态机的输出只与当前的状态有关
- Mealy 型状态机:状态机的输出不仅与当前的状态有关,还与当前的输入有关
常见面试题:两种状态机区别?
- 答:1、Moore状态机:在时钟脉冲的有限个门延时后,输出达到稳定。输出会在一个完整的时钟周期内保持稳定值,即使在该时钟内输入信号变化了,输出信号也不会变化。输入对输出的影响要到下一个时钟周期才能反映出来。把输入和输出分开,是Moore状态机的重要特征。
- 2、Melay状态机:由于输出直接受到输入影响,而输入可以在时钟周期的任意时刻变化,这就使得输出状态比Moore状态的输出状态提前一个周期到达。输入信号的噪声可能会出现在输出信号上。
- 3、对同一个电路,使用Moore状态机设计可能要比使用Mealy状态机多出一些状态。
状态机写法关键,分成三部分来写:
- 1、第一部分负责:状态跳转
- 2、第二部分负责:跳转条件
- 3、第三部分负责:输出信号
2.7、需要注意的问题:full case
- 定义完全状态,即使有的状态在电路中可能不会出现
- 目的是避免逻辑综合时出现组合逻辑环
- 组合逻辑环会导致STA没办法分析,DFT没办法覆盖
- 异步时序(timing 路径没办法约束,也就没办法分析)的问题
三、实战测试:序列检测器
3.1、序列检测器的功能要求
- 设计要求
- 用状态机设计序列检测器(1110010)
- 设计功能
- 设计一个序列检测器,检测的序列为“1110010”
- 当输入信号X依次为“1110010”时,输出信号Y输出一个高电平
- 否则输出信号Y为低电平
注:工程中序列检测器用的还是比较多的,用于检测序列头!
3.2、时序检测器的时序图
3.3、时序检测器的状态转换图
注意看,输出与输入无关,这是个Moore状态机!
3.4、序列检测器的参考代码
RTL 参考代码
// 1110010
module seq(
input wire in,
input wire clk,
input wire reset,
output wire out
);
parameter [2:0] S0 = 3'b000,
S1 = 3'b001,
S2 = 3'b010,
S3 = 3'b011,
S4 = 3'b100,
S5 = 3'b101,
S6 = 3'b110,
S7 = 3'b111;
reg [2:0] cur_state;
reg [2:0] next_state;
//first step: state transfer
[email protected](posedge clk or negedge reset)
if(~reset)
cur_state <= S0;
else
cur_state <= next_state;
//second: transfer condition
[email protected](*)
case(cur_state)
S0:begin
if(in == 1) next_state = S1;
else next_state = S0;
end
S1:begin
if(in == 1) next_state = S2;
else next_state = S0;
end
S2:begin
if(in == 1) next_state = S3;
else next_state = S0;
end
S3:begin
if(in == 0) next_state = S4;
else next_state = S3;
end
S4:begin
if(in == 0) next_state = S5;
else next_state = S1;
end
S5:begin
if(in == 1) next_state = S6;
else next_state = S0;
end
S6:begin
if(in == 0) next_state = S7;
else next_state = S2;
end
S7:begin
if(in == 0) next_state = S0;
else next_state = S1;
end
default: next_state = S0;
endcase
//third: output
assign out = (cur_state == S7) ? 1'b1 : 1'b0;
endmodule
TestBench 参考代码
`timescale 1ns/1ns
module tb_led();
//reg define
reg clk;
reg rst_n;
reg C;
//wire define
wire Y;
// //初始化系统时钟、全局复位
initial begin
clk = 1'b1;
rst_n <= 1'b0;
#10
rst_n <= 1'b1;
end
always #5 clk = ~clk;
[email protected](posedge clk or negedge rst_n)
if(rst_n == 1'b0)
C <= 1'b0;
else
C <= {$random} % 2;
seq seq_inst(
.clk (clk ),
.reset (rst_n ),
.in (C ),
.out (Y )
);
endmodule
节选仿真结果如下:
参考
边栏推荐
- Recommended collection, my Tencent Android interview experience sharing
- JVMRandom不可设置种子|问题追溯|源码追溯
- Debezium series: PostgreSQL loads the correct last submission LSN from the offset
- 深度學習 卷積神經網絡(CNN)基礎
- selenium 元素信息
- 多分支结构
- Debezium series: record the messages parsed by debezium and the solutions after the MariaDB database deletes multiple temporary tables
- .Net分布式事務及落地解决方案
- 函数的概念及语法
- ffplay文档[通俗易懂]
猜你喜欢
40000 word Wenshuo operator new & operator delete
JS implementation prohibits web page zooming (ctrl+ mouse, +, - zooming effective pro test)
ACM getting started Day1
Leetcode brush question: binary tree 13 (the same tree)
淺淺的談一下ThreadLocalInsecureRandom
Leetcode brush questions: binary tree 11 (balanced binary tree)
Force buckle 729 My schedule I
Leetcode brush question: binary tree 14 (sum of left leaves)
leetcode刷题:二叉树17(从中序与后序遍历序列构造二叉树)
Securerandom things | true and false random numbers
随机推荐
leetcode刷题:二叉树15(找树左下角的值)
Leetcode brush questions: binary tree 11 (balanced binary tree)
[C language] three implementations of quick sorting and optimization details
C language OJ gets PE, OJ of ACM introduction~
Elk distributed log analysis system deployment (Huawei cloud)
.Net分布式事务及落地解决方案
Go language | 02 for loop and the use of common functions
ffplay文档[通俗易懂]
Securerandom things | true and false random numbers
leetcode刷题:二叉树18(最大二叉树)
怎么挑选好的外盘平台,安全正规的?
Analysis of openh264 decoded data flow
Go language learning tutorial (XV)
Database logic processing function
leetcode刷题:二叉树11(平衡二叉树)
【c语言】快速排序的三种实现以及优化细节
国信证券在网上开户安全吗?
城链科技数字化创新战略峰会圆满召开
图嵌入Graph embedding学习笔记
如何安全快速地从 Centos迁移到openEuler