我希望将值保存在寄存器中任意数量的时钟周期。基本上我想做的就像处理状态机一样:
always@ (posedge Clock ) begin
if ( Reset ) CurrentState <= STATE_Initial ;
else CurrentState <= NextState ;
end
always@ ( * ) begin
NextState = CurrentState ;
case ( CurrentState )
STATE_Initial : begin
NextState = STATE_1 ;
end
STATE_1 : begin
NextState = STATE_2 ;
end
endcase
end
我现在的问题是除了那个之外我还要继续,并且类似于24位的标准寄存器:
always@ (posedge Clock ) begin
if ( Reset )
CurrentState <= STATE_Initial ;
curReg <= 24'd0;
else
CurrentState <= NextState ;
curReg <= nextReg;
end
always@ ( * ) begin
NextState = CurrentState ;
nextReg = curReg;
case ( CurrentState )
STATE_Initial : begin
NextState = STATE_1 ;
nextReg = 24'd2048;
end
STATE_1 : begin
NextState = STATE_2 ;
nextReg = 24'd211;
end
endcase
end
对我而言似乎是以同样的方式对待,但我总是收到一些不符合时序约束的错误。那么,为什么这是一个问题呢?
答案 0 :(得分:1)
在[{1}} - begin
声明
end
- if
else
为了改善时序,您可以指示合成器执行并行操作。这将增加面积。 IEEE Std 1364-2001(又名Verilog-2001)在2.8节中描述了为verilog添加属性以进行合成。但是我没有看到可能工具使用这个功能,大多数人已经采用了更多的SystemVerilog方法,并在评论中不断支持他们的自定义关键字
IEEE Std 1364-2001及以上LRM的建议:
always @(posedge Clock) begin
if ( Reset ) begin // <---- HERE
CurrentState <= STATE_Initial ;
curReg <= 24'd0;
end // <---- HERE
else begin // <---- HERE
CurrentState <= NextState ;
curReg <= nextReg;
end // <---- HERE
end
IEEE Std 1800-2005(SystemVerilog)及以上解决方案:(推荐)
(* parallel_case *)
case(CurrentState)
...
endcase
IEEE Std 1800-2009(SystemVerilog)及以上解决方案:(如果支持则最好)
unique case(CurrentState)
...
default: begin end // blank default for parallel only, else unique means parallel+full
endcase
典型的供应商特定语法。有关确切语法,请参阅综合手册:
unique0 case(CurrentState) // unqiue0 is explicit parallel case
...
endcase
并行性将有助于您的下一次状态计算。你的合成器可能已经在做它,如果它足够智能和时间感知。您可能仍会遇到500MHz的时序问题,具体取决于您的标准单元和路由。
如果所有其他方法都失败了,您将需要减慢时钟速度或不在每个时钟周期更新所有触发器。例如一个微小的更新计数器:
case(CurrentState) // synthesis parallel_case
...
endcase