当前位置:网站首页>【深入浅出玩转FPGA学习4----漫谈状态机设计】
【深入浅出玩转FPGA学习4----漫谈状态机设计】
2022-07-02 07:29:00 【周猿猿】
状态机的基本概念
硬件设计很讲究并行设计思想,虽然用Verilog描述的电路大都是并行实现的,但是对于实际的工程应用,往往需要让硬件来实现一些具有一定顺序的工作,这就要用到状态机的思想。简单的说,状态机就是通过不同的状态迁移来完成一些特定的顺序逻辑。硬件的并行性决定了用Verilog描述的硬件实现(譬如不同的always语句)都是并行执行的,那么如果希望分多个时间完成一个任务,怎么办?也许可以用多个使能信号来衔接多个不同的模块,但是这样做多少显得有些繁琐。状态机的提出就会大大简化这一工作。
下面举一个SRAM控制的例子来说明状态机。如图所示,它表示了一个SRAM控制状态的变化
首先,在系统复位信号rst_n=0(复位有效)后,进入IDLE状态。每当rst_n=0(复位有效)时,都会保持在IDLE状态;当rst_n=1(复位完成),如果wr_req=1就进入WR_S1状态,如果rd_req=1就会进入RD_S1状态,否则保持IDLE状态不变。相应的,只要满足一定条件或者有时不需要任何条件,系统会在这些固定的状态间进行切换。这样做的好处在于每当需要操作SRAM时,其他模块只要发出一个wr_req或者rd_req信号(置高),系统就会进入相应状态并根据不同状态对SRAM的控制总线、地址总线和数据总线进行赋值。
构成状态机的基本要素是状态机的输入、输出和状态。输入就是一些引发状态变化的条件,比如图中的wr_req和rd_req的变化会引发状态的迁移,那么它们就是输入;输出就是状态变化后引起的变化,图中的控制总线、地址总线和数据总线的输出值就是由状态变化后引起的变化,状态就是IDLE、WR_S1、WR_S2等,它们一般是由一些逻辑值来表示。
状态机根据其状态变化是否与输入条件相关分为两类,即Moore型状态机和Mealy型状态机。Moore型状态机的状态变化仅和当前状态有关,而与输入条件无关;Mealy型状态机的状态变化不仅与当前的状态有关,还取决于当前的输入条件。
有些分类还会提出有限状态机(FSM)和无限状态机(ISM),但是实际设计中一般都指的是有限状态机。
三种不同状态机写法
状态机一般有三种不同的写法,即一段式、两段式和三段式的状态机写法,它们在速度、面积、代码可维护性等各个方面互有优劣。以下为SRAM控制状态机给出的三种不同的写法以及它们综合出的效果。wr_req和rd_req作为输入,cmd为输出,cstate、nstate为状态寄存器。
一段式状态机
一段式状态机代码如下:
reg[3:0] cstate;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
cstate <= IDLE;
cmd <= 3'b111;
end
else
case(cstate)
IDLE: if(wr_req) begin
cstate <= WR_S1;
cmd <= 3'b011;
end
else begin
cstate <= IDLE;
cmd <= 3'b111;
end
WR_S1: begin
cstate <= WR_S2;
cmd <= 3'b101;
end
WR_S2: begin
cstate <= IDLE;
cmd <= 3'b111;
end
RD_S1: if (wr_req) begin
cstate <= WR_S2;
cmd <= 3'b101;
end
else begin
cstate <= RD_S2;
cmd <= 3'b110;
end
RD_S2: if (wr_req) begin
cstate <= WR_S1;
cmd <= 3'b011;
end
else begin
cstate <= IDLE;
cmd <= 3'b111;
end
default: cstate <= IDLE;
endcase
end
一段式状态机RTL视图见图:
一段式状态机综合后资源使用报告:


两段式状态机
两段式状态机代码如下:
reg[3:0] cstate;
reg[3:0] nstate;
always @ (posedge clk or negedge rst_n)
if(!rst_n) cstate <= IDLE;
else cstate <= nstate;
always @ (cstate or wr_req or rd_req) begin
case(cstate)
IDLE: if(wr_req) begin
nstate = WR_S1;
cmd = 3 'b011;
end
else if(rd_req) begin
nstate = RD_S1;
cmd = 3'b011;
end
else begin
nstate = IDLE;
cmd = 3'b111;
end
WR_S1: begin
nstate = WR_S2;
cmd = 3'b101;
end
WR_S2: begin
nstate = IDLE;
cmd = 3'b111;
end
RD_S1: if(wr_req) begin
nstate = WR_S2;
cmd = 3'b101;
end
else begin
nstate = RD_S2;
cmd = 3'b110;
end
RD_S2: if(wr_req) begin
nstate = WR_S1;
cmd = 3'b011;
end
else begin
nstate = IDLE;
cmd = 3'b111;
end
default: nstate = IDLE;
endcase
end
两段式状态机RTL视图见图:
两段式状态机综合后资源使用报告:

