Verilog:像always&amp ;;的功能合成的

时间:2014-05-15 20:17:50

标签: verilog

是否有任何其他功能,如always(仅在敏感信号发生变化时才会运行,只要信号保持不变就不会迭代),可以单独或在{{1}内级联},但可以用Verilog合成。

2 个答案:

答案 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语句最接近您alwaysassign只能用于连续分配。左侧作业必须是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