System verilog 参数化压缩结构中字段的位宽度,以便模块可以推断端口映射中使用的位宽度
还讨论了: 我很难在SystemVerilog中实现我的意图,因为我试图使用最新的语言特性使我的代码更优雅、更简洁。合成用** 我希望做到以下几点:System verilog 参数化压缩结构中字段的位宽度,以便模块可以推断端口映射中使用的位宽度,system-verilog,vivado,System Verilog,Vivado,还讨论了: 我很难在SystemVerilog中实现我的意图,因为我试图使用最新的语言特性使我的代码更优雅、更简洁。合成用** 我希望做到以下几点: 能够参数化我想要定义的压缩结构中字段的位宽度。。。我尝试使用参数化接口构造来实现这一点 我希望将参数化接口作为模块输入的模块能够推断接口内定义的压缩结构内字段的位宽度 我在过去的实验中取得了很大的成功,但我遇到了一个问题 请参见以下简单接口定义: interface MyInterface #(int DATA_W, ADDR_W) ()
- 能够参数化我想要定义的压缩结构中字段的位宽度。。。我尝试使用参数化接口构造来实现这一点
- 我希望将参数化接口作为模块输入的模块能够推断接口内定义的压缩结构内字段的位宽度
interface MyInterface #(int DATA_W, ADDR_W) () ;
typedef struct packed
{ logic valid
; logic [ADDR_W-1:0] addr
; logic [DATA_W-1:0] data
; } SimpleStruct;
SimpleStruct bus;
logic ready;
modport SNK (input bus, output ready);
modport SRC (output bus, input ready);
endinterface
实例化一个接口并在我的顶层模块中的一个简单模块输入时使用它非常容易,本例中:
module TopTest
( input wire Clock
, input wire Reset
, input wire [31:0] In
, output wire dummyOut
) ;
MyInterface # ( 32, 3 ) my_interface ();
assign my_interface.bus.data = In ;
assign my_interface.bus.addr = 3'h3 ;
InnerTest inst_mod_inner_test
( .Clock( Clock )
, .Reset( Reset )
, .Sink( my_interface )
) ;
assign dummyOut = my_interface.ready ;
endmodule
我遇到的问题是,我不想用字段位宽度参数化实际模块,因为我相信在编译时字段的位宽度应该已经建立并可以访问。情况似乎并非如此,我想知道我是否可以做些什么来推断接口中压缩结构的位宽度(请记住,这种情况是因为我希望它参数化,我知道很容易获得未在接口中定义,而是在包或模块中定义的结构的字段的$位)
设计人员希望使模块“可参数化”的原因有很多,我过去也采用过这种方法,但我对不重复信息非常感兴趣。如果我采取简单的方法,我会简单地参数化我的内部测试模块,这样我就可以提供它的数据宽度,但是我会有两个数字要更新,还有很多我觉得不需要的参数。我认为,如果我能以某种方式简单地推断参数化结构的特征,那将是最优雅的。在我看来,我所寻找的信息是在编译时真正为人所知的。我似乎无法访问它,或者这是SystemVerilog的另一个不足之处
在模拟中跟踪Q
Dave提到的解决方法在使用QuestaSim时非常有用,但现在在QuestaSim中遇到了不同的问题:
当实例中的实际接口是阵列实例元素或低于生成构造时,通过接口端口“sink”的参数引用“sink.bus.data”无效
解决方法是什么,我不明白为什么仅仅在一个generate语句中就会影响下游的事情。在本例中,我使用generate语句在不同的FIFO实现之间进行选择,在发生错误的代码行上方的几层
typedef sink.bus.data questasim_workaround;
localparam width = $bits(questasim_workaround);
后续实验
我尝试了输入类型,而不是限制自己输入数据
interface MyInterface #(int ADDR_W, type DATA_TYPE) () ;
typedef struct packed
{ logic valid
; logic [ADDR_W-1:0] addr
; DATA_TYPE data
; } SimpleStruct;
SimpleStruct bus;
logic ready;
modport SNK (input bus, output ready);
modport SRC (output bus, input ready);
endinterface
这允许更大的灵活性。我观察到Vivado模拟器和合成工具可以毫无问题地处理这样的示例
module SomeModule
( MyInterface myInt
blah...
);
localparam SOMETHING = $bits(myInt.DATA_TYPE);
// or equivalently
localparam SOMETHING_ELSE = $bits(myInt.data);
// or even this, for needs of a internal signal for pipelined processing steps
MyInterface # ($bits(myInt.addr), myInt.DATA_TYPE) internal_0 () ;
在QUestaSim中,我们必须实施Dave的工作:
module SomeModule
( MyInterface myInt
blah...
);
// this gets less elegant :/
typedef myInt.data questasim_workaround_data;
typedef myInt.addr questasim_workaround_addr;
localparam SOMETHING = $bits(questasim_workaround_data);
// or equivalently
localparam SOMETHING_ELSE = $bits(questasim_workaround_data);
// or even this, for needs of a internal signal for pipelined processing steps
MyInterface # ($bits(questasim_workaround_addr), questasim_workaround_data) internal_0 () ;
当前SystemVerilog BNF不允许在参数初始化中使用任何虚线“.”名称。但是你可以用typedef来解决这个问题
interface MyInterface #(int DATA_W=0, ADDR_W=0) () ;
typedef logic [DATA_W-1:0] data_t;
...
endinterface
module InnerTest
( input wire Clock
, input wire Reset
, MyInterface.SNK Sink
) ;
typedef Sink.data_t data_t;
localparam BIT_WIDTH_SINK_DATA = $bits( data_t );
...
endmodule
每当您在Vivado中看到“不支持[Synth 8-27]作用域/层次结构类型名称”周围出现意外错误时。。。检查实例化端口映射是否与实际模块定义端口映射的所有名称匹配。这是Vivado中的问题,只有使用此代码。拼写不匹配,而不是出现“[Synth 8-448]命名端口连接'CLKKK'不存在”错误,而是出现“[Synth 8-27]作用域/层次结构类型名称不受支持”错误
如中所述:答案是否改为使用类endclass?我现在正在测试,不是答案:/因为即使以有限的方式使用类endclass,也不能在vivado中合成。[Synth 8-27]不支持作用域/层次结构类型名称Xilinx的Vivado能够在编译期间处理此问题,并将检查推到细化。非常酷,我希望QuestaSim很快也能支持这种方式。新一期的《问题》为澄清起见,增加了Vivado模拟器和Vivado合成工具的支持。在值中命名应该是“编译时已知常量”,如参数。。。对于我发布的接口示例
interface MyInterface #(int DATA_W=0, ADDR_W=0) () ;
typedef logic [DATA_W-1:0] data_t;
...
endinterface
module InnerTest
( input wire Clock
, input wire Reset
, MyInterface.SNK Sink
) ;
typedef Sink.data_t data_t;
localparam BIT_WIDTH_SINK_DATA = $bits( data_t );
...
endmodule