是否有任何其他功能,如always
(仅在敏感信号发生变化时才会运行,只要信号保持不变就不会迭代),可以单独或在{{1}内级联},但可以用Verilog合成。
答案 0 :(得分:1)
虽然我不认为在Verilog中有一个特别类似的构造,但有一种简单的方法可以做到这一点。如果对要对其敏感的信号进行边缘检测,则只需在“始终”块中“if”。像这样:
reg event_detected;
reg [WIDTH-1:0] sensitive_last;
always @ (posedge clk) begin
if (sensitive_signal != sensitive_last) begin
event_detected <= 1'b1;
end else begin
event_detected <= 1'b0;
end
sensitive_last <= sensitive_signal;
end
// Then, where you want to do things:
always @ (posedge clk) begin
if (event_detected ) begin
// Do things here
end
end
使用嵌套的“always”语句进行操作的问题在于它不会立即显示它将合成多少逻辑。根据FPGA或ASIC架构的不同,您将拥有一个相对较大的寄存器和可以隐式实例化的额外逻辑,这使得波形调试和门级综合等问题变得困难(更不用说时序分析)。在每个门/ LUT都很重要的世界中,这种隐式定义的逻辑可能成为一个主要问题。
答案 1 :(得分:1)
assign
语句最接近您always
。 assign
只能用于连续分配。左侧作业必须是wire
; SystemVerilog还允许logic
。
我更喜欢always
阻止assign
。我发现当通常同时更新的信号组合在一起时,模拟可以提供更好的性能。我相信合成器中的优化器可以用always
做得更好,但这可能取决于所使用的合成器。
对于同步逻辑,您需要一个always
块。在always块中读取硬件开关没有问题。 fpga主板可能已经为您取消了输入。如果没有,则在将输入与代码一起使用之前,通过两相管线发送输入。这有助于解决潜在的设置/保持问题。
always @(posedge clk) begin
pre_sync_human_in <= human_in;
sync_human_in <= pre_sync_human_in;
end
always @* begin
//...
case( sync_human_in )
0 : // do this
1 : // do that
// ...
endcase
//...
end
always @(posedge clk) begin
//...
if ( sync_human_in==0 ) begin /* do this */ end
else begin /* else do */ end
//...
end
如果您想要让状态机等待人类输入多位值进行握手,则添加到等待输入的状态。一个等待未准备好的状态(来自先前输入的过时位),另一个等待准备好的状态:
always @(posedge clk) begin
case(state)
// ...
PRE_HUMAN_IN :
begin
// ...
state <= WAIT_HUMAN__FOR_NOT_READY;
end
WAIT_HUMAN_FOR_NOT_READY :
begin
// ready bit is still high for the last input, wait for not ready
if (sync_human_in[READ_BIT])
state <= WAIT_HUMAN_FOR_NOT_READY;
else
state <= WAIT_HUMAN_FOR_READY;
end
WAIT_HUMAN_FOR_READY :
begin
// ready bit is low, wait for it to go high before proceeding
if (sync_human_in[READ_BIT])
state <= WORK_WITH_HUMAN_INPUT;
else
state <= WAIT_HUMAN_FOR_READY;
end
// ...
endcase
end