三段式状态机
三段式状态机代码如下:
reg[3:0] cstate;
reg[3:0] nstate;
always @ (posedge clk or negedge rst_n)
if(!rst_n) cstate <= IDLE;
else cstate <= nstate;
always @ (cstate or wr_req or rd_req) begin
case(cstate)
IDLE: if(wr_req) nstate = WR_S1;
else if(rd_req) nstate = RD_S1;
else nstate = IDLE;
WR_S1: nstate = WR_S2;
WR_S2: nstate = IDLE;
RD_S1: if(wr_req) nstate = WR_S2;
else nastate = RD_S2;
RD_S2: if(wr_req) nstate = WR_S1;
else nstate = IDLE;
default: nstate = IDLE;
endcase
end
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) cmd <= 3'b111;
else
case(nstate)
IDLE: if(wr_req) cmd <= 3'b011;
else if(rd_req) cmd <= 3'b011;
else cmd <= 3'b111;
WR_S1: cmd <= 3'b101;
WR_S2: cmd <= 3'b111;
RD_S1: if(wr_req) cmd <= 3'b101;
else cmd <= 3'b110;
RD_S2: if(wr_req) cmd <= 3'b011;
else cmd <= 3'b111;
default: ;
endcase
end
三段式状态机RTL视图见图:
三段式状态机综合后资源使用报告:


从上面的三个实例来看,一段式状态机似乎是一锅端,把所有逻辑(包括输入、输出、状态)都在一个always里解决了;这种写法看上去好像很简洁,但是往往不利于维护,也许这个实例中体现得还不那么明显,如果状态复杂一些就很容易出错了;这种写法一般不太推荐,但是在一些简单得状态机中还是可以使用的。两段式状态机是一种常用的写法,他把时序逻辑和组合逻辑划分开来,时序逻辑里进行当前状态和下一状态得切换,组合逻辑实现各个输入、输出以及状态判断;这种写法相对容易维护,不过组合逻辑输出较易出现毛刺等常见问题。三段式状态机写法也是一种比较推荐得写法,代码容易维护,时序逻辑得输出解决了两段式写法种组合逻辑得毛刺问题;但是从资源消耗上来讲,三段式得资源消耗多一些;另外,三段式从输入到输出比一段式和两段式会延时一个时钟周期。
边栏推荐
- Win11 arm系统配置.net core环境变量
- 12. Process synchronization and semaphore
- VSCode工具使用
- PCL 投影点云
- Mongodb quickly get started with some simple operations of mongodb command line
- What are the popular frameworks for swoole in 2022?
- 洛谷 P1892 [BOI2003]团伙(并查集变种 反集)
- 对话吴纲:我为什么笃信“大国品牌”的崛起?
- axis设备的rtsp setup头中的url不能带参
- js数组常用方法
猜你喜欢

Internet News: Tencent conference application market was officially launched; Soul went to Hong Kong to submit the listing application

From Read and save in bag file Jpg pictures and PCD point cloud

全网显示 IP 归属地,是怎么实现的?

Beautiful and intelligent, Haval H6 supreme+ makes Yuanxiao travel safer

JSP webshell免殺——JSP的基礎

JSP webshell free -- the basis of JSP

AI技术产业热点分析

Shapiro Wilk normal analysis by SPSS

Retrofit's callback hell is really vulnerable in kotlin synergy mode!
![2. Hacking lab script off [detailed writeup]](/img/f3/29745761cd5ad4df84c78ac904ea51.png)
2. Hacking lab script off [detailed writeup]
随机推荐
点云投影图片
Point cloud projection picture
【AGC】构建服务3-认证服务示例
MySQL keyword
【快应用】text组件里的文字很多,旁边的div样式会被拉伸如何解决
华为游戏初始化init失败,返回错误码907135000
华为应用市场应用统计数据问题大揭秘
转换YV12到RGB565图像转换,附YUV转RGB测试
简洁、快速、节约内存的Excel处理工具EasyExcel
SPSS做Shapiro-Wilk正态分析
14. Code implementation of semaphore
Oracle notes
JVM garbage collector
二叉树专题--AcWing 1497. 树的遍历(利用后、中序遍历,构建二叉树)
P1055 [noip2008 popularization group] ISBN number
集成学习概览
Disassembling Meitu SaaS: driving the plane to change the engine
洛谷 P4281 [AHOI2008]紧急集合 / 聚会(树上倍增 LCA)
Shapiro Wilk normal analysis by SPSS
二叉树专题--AcWing 3540. 二叉搜索树建树(实用板子 构建二叉搜索树 并输出前、中、后序遍历)