【问题标题】:SV: Error llegal combination of procedural driversSV:程序驱动程序的错误合法组合
【发布时间】:2020-04-01 15:46:32
【问题描述】:

使用下面的代码得到一个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

【问题讨论】:

  • assign ll_data_map = data_in; 如果您想将 data_in 传递给 ll_data_map,这是一个简单的语句

标签: driver system-verilog synthesis


【解决方案1】:

错误原因:
生成 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 设计中,不鼓励使用闩锁,但对于某些功能来说这是必需的)

【讨论】:

    【解决方案2】:

    generate 语句只是在其主体中重复或有条件地添加/排除语句。在您的情况下,它会生成多个 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 次。这是非法的。

    我的猜测是你不需要任何 generate 块,只需将你的 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
    
    
    
    

    【讨论】:

    • 嗨,Serge,根据您的建议,多驱动程序问题已解决,但在综合锁存器推断错误标记时,已通过添加 ll_data_map = '{default:'0};在开始 for 循环之前。
    • 对,我没注意。格雷格在他的回答中提到了这一点。
    猜你喜欢
    • 2014-01-08
    • 2012-09-18
    • 2018-08-27
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-28
    相关资源
    最近更新 更多