在 systemverilog 设计中覆盖包结构
overwrite package struct in systemverilog design
我尝试通过在模块外声明另一个 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 代码是否有什么问题导致我无法成功覆盖打包结构?
您看到的消息是正确的。从报错信息看实例:
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}};
我尝试通过在模块外声明另一个 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 代码是否有什么问题导致我无法成功覆盖打包结构?
您看到的消息是正确的。从报错信息看实例:
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}};