我已经看到以下用于在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
答案 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延迟只是开销。