1

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

state <= 2'b10;

state <= #1 IDLE;

为什么使用 <= 而不仅仅是 =?使用#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
4

2 回答 2

7

在像您这样的顺序逻辑always块中,最好使用非阻塞赋值(<=)而不是阻塞赋值(=)。模拟将更好地代表实际结果逻辑。

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

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

另请参阅: Verilog 综合中的非阻塞分配,致命的编码风格!

此外,最好使用 aparameter来命名您的每个州。如果一个 state 被命名IDLE而不是2'b10.

于 2011-04-16T20:03:53.757 回答
1

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

为避免时钟始终块的非确定性行为,您必须对在其他块中使用的那些变量(非局部变量)使用非阻塞分配。有关更详细的分析,请参阅我关于该主题的博客文章:

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

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

与您从许多其他人那里听到的相反,例如 Cliff Cummings 的热门论文,没有必要只对局部变量使用非阻塞赋值。局部变量完全可以接受阻塞赋值。这是相关的,因为它允许使用纯“变量”语义(如在编程语言中)进行内部建模。

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

于 2011-04-17T11:14:46.463 回答