SV:程序驱动程序的错误非法组合

SV: Error llegal combination of procedural drivers

使用以下代码出现 SV: Error illegal combination of procedural drivers 错误,知道如何解决这个问题吗? temp 的取值范围为 0 到 3。

    module multi_driver_check ();
    reg [7:0] ll_data_map[3:0];
    reg [7:0] data_in[3:0];
    reg [7:0] temp[3:0];
    assign data_in = '{default:0};
    genvar map_i;
    for(map_i=0;map_i<4;map_i++)
    begin
      always_comb
      begin
        if(temp[map_i]==0)
          ll_data_map[0] = data_in[map_i];
        else if(temp[map_i]==1)
          ll_data_map[1] = data_in[map_i];
        else if(temp[map_i]==2)
          ll_data_map[2] = data_in[map_i];
        else
          ll_data_map[3] = data_in[map_i];
     end 
    end
   endmodule

generate 语句只是重复或有条件地在它的主体中 adds/excludes 语句。在您的情况下,它会生成多个 always_comb 块,如下所示:

always_comb
      begin
        if(temp[0]==0)
          ll_data_map[0] = data_in[0];
        else if(temp[0]==1)
          ll_data_map[1] = data_in[0];
        else if(temp[0]==2)
          ll_data_map[2] = data_in[0];
        else
          ll_data_map[3] = data_in[0];
     end
always_comb
      begin
        if(temp[1]==0)
          ll_data_map[0] = data_in[1];
        else if(temp[1]==1)
          ll_data_map[1] = data_in[1];
        else if(temp[1]==2)
          ll_data_map[2] = data_in[1];
        else
          ll_data_map[3] = data_in[1];
     end

...

如您所见,ll_data_map[0](和其他)被不同的 always 块驱动至少 4 次。这是非法的。

我的猜测是,您在这里不需要任何生成块,只需将 for 循环移动到 always 块内即可:

int map_i;
always_comb begin
  for(map_i=0;map_i<4;map_i++)
    begin
        if(temp[map_i]==0)
          ll_data_map[0] = data_in[map_i];
        else if(temp[map_i]==1)
          ll_data_map[1] = data_in[map_i];
        else if(temp[map_i]==2)
          ll_data_map[2] = data_in[map_i];
        else
          ll_data_map[3] = data_in[map_i];
     end 
 end



错误原因:
生成 for 循环在编译的详细说明时解开它封装在其中的代码。 always_comb 确保它分配的任何东西都没有分配到其他任何地方。在你的代码编译中,你实际上有 4 always_combs 分配 ll_data_map 这是非法的。

解法:
always_comb 内移动 for 循环(map_i 不能是 genvar)。这样,对 ll_data_map 的所有分配都由单个 always_comb.

完成

其他注意事项:
ll_data_map 不是组合逻辑,即使它是在 always_comb 中定义的。最好的工具会标记这一点;最坏的情况是合成失败,因为目标设备不支持锁存器。
为了使其成为正确的组合逻辑,您可以在开始 for 循环之前添加 ll_data_map = '{default:'0};(或其他一些确定性赋值)。
如果 ll_data_map 打算用作锁存器,则使用 always_latch 而不是 always_comb(在一般的 RTL 设计中,不鼓励使用锁存器,但对于某些功能来说是必需的)