我很确定没有办法做我想做的事情,但是以防万一有一个有趣的聪明解决方案,我想我应该问问。我有一个参数化的SystemVerilog接口,在其中生成了modports
interface some_interface #(parameter NUM_READERS=3);
logic [`kBitsPerProgramCounter-1:0] read_addr[NUM_READERS];
logic [`kBitsPerProgramCounter-1:0] write_addr;
genvar i;
generate
// generates Reader[n].Modport
for (i = 0; i < NUM_READERS; ++i) begin : Reader
modport Modport
(
output .read_addr(read_addr[i])
);
end
endgenerate
endinterface
如果我使用不同的模块类型使用不同的Modport,则使用此方法很容易。但是,我想尝试做的是拥有同一个模块的多个实例。我通过对类型进行参数化来尝试了此
module some_block#(parameter type SOMETYPE) (
input logic CLK200MHZ,
SOMETYPE aarrgghh);
但是要使其在语法上正常工作一直是一个挑战。给SOMETYPE设置默认值是行不通的,因为Vivado抱怨不允许分层类型,所以马上就认为这是行不通的。实例化时,我尝试使用完整的modport名称,具有实例化接口的完整modport名称以及其他一些名称,但似乎无济于事。
因此,我想知道是否有一种巧妙的方法可以使some_block的多个实例化,每个实例采用不同的生成的modport。如果没有,我可以使用生成的modport做一些有趣的聪明技巧吗?首先,我的想法是拥有一个作家和多个读者的东西。我想为每个阅读器生成一个modport,以便它只能触摸自己的阅读地址。我想我总是可以在整数上参数化some_block,在整个接口中传递some_block,然后依靠some_block来仅触摸与传入的整数相对应的读取地址,但这可能容易出错。
module top();
some_interface ifc;
for (genvar gi = 0; gi < NUM_REASDERS; gi++) begin: inst
some_block sb(ifc.Reader[gi].Modport);
end
endmodule
module some_block (some_interface ifc);
always_comb myvar = ifc.read_addr;
some_block
始终始终引用modport变量'read_addr'。您可以在“顶部”模块中使用generate块。