将模块名称作为参数传递
Passing a module name as parameter
我想为我正在编写的一堆模块创建这个通用包装器。包装器应提供将这些模块连接到不同类型的 NoC 的能力,而无需更改内部模块的行为。
我认为执行此操作的一种方法如下。
考虑一个非常简单的模块来包装:
module add #(
parameter COLUMN_WIDTH = 32
)
(
//data in
input logic [COLUMN_WIDTH-1:0] col_1,
input logic [COLUMN_WIDTH-1:0] col_2,
//data out
output logic [COLUMN_WIDTH-1:0] col_o
);
assign col_o = col_1 + col_2;
endmodule
包装应如下所示:
module wrapper #(
parameter COLUMN_WIDTH = 32,
parameter WRAPPED_MODULE = add
)
(
//data in
input logic [COLUMN_WIDTH-1:0] col_1,
input logic [COLUMN_WIDTH-1:0] col_2,
//data out
output logic [COLUMN_WIDTH-1:0] col_o,
/* std signals */
input logic clk,
input logic reset_i // reset everything
);
logic [COLUMN_WIDTH-1:0] max_result;
WRAPPED_MODULE #(.COLUMN_WDITH(COLUMN_WIDTH),
) a(
.*
);
always @(posedge clk) begin
if (reset_i)
max_result <= 0;
else
max_result <= (col_o > max_result) ? col_o : max_result;
end
endmodule
我得到的错误如下:
Error-[IND] Identifier not declared
wrapper.sv, 4
Identifier 'add' has not been declared yet. If this error is not expected,
please check if you have set `default_nettype to none.
这是有道理的,因为参数与宏不同。
一个完整的设计可能应该实例化一堆包装模块,我不想通过为每个内部模块创建包装器来复制代码。
我该怎么做?
参数不能是模块名。它可以是 data_type、隐式 data_type 或 type
IEEE Std 1800-2012 § A.2.1.1 模块参数声明:
parameter_declaration ::=
parameter data_type_or_implicit list_of_param_assignments
| parameter type list_of_type_assignments
解决方法是使用生成块并比较参数值。
module wrapper #(
parameter COLUMN_WIDTH = 32,
parameter string WRAPPED_MODULE = "add"
)
(
// ...
);
// ...
generate
if (WRAPPED_MODULE=="add") begin
add #(.COLUMN_WDITH(COLUMN_WIDTH) ) a( .* );
end
else begin
// ...
end
endgenerate
// ...
endmodule
如果您使用的是 Vivado 和 SystemVerilog(仅在 2017.4 上测试过,可能也适用于更高版本),我已经能够使用 parameter type WRAPPED_MODULE = add
之类的东西,它也会进行综合。
我想为我正在编写的一堆模块创建这个通用包装器。包装器应提供将这些模块连接到不同类型的 NoC 的能力,而无需更改内部模块的行为。
我认为执行此操作的一种方法如下。 考虑一个非常简单的模块来包装:
module add #(
parameter COLUMN_WIDTH = 32
)
(
//data in
input logic [COLUMN_WIDTH-1:0] col_1,
input logic [COLUMN_WIDTH-1:0] col_2,
//data out
output logic [COLUMN_WIDTH-1:0] col_o
);
assign col_o = col_1 + col_2;
endmodule
包装应如下所示:
module wrapper #(
parameter COLUMN_WIDTH = 32,
parameter WRAPPED_MODULE = add
)
(
//data in
input logic [COLUMN_WIDTH-1:0] col_1,
input logic [COLUMN_WIDTH-1:0] col_2,
//data out
output logic [COLUMN_WIDTH-1:0] col_o,
/* std signals */
input logic clk,
input logic reset_i // reset everything
);
logic [COLUMN_WIDTH-1:0] max_result;
WRAPPED_MODULE #(.COLUMN_WDITH(COLUMN_WIDTH),
) a(
.*
);
always @(posedge clk) begin
if (reset_i)
max_result <= 0;
else
max_result <= (col_o > max_result) ? col_o : max_result;
end
endmodule
我得到的错误如下:
Error-[IND] Identifier not declared
wrapper.sv, 4
Identifier 'add' has not been declared yet. If this error is not expected,
please check if you have set `default_nettype to none.
这是有道理的,因为参数与宏不同。 一个完整的设计可能应该实例化一堆包装模块,我不想通过为每个内部模块创建包装器来复制代码。 我该怎么做?
参数不能是模块名。它可以是 data_type、隐式 data_type 或 type
IEEE Std 1800-2012 § A.2.1.1 模块参数声明:
parameter_declaration ::=
parameter data_type_or_implicit list_of_param_assignments
| parameter type list_of_type_assignments
解决方法是使用生成块并比较参数值。
module wrapper #(
parameter COLUMN_WIDTH = 32,
parameter string WRAPPED_MODULE = "add"
)
(
// ...
);
// ...
generate
if (WRAPPED_MODULE=="add") begin
add #(.COLUMN_WDITH(COLUMN_WIDTH) ) a( .* );
end
else begin
// ...
end
endgenerate
// ...
endmodule
如果您使用的是 Vivado 和 SystemVerilog(仅在 2017.4 上测试过,可能也适用于更高版本),我已经能够使用 parameter type WRAPPED_MODULE = add
之类的东西,它也会进行综合。