如何在verilog中使用Clocking block

时间:2017-02-28 15:04:50

标签: verilog system-verilog hdl

如何在verilog中使用时钟块来获取非阻塞赋值的等效代码

if((datain1[49]==1)||(datain2[49]==1)||(datain3[49]==1)||(datain4[49]==1)) 
begin
buffer[1][59:50]  <=buffer[1][147:138];
buffer[1][147:138]<=buffer[1][235:226];

buffer[2][59:50]  <=buffer[2][147:138];
buffer[2][147:138]<=buffer[2][235:226];

buffer[3][59:50]  <=buffer[3][147:138];
buffer[3][147:138]<=buffer[3][235:226];

buffer[4][59:50]  <=buffer[4][147:138];
buffer[4][147:138]<=buffer[4][235:226];
end

3 个答案:

答案 0 :(得分:2)

时钟块不会帮助你实现你想要实现的目标。

您的original codebuffer自行分配(异步反馈)。 buffer不是灵敏度列表的一部分并不重要,合成器会将其视为灵敏度列表的一部分。你有一个时钟输入,你应该使用它。

我建议您将编码风格更改为两个始终阻止的方法。一个总是块应该是用于下一状态计算的纯粹的组合逻辑。第二个始终块用于同步分配。如果您想了解更多关于不同编码风格及其优缺点的信息,我建议您使用Cliff Cummings this paper

您的代码应该是这样的:

// Use 'reg' for Verilog; 'logic' is recommended for SytemVerilog
reg       [263:0] buffer [0:63]; // flopped value
reg       [263:0] next_buffer [0:63]; // next-state of buffer

// Use whatever name you want for the indexes so long as they are unique per always block
integer comb_idx; ff_idx; 

// always_comb // <<== SystemVerilog
always @* // <<== Verilog (IEEE1364-2001)
begin
  for(comb_idx = 0; comb_idx<64; comb_idx=comb_idx+1) begin
    next_buffer[comb_idx] = buffer[comb_idx]; // initialize
  end

  if(start) begin
    next_buffer[0] = 0;
    // ...
  end

  // ... other conbinational and next-state calculations ...

  if((datain1[49]==1)||(datain2[49]==1)||(datain3[49]==1)||(datain4[49]==1)) 
  begin
    // we can use a loop for this
    for(comb_idx = 1; comb_idx<27; comb_idx=comb_idx+1) begin
      next_buffer[comb_idx][59:50]   = buffer[comb_idx][147:138];
      next_buffer[comb_idx][147:138] = buffer[comb_idx][235:226];
    end
  end
end

/*
// SystemVerilog
always_ff @(posedge clk)
begin
  // ... other synchronous assignments ...

  // SystemVerilog can assign unpacked arrays of same dimensions on one shot
  buffer <= next_buffer; type
end
*/

// Verilog
always @(posedge clk)
begin
  // ... other synchronous assignments ...
  for(ff_idx = 0; ff_idx<64; ff_idx=ff_idx+1) begin
    // Verilog cannot assign unpacked arrays in one shot
    buffer[ff_idx] <= next_buffer[ff_idx];
  end
end

答案 1 :(得分:1)

您不能使用时钟模块来获得与非阻塞分配相同的功能。

System-Verilog有9个调度区域

from prev time step
        |
     PREPONED
        |
      ACTIVE
        |
     INACTIVE
        |
       NBA
        |
     OBSERVED
        |
    RE-ACTIVE
        |
   RE-INACTIVE
        |
      RE-NBA
        |
    POSTPONED
        |
        V
 to next time step

由时钟区驱动的信号在RE-NBA区域被驱动,而变量被分配到在NBA区域使用非阻塞分配。

答案 2 :(得分:0)

您在谈论Systemverilog还是Verilog? Verilog没有时钟模块。