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

2014-3-4 16:15 1447 9 11 分类: FPGA/CPLD 文集: FPGA

两段式状态机不可能完成的任务(特权)

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

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的一个特例。

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户1613626 2014-9-10 17:01

输出引用了之前的状态,组合逻辑无法完成这样的功能。

用户759784 2014-3-31 12:18

主要是因为计数器没有时钟驱动,这才是本质原因!
相关推荐阅读
pengchengcheng082_593158939 2015-08-21 16:26
Linux 下 的 vi 编辑器
一、按ESC键 跳到命令模式,然后: :w 保存文件但不退出vi :q 不保存文件,退出vi :wq 保存文件并退出vi :q! 不保存文件,强制退出vi :w! 强制保存,不推出...
pengchengcheng082_593158939 2015-07-28 15:57
面向对象和面向过程区别
转自 http://blog.sina.com.cn/s/blog_4dd5955301000a2m.html     面向对象和面向过程的区别,实在是难用一两句话说明白。   ...
pengchengcheng082_593158939 2015-05-23 10:39
后仿真能否被形式验证(Formal Verification)和静态时序分析(Static Timing Analysis)所取代
转自 http://www.cnblogs.com/jyaray/archive/2011/04/26/2029856.html 验证的主要目的:就是检查时间模型是否满足时间要求,是否实现了时...
pengchengcheng082_593158939 2015-05-19 11:18
两种代码方式
下面的两段程序等价,RTL图以及综合后的结果 完全一样。看似简单,其实是两种不同的思维方式。在复杂电路中能体现出两种方式各自的特点,第一种容易理解,第二种则结构更清晰,更接近综合后的结果。以前习惯用上...
pengchengcheng082_593158939 2015-05-14 16:28
Linux 下 的 cc 和 gcc
转自 http://www.cnblogs.com/zhouyinhui/archive/2010/02/01/1661078.html   在Linux下一会看到cc,另一会又看到gcc...
pengchengcheng082_593158939 2015-05-13 17:19
mips 编译器
1、linux 系统下编程的编译器 GNU toolchain(GNU工具链)是一个包含了由GNU项目所产生的各种编程工具的集合。这些工具形成了一条工具链,用于开发应用程序和操作系统。  ...
EE直播间
更多
我要评论
2
9
关闭 站长推荐上一条 /3 下一条