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

2011-4-22 13:39 5461 15 26 分类: 消费电子

 

最近折腾状态机,发现一个小任务对于两段式状态机写法是不可能完成的。这个小任务很简单,先看用一段式状态机实现的代码:

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.

20110422_tq_f3_ana.jpg

 

 

没有寄存器打一拍的这种combinational loop(组合环)是一种不推荐的设计方式,就如两段式状态机所实现的效果,甚至最终无法实现功能要求。同样的功能,一段式和三段式状态机之所以能够解决这个问题,就是避免了在纯组合逻辑中涉及这个反馈逻辑。在初学verilog时,我们常提的latch(锁存器),其实也是combinational loop的一个特例。

文章评论11条评论)

登录后参与讨论

kent_rao_738407428 2013-8-16 13:51

说得也是,至少我们还能抄,抄的东西也没准更可靠。就像中国的高速列车,抄的就很有水平。

用户1053489 2013-8-16 13:37

呵呵,最后一句太对了,不抄的东西更不靠谱

kent_rao_738407428 2013-6-26 09:06

没办法,博客自动把照片超级压缩了

用户1406868 2013-6-25 21:47

照片怎么噪点那么多?

用户1406868 2013-6-25 07:24

研发不仅要求个人要求有着孩子对待钟爱的玩具一样的热情 更重要的还要有支持持久研发的环境 变换太快的环境并不出精品 只能出抄袭山寨 创意源于生活 浮躁的世风也会蒙蔽人的双眼

用户1602177 2013-6-24 11:41

对于 Scott 的功成身退,我们也不必太过伤感~~毕竟,在他辛勤的付出之后,一切的收获表明,那都是值得的~~和家人开始一段新的生活,更是值得高兴的~~祝福老前辈!

黑洋 2013-6-24 09:17

更深去研究用户需求和技术创新, 少一些抄袭和山寨----这个真的太难。很多工程师对于自己的产品真的是像孩子一样有热情,但身处产业中,山寨与抄袭成了自重要的工具。 另外说一句,不抄袭的东西,出来的就更难说了。

用户1018579 2013-6-23 18:44

真情感人。 对楼主的“希望我们的中国年轻一代的工程师和项目管理者, 在聪明的同时,能更多些智慧; 在勤奋耐劳的同时,更多些热情和激情; 同时, 更多些虚心和务实,少一些浮躁; 更深去研究用户需求和技术创新, 少一些抄袭和山寨….. 也许,要做到这些需要时间, 还有整个社会的进步。但也只有这样,我们才能获得真正意义上的进步。 ”非常认同。谢谢您。

用户1406868 2012-11-19 15:20

在组合逻辑中出现

cnt = cnt +1;

这本身就是大忌

组合逻辑中应该这样写

cnt_next = cnt +1;

然后 在第一段中添加

cnt = cnt_next;

是这里的问题吗? 晚上我试试再通知作者

用户1406868 2011-5-30 05:34

只是一个错误的设计而已。被形式所迷惑。 CNT是个寄存器,怎么可以用组合逻辑电路的描述方式来写。稍微动动脑子,这个程序改改两段式写法太容易了。 写法只是一种新式,理解电路才是本质。
相关推荐阅读
用户1587532 2012-12-04 14:56
被忽略的硬件常识
          在特权同学的《都是IO弱上拉惹的祸》一文中,提及了Altera的CPLD在初始化时管脚通常会处于弱上拉状态。在实际示波器采样来看,就表现在上电初 期IO脚会有一个短暂(当时是持...
用户1587532 2012-12-04 14:56
都是IO弱上拉惹的祸
         开发的一款液晶驱动器,接收MCU过来的指令和数据进行图像显示。使用了一片可编程(带使能和PWM调节控制)的背光芯片。在CPLD设计中,上电复位状态将背光使能拉低(关闭),直到MC...
用户1587532 2011-12-29 09:39
四通道波形动态演示效果
 ">http:// http://v.youku.com/v_show/id_XMzM3MDY2NjYw.html   这效果,Cortex-M3可以吗?     ...
用户1587532 2011-12-21 12:54
高速绘图显示,还是FPGA给力
  示波器的效果,曾经以为难于上青天,殊不知咱用FPGA一样能够轻松效仿。目前只是单通道的显示效果,随后送上4通道独立或叠加的波形效果。          感兴趣的朋友不妨去看看他的详细参数:...
用户1587532 2011-10-12 10:23
Keil存储空间自定义分配
Keil存储空间自定义分配          看来Capital-Micro的软件支持包做得还不够到位啊,在51编程环境KeilC中使用Astro II器件光有个Capital Micro D...
用户1587532 2011-09-22 16:38
源同步信号跨时钟域采集的两种方法
源同步信号跨时钟域采集的两种方法            对于数据采集接收的一方而言,所谓源同步信号,即传输待接收的数据和时钟信号均由发送方产生。FPGA应用中,常常需要产生一些源同步接口信...
我要评论
11
15
关闭 站长推荐上一条 /2 下一条