多路复用通道中的 SystemVerilog 错误:实例数组中的非常量索引
SystemVerilog error in multiplexing channels : nonconstant index into instance array
我正在设计一个接受多个通道并输出一个通道的模块。
每个通道由valid
个信号和data
个宽度组成。
如果一个通道有有效数据,模块应该输出那个通道。如果多个通道有有效数据,模块应该输出其中一个(在我的例子中,索引最高的通道),其余的被丢弃。
我的简单实现如下所示:
module test1 #(
parameter NUM_CHANNEL = 8,
parameter DATA_WIDTH = 512
) (
input logic [DATA_WIDTH - 1 : 0] data_in [NUM_CHANNEL],
input logic valid_in [NUM_CHANNEL],
output logic [DATA_WIDTH - 1 : 0] data_out,
output logic valid_out
);
always_comb begin
valid_out = 0;
for (int i = 0; i < NUM_CHANNEL; ++i) begin
if (valid_in[i]) begin
valid_out = 1;
data_out = data_in[i];
end
end
end
endmodule
这在模拟和实际电路 (FPGA) 中都能完美运行。
但是,通道可以是复杂类型,所以我使用了这样的接口:
interface channel #(
parameter DATA_WIDTH = 512
);
logic valid;
logic [DATA_WIDTH - 1 : 0] data;
modport in (
input valid,
input data
);
modport out (
output valid,
output data
);
endinterface // sub_csr_if
module test #(
parameter NUM_CHANNEL = 8,
parameter DATA_WIDTH = 512
) (
channel.in in[NUM_CHANNEL],
channel.out out
);
always_comb begin
out.valid = 0;
for (int i = 0; i < NUM_CHANNEL; ++i) begin
if (in[i].valid) begin
out.valid = 1;
out.data = in[i].data;
end
end
end
endmodule
然后,此代码在 ModelSim 中出现 Nonconstant index into instance array 'sub_port'.
错误,在 Quartus 中出现 i is not a constant
错误。
如果我展开循环,它可以工作,但它变成了非参数代码。 (仅适用于固定 NUM_CHANNEL)
为什么后一个不起作用,而第一个完美运行?
实例数组(模块或接口)不是真正的数组类型。如您的错误消息所示,您不能 select 具有可变索引的特定实例。对于真正的数组,每个元素都是相同的。由于参数化、defparam 和端口连接的工作方式,每个实例元素可能会有差异。在模拟开始之前,详细化过程基本上会展平所有层次结构。
你可以做的是使用 generate
构造来 select 你的实例,如下所示
;
module test #(
parameter NUM_CHANNEL = 8,
parameter DATA_WIDTH = 512
) (
channel.in in[NUM_CHANNEL],
channel.out out
);
logic _valid[NUM_CHANNEL];
logic [DATA_WIDTH - 1 : 0] _data[NUM_CHANNEL];
for (genvar ii=0;ii<NUM_CHANNEL;ii++) begin
assign _valid[ii] = in[ii].valid;
assign _data[ii] = in[ii].data;
end
always_comb begin
out.valid = 0;
for (int i = 0; i < NUM_CHANNEL; ++i) begin
if (_valid[i]) begin
out.valid = 1;
out.data = _data[i];
end
end
end
endmodule
我正在设计一个接受多个通道并输出一个通道的模块。
每个通道由valid
个信号和data
个宽度组成。
如果一个通道有有效数据,模块应该输出那个通道。如果多个通道有有效数据,模块应该输出其中一个(在我的例子中,索引最高的通道),其余的被丢弃。
我的简单实现如下所示:
module test1 #(
parameter NUM_CHANNEL = 8,
parameter DATA_WIDTH = 512
) (
input logic [DATA_WIDTH - 1 : 0] data_in [NUM_CHANNEL],
input logic valid_in [NUM_CHANNEL],
output logic [DATA_WIDTH - 1 : 0] data_out,
output logic valid_out
);
always_comb begin
valid_out = 0;
for (int i = 0; i < NUM_CHANNEL; ++i) begin
if (valid_in[i]) begin
valid_out = 1;
data_out = data_in[i];
end
end
end
endmodule
这在模拟和实际电路 (FPGA) 中都能完美运行。
但是,通道可以是复杂类型,所以我使用了这样的接口:
interface channel #(
parameter DATA_WIDTH = 512
);
logic valid;
logic [DATA_WIDTH - 1 : 0] data;
modport in (
input valid,
input data
);
modport out (
output valid,
output data
);
endinterface // sub_csr_if
module test #(
parameter NUM_CHANNEL = 8,
parameter DATA_WIDTH = 512
) (
channel.in in[NUM_CHANNEL],
channel.out out
);
always_comb begin
out.valid = 0;
for (int i = 0; i < NUM_CHANNEL; ++i) begin
if (in[i].valid) begin
out.valid = 1;
out.data = in[i].data;
end
end
end
endmodule
然后,此代码在 ModelSim 中出现 Nonconstant index into instance array 'sub_port'.
错误,在 Quartus 中出现 i is not a constant
错误。
如果我展开循环,它可以工作,但它变成了非参数代码。 (仅适用于固定 NUM_CHANNEL)
为什么后一个不起作用,而第一个完美运行?
实例数组(模块或接口)不是真正的数组类型。如您的错误消息所示,您不能 select 具有可变索引的特定实例。对于真正的数组,每个元素都是相同的。由于参数化、defparam 和端口连接的工作方式,每个实例元素可能会有差异。在模拟开始之前,详细化过程基本上会展平所有层次结构。
你可以做的是使用 generate
构造来 select 你的实例,如下所示
;
module test #(
parameter NUM_CHANNEL = 8,
parameter DATA_WIDTH = 512
) (
channel.in in[NUM_CHANNEL],
channel.out out
);
logic _valid[NUM_CHANNEL];
logic [DATA_WIDTH - 1 : 0] _data[NUM_CHANNEL];
for (genvar ii=0;ii<NUM_CHANNEL;ii++) begin
assign _valid[ii] = in[ii].valid;
assign _data[ii] = in[ii].data;
end
always_comb begin
out.valid = 0;
for (int i = 0; i < NUM_CHANNEL; ++i) begin
if (_valid[i]) begin
out.valid = 1;
out.data = _data[i];
end
end
end
endmodule