两段式状态机不可能完成的任务

最近折腾状态机,发现一个小任务对于两段式状态机写法是不可能完成的。这个小任务很简单,先看用一段式状态机实现的代码:
module test(
clk,rst_n,
din,dout
);
input clk;
input rst_n;
input din;
output[3:0] dout;
parameter idle = 3'd0;
parameter sta1 = 3'd1;
//一段式写法
reg[2:0] cstate;
reg[3:0] cnt;
always @(posedge clk or negedge rst_n)
if(!rst_n) cstate <= idle;
else begin
case(cstate)
idle: begin
cnt <= 4'd0;
if(din) cstate <= sta1;
else cstate <= idle;
end
sta1: begin
cnt <= cnt+1'b1;
if(cnt == 4'd10) cstate <= idle;
else cstate <= sta1;
end
default: cstate <= idle;
endcase
end
assign dout = cnt;
endmodule
同样的,用三段式状态机也能够实现这个功能:
//三段式写法
reg[2:0] cstate,nstate;
reg[3:0] cnt;
always @(posedge clk or negedge rst_n)
if(!rst_n) cstate <= idle;
else cstate <= nstate;
always @(cstate or din or cnt) begin
case(cstate)
idle: if(din) nstate = sta1;
else nstate = idle;
sta1: if(cnt == 4'd10) nstate = idle;
else nstate = sta1;
default: nstate = idle;
endcase
end
always @(posedge clk or negedge rst_n)
if(!rst_n) cnt <= 4'd0;
else begin
case(nstate)
idle: cnt <= 4'd0;
sta1: cnt <= cnt+1'b1;
default: ;
endcase
end
严格来看,上面的三段式状态机相比于一段式会滞后一个时钟周期。但是我们的重点不在这里,大家大可以不必钻这个牛角尖。另外,这个实例实现的功能本身也没有什么意义,当然也是可以用别的更简单(不需要状态机)的方式实现,但是你可以想象成这是实际应用中状态机各种复杂输出的一部分。
而如果大家希望用两段式状态机实现这个功能,或许会这么写:
//两段式写法
reg[2:0] cstate,nstate;
reg[3:0] cnt;
always @(posedge clk or negedge rst_n)
if(!rst_n) cstate <= idle;
else cstate <= nstate;
always @(cstate or din or cnt) begin
case(cstate)
idle: begin
cnt = 4'd0;
if(din) nstate = sta1;
else nstate = idle;
end
sta1: begin
cnt = cnt+1'b1;
if(cnt == 4'd10) nstate = idle;
else nstate = sta1;
end
default: nstate = idle;
endcase
end
如果大家有兴趣对三中代码方式都做一下仿真,会发现一些有意思的问题,尤其两段式状态机最终根本无法退出sta1,计数器cnt也会死在那里。究其根本原因,可大有学问。在编译工程后,出现了数条类似下面的warning:
warning: found combinational loop of 2 nodes
warning: node add0~2
warning: node cnt~9
何为combinational loop?让handbook来解释吧,看不懂英文的可别怪我~_~
combinational loops are among the most common causes of instability and unreliability in digital designs. they should be avoided whenever possible. in a synchronous design, feedback loops should include registers. combinational loops generally violate synchronous design principles by establishing a direct feedback loop that contains no registers. for example, a combinational loop occurs when the left-hand side of an arithmetic expression also appears on the right-hand side in hdl code. a combinational loop also occurs when you feed back the output of a register to an asynchronous pin of the same register through combinational logic, as shown in figure 5–1.
没有寄存器打一拍的这种combinational loop(组合环)是一种不推荐的设计方式,就如两段式状态机所实现的效果,甚至最终无法实现功能要求。同样的功能,一段式和三段式状态机之所以能够解决这个问题,就是避免了在纯组合逻辑中涉及这个反馈逻辑。在初学verilog时,我们常提的latch(锁存器),其实也是combinational loop的一个特例。

2018年亿邦未来零售大会 互联网资讯
我国航空发动机事业的发展情况探讨
云平台部署:基于Arduino与机智云的家居环境远程系统设计
苹果汽车 iCar 外观曝光,特斯拉拜拜了!
PY32F002A开发板,32 位 ARM® Cortex®-M0+内核,开发简单
两段式状态机不可能完成的任务
全新升级|才茂双5G模块千兆路由器CM520-37FS重磅发布!
三元软包电池在新能源乘用车领域的应用渗透进入加速期
大型5G终端设备无人机用于通信保障工作
sim800c模块应用实例分析
宝马Vision iNEXT:一款全面互联、提供高度自动驾驶功能的纯电动汽车
西门子博途:SCL中FB模块的结构
2022骨科手术机器人的进展如何
对于ANY数据类型及参数传递的详细解析
纯电动汽车优缺点 纯电动汽车的组成
汇顶科技聘任胡煜华女士为公司总裁 负责公司整体运营管理
一文解析FCC的卫星标准
物联网快讯:上汽集团联合浦东新区、阿里三方打造的「智己汽车」正式启动
联通沃Phone有望本月开售
关于扫地机器人都有哪些好用的产品