Verilog中的FSM状态发生了变化

时间:2011-04-16 19:36:23

标签: verilog fsm state-machine

我已经看到以下用于在Verilog模块中进行状态更改:

state <= 2'b10;

state <= #1 IDLE;

为什么&lt; =使用而不只是=?使用#1的目的是什么?它有所作为吗?

以下是FSM的一些Verilog代码,显示了第一个正在使用的代码。如果用第二个替换它会不会起作用?

module fsm( clk, rst, inp, outp);

   input clk, rst, inp;
   output outp;

   reg [1:0] state;
   reg outp;

   always @( posedge clk, posedge rst )
   begin
   if( rst )
       state <= 2'b00;
   else
   begin
       case( state )
       2'b00:
       begin
            if( inp ) state <= 2'b01;
            else state <= 2'b10;
       end

       2'b01:
       begin
            if( inp ) state <= 2'b11;
            else state <= 2'b10;
       end

       2'b10:
       begin
            if( inp ) state <= 2'b01;
            else state <= 2'b11;
       end

       2'b11:
       begin
            if( inp ) state <= 2'b01;
            else state <= 2'b10;
       end
       endcase
   end
end

2 个答案:

答案 0 :(得分:7)

在与您类似的顺序逻辑always块中,最好使用非阻塞分配(<=)而不是阻止分配(=)。模拟将更好地代表实际产生的逻辑。

在纯RTL Verilog代码中,如果您对所有顺序逻辑使用非阻塞分配,则没有理由使用#1延迟。

我也看到其他人像这样使用#延迟。有时,这是由于在同一模拟中混合RTL和门网表。其他时候,它是为了弥补不良的建模。如果可以,您应该避免使用RTL代码中的延迟。

另见: Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!

此外,最好使用parameter来命名每个州。如果状态名为IDLE而不是2'b10,则更有意义。

答案 1 :(得分:2)

Verilog本质上是非确定性的。这意味着一般来说,模拟有多种可能的结果,这些结果都是不同的,但根据标准是有效的。

为了避免来自时钟总是块的非确定性行为, 对其他块(非局部变量)中使用的那些变量使用非阻塞赋值。有关更详细的分析,请参阅我关于该主题的博客文章:

http://www.sigasi.com/content/verilogs-major-flaw

综合工具通常接受时钟始终块中非局部变量的阻塞分配,但这实际上是一个错误,因为它们无法保证合成逻辑的行为与模型类似(因为这样的模型是非模型的)确定性)。

与许多其他人(如Cliff Cummings的热门论文)所听到的相比,没有只需要对本地变量使用非阻塞分配。阻止分配对于局部变量是完全可接受的。这是相关的,因为它允许使用纯“变量”语义(如在编程语言中)进行内部建模。

在纯RTL样式建模中,#1延迟只是开销。