gpt4 book ai didi

parameters - systemverilog 使用参数指定导入命名空间

转载 作者:行者123 更新时间:2023-12-04 17:02:47 26 4
gpt4 key购买 nike

我有一个 systemverilog 模块,它引用一个生成的头文件,其中包含各种类型定义和函数。这是可合成的代码。该模块之前工作正常,因为头文件是使用预处理器包含的。

现在我的架构发生了变化,我需要实例化这个模块的多个案例并为每个实例指定不同的头文件。由于预处理器定义变量的全局特性,我不相信预处理器方法将不再起作用。我不能为模块的一个实例包含一个头文件,也不能为另一个实例包含另一个头文件。正确的?

所以我正在尝试使用包。我想要做的是如下所示:

package pack1;
parameter from_pack = 1;
typedef struct packed
{
logic [7:0] test1;
logic test2;
} test_t;
function automatic void hello();
$display("in pack1");
endfunction
endpackage

package pack2;
parameter from_pack = 2;
typedef struct packed
{
logic [7:0] test1;
logic test2;
logic [18:0] test3;
} test_t;
function automatic void hello();
$display("in pack2");
endfunction
endpackage

module top();
parameter PACKAGE_INST = 1;

generate
case (PACKAGE_INST)
1: begin
// import pack1::hello;
import pack1::*;
end
default: begin
// import pack2::hello;
import pack2::*;
end
endcase

// Error! Compiler doesn't know anything about the test_t type
test_t test_struct;
// pack1::test_t test_struct;

initial begin
$display("P1 = %d", P1);

// Error at elaboration! Simulator cannot find the 'hello()' function
hello();
// pack1::hello();
end
endgenerate
endmodule

请注意此代码的两个问题,都与我无法指定要与参数一起使用的命名空间有关。我怀疑我的问题是参数更改不一定需要重新编译,而我试图影响的更改肯定需要重新编译。这对我的应用程序很好;我不需要能够在不重新编译我的代码的情况下进行这些更改。

我能在 SO 上找到关于这个问题的最接近的讨论,至少在这里:

Handling parameterization in SystemVerilog packages

但最好的答案是使用预处理器巫术,我认为在我的情况下不起作用。我真的很感激对这个问题的任何洞察。谢谢。

最佳答案

您尝试做的问题是导入语句对于它出现的开始/结束范围是本地的。您需要在每个分支中声明 test_struct 变量,不幸的是,处理该函数的唯一方法是编写一个包装。

package pack1;
parameter from_pack = 1;
typedef struct packed
{
logic [7:0] test1;
logic test2;
} test_t;
function automatic void hello();
$display("in pack1");
endfunction
endpackage

package pack2;
parameter from_pack = 2;
typedef struct packed
{
logic [7:0] test1;
logic test2;
logic [18:0] test3;
} test_t;
function automatic void hello();
$display("in pack2");
endfunction
endpackage

module top();
parameter PACKAGE_INST = 1;

case (PACKAGE_INST)
1: begin : genscope
pack1::test_t test_struct;
function void hello;
pack1::hello();
endfunction
end
default: begin :genscope
pack2::test_t test_struct;
function void hello;
pack2::hello();
endfunction
end
endcase

initial begin
$display("PACKAGE_INST = %d", PACKAGE_INST);
$display("%p",genscope.test_struct);
genscope.hello();
end

endmodule

另一种完全不同的方法是使用接口(interface)而不是包。通过将您的模块连接到不同的接口(interface)实例,您可以选择连接到模块的类型和功能。
interface intf1;
parameter from_intf = 1;
typedef struct packed
{
logic [7:0] test1;
logic test2;
} test_t;
function automatic void hello();
$display("in intf1");
endfunction
endinterface

interface intf2;
parameter from_intf = 2;
typedef struct packed
{
logic [7:0] test1;
logic test2;
logic [18:0] test3;
} test_t;
function automatic void hello();
$display("in intf2");
endfunction
endinterface

module DUT(interface itf);

typedef itf.test_t test_t; // LRM requires this so typename does not
// appear as a hierarchical reference
test_t test_struct;

initial begin
$display("%m from_intf = %d", itf.from_intf);
$display("%p",test_struct);
itf.hello();
end

endmodule

module top2;


intf1 i1();
intf2 i2();

DUT d1(i1);
DUT d2(i2);

endmodule

关于parameters - systemverilog 使用参数指定导入命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33312433/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com