【问题标题】:overwrite package struct in systemverilog design在 systemverilog 设计中覆盖包结构
【发布时间】:2022-01-22 13:52:04
【问题描述】:

我尝试通过在模块外声明另一个 packad 结构来覆盖包结构 并将其覆盖为参数 这是 RTL 代码。

顶级模块

module test_top 
#()
();

//Module A
A#()
u0
();


//Module B
B#()
u1
(); 

endmodule

模块 A

module A 
#()
();

typedef struct packed
{
 logic [31:0]    addr    ;       
 logic [3:0]     tag     ;       
} a_cmd_t;

target
#(
  .CNT    (4),
  .CMD_T  (a_cmd_t   )   
)
u0
(
 .cmd() 
); 

endmodule

模块 B

module B 
#(
)
(
);

typedef struct packed
{
 logic [31:0]    addr    ;       
 logic [7:0]     tag     ;       
} b_cmd_t;

target
#(
   .CNT(5),         
   .CMD_T (b_cmd_t) 
)
u0
(
  .cmd() 
);

endmodule

模块目标

module target
import target_pkg::*;
 #(
 parameter CNT = 1,             
 parameter type CMD_T     = target_cmd_t      
)
(
 output CMD_T cmd
);

localparam WIDTH = $bits(cmd.tag);  
localparam ZERO_FILL_WIDTH = (WIDTH - CNT);

wire [ZERO_FILL_WIDTH-1:0] test;
assign test = {ZERO_FILL_WIDTH{1'b0}};

endmodule

package target_pkg;

typedef struct packed
{
 logic [31:0]   addr  ;       
 logic [7:0]    tag   ; 
} target_cmd_t;

endpackage

但是当我编译 (w/ VCS) 时,数字似乎不能像我预期的那样被覆盖 因为我会得到如下编译错误:

Error-[ZMMCM] Zero multiconcat multiplier
~/target.sv, 15
"{ZERO_FILL_WIDTH {1'b0}}"
  Zero multiconcat multiplier cannot be used in this context. (Target as 
  above)
  A replication with a zero replication constant is considered to have a size 
  of zero and is ignored. Such a replication shall appear only within a 
  concatenation in which at least one of the operands of the concatenation has
  a positive size.
  Please use -error=noZMMCM to get around this error.
  Instance stack trace:
      target#(4, a_cmd_t, , )   
~/A.sv, 21
      A#()   
~/test_top.sv, 14
      test_top  
~/test_top.sv, 2
  

Error-[NMCM] Negative multiconcat multiplier
~/target.sv, 15
  Multiconcat multiplier cannot be negative value.
  Source info: {ZERO_FILL_WIDTH {1'b0}}
  Instance stack trace:
      target#(5, b_cmd_t, , )   
~/B.sv, 23
      B#()   
~/test_top.sv, 21
      test_top  
~/test_top.sv, 2
  Please refer LRM(1364-2005) section 5.1.14.

对于第一条错误信息“zero multiconcat multiplier”我认为是合理的,因为对于模块A (hierarchy:test_top.u0.u0) 参数 CNT 为 4,WIDTH = $bits(cmd.tag) = 4 所以参数 ZERO_FILL_WIDTH= (WIDTH - CNT) = 0。

但是对于其他错误消息“Negative multiconcat multiplier” 来自模块 B(层次结构:test_top.u1.u0)对我来说是不合理的。 因为对于模块 B(层次结构:test_top.u1.u0) 参数 CNT 为 5,WIDTH = $bits(cmd.tag) = 8 所以参数 ZERO_FILL_WIDTH= (WIDTH - CNT) = 3 是一个正值。

我尝试像这样修改模块 B:

module B 
#(
)
(
);

typedef struct packed
{
 logic [31:0]    addr    ;       
 logic [7:0]     tag     ;       
} b_cmd_t;

target
#(
   .CNT(3),         
   .CMD_T (b_cmd_t) 
)
u0
(
  .cmd() 
);

endmodule

让参数CNT=5,重新编译报错信息 “负多联乘数”消失了。 因此,WIDTH = $bits(cmd.tag) 的值似乎是 4 而不是 8。
但我希望值应该来自 b_cmd_t

所以我想知道这个 RTL 代码有什么问题我无法成功覆盖打包的结构吗?

【问题讨论】:

  • 你没有显示你的问题。 “WIDTH 似乎是 4”是什么意思?你怎么知道?在哪种情况下?请提供一个可重现的例子。否则你的代码看起来或多或少是正确的。顺便说一句,没有像 package struct 这样的东西,你的意思可能是 packed struct
  • 感谢您的反馈。我修改了描述以解释为什么我认为 WIDTH 是 4。是的,我的意思是打包结构。

标签: system-verilog


【解决方案1】:

您看到的消息是正确的。查看报错信息中的实例:

 target#(4, a_cmd_t, , )  

在上面的CNT == 4中,a_cmd_t中标签的宽度也是4:logic [3:0] tag

表达式localparam ZERO_FILL_WIDTH = (WIDTH - CNT); 被评估为0,这在以下复制器中是非法的:{ZERO_FILL_WIDTH{1'b0}};

对于第二个问题(负数),问题有所不同。 vcs中显然有一个错误。无论出于何种原因,vcs 在那里没有做正确的工作,也没有做正确的覆盖。它查看了一个正确的结构,但没有选择正确的字段,并且无法识别它的宽度为 8。我建议您将其报告给 synopsys。

但是,如果您摆脱 localparams 并使用以下内容,它将起作用:

  wire [$bits(cmd.tag) - CNT -1:0] test;
  assign test = {$bits(cmd.tag) - CNT{1'b0}};

【讨论】:

  • 是的,我认为第二个问题(负数)可能是 synopsys VCS 的问题。我正在 solvnet 上报告此问题并等待反馈。如果有任何更新我会在这里回复。感谢您的解决方法建议。很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多