加入收藏 | 设为首页 | 会员中心 | 我要投稿 | RSSRSS-巴斯仪表网
您当前的位置:首页 > 设计中心 > 可编程逻辑器件

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

时间:2014-05-03  来源:123485.com  作者:9stone

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

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

分享到:
来顶一下
返回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
栏目导航->可编程逻辑器件
  • 可编程逻辑器件
  • 传感器技术
  • 推荐资讯
    使用普通运放的仪表放大器
    使用普通运放的仪表放
    3V与5V混合系统中逻辑器接口问题
    3V与5V混合系统中逻辑
    数字PID控制及其改进算法的应用
    数字PID控制及其改进
    恶劣环境下的高性价比AD信号处理数据采集系统
    恶劣环境下的高性价比
    栏目更新
    栏目热门