以何种方式定义msb:lsb range作为参数?

时间:2018-05-15 13:35:32

标签: system-verilog

在我的硬件中定义了大量寄存器,包含位字段,我想“命名”那些寄存器,并使用它们的名称而不是msb:lsb格式在SystemVerilog中访问位字段。所以,我制作了一个新包,并在里面声明了常量参数,并尝试了那些描述范围的参数。像这样:

package VmeAddressMap;
   parameter SYS_INTCONFIG = 32'h00000044;
   parameter RSYS_INTCONFIGRORA = 31:16;
   parameter RSYS_INTCONFIGENABLE = 15:0;
endpackage // VmeAddressMap
很明显,这不起作用。所以我带来了一个'混合'解决方案,即简单的常量保留在包中,而对于范围,我创建了另一个包含宏的文件:

包文件:

package VmeAddressMap;
   parameter SYS_INTCONFIG = 32'h00000044;
endpackage // VmeAddressMap

宏文件:

`define RSYS_INTCONFIGRORA 31:16
`define RSYS_INTCONFIGENABLE 15:0

这个解决方案允许我做以下事情(读取是通过VME总线读取数据的任务):

Read(SYS_INTCONFIG);
`CHECK_EQUAL(LastVmeReadData_b32[`RSYS_INTCONFIGRORA], 15,
           "IRQ setup invalid");

这有效,并且做我想要的。但是我不喜欢它。特别是将宏与SystemVerilog描述风格混合在一起。

有没有办法直接在包中完成相同的任务?

2 个答案:

答案 0 :(得分:1)

您可以为MSB使用一个参数,为LSB使用另一个参数。

parameter RSYS_INTCONFIGRORA_MSB = 31;
parameter RSYS_INTCONFIGRORA_LSB = 16;

LastVmeReadData_b32[RSYS_INTCONFIGRORA_MSB:RSYS_INTCONFIGRORA_LSB]

这有点笨重,所以如果一切都是16位宽,你可以定义LSB:

parameter RSYS_INTCONFIGRORA = 16;

LastVmeReadData_b32[RSYS_INTCONFIGRORA +: 16]

或者,您可以使用结构:

typedef struct packed {
  logic [15:0] RSYS_INTCONFIGRORA;
  logic [15:0] RSYS_INTCONFIGENABLE;
} some_register_t;

如果设计的某些部分需要与整个寄存器对象进行交互而其他部分只需要与位字段进行交互,则可以进一步使用该结构生成union

这些寄存器结构可以构建为更大的寄存器映射结构。

如果您使用的是UVM,那么您应该建立一个RAL寄存器模块

答案 1 :(得分:1)

这正是UVM寄存器抽象层为您所做的。您可以定义字段,为其指定名称,位宽和其他属性。这些字段被分组为寄存器,寄存器被分组为具有地址和偏移的块。

现在我告诉过你,这是一个简单的解决方案,可以使用table.forms { border-color:#999999; border-width:2px; border-collapse:collapse; width:100%; padding:0px; margin:0px; } th.forms { padding:5px; border-color:#999999; border-width:1px; background-color:#FF9; } td.forms { padding:5px; border-color:#999999; border-width:1px; background-color:#FFC; } 构造来完成你想要的工作。

let

但现在你必须将范围放在变量前面。

package VmeAddressMap;
   parameter SYS_INTCONFIG = 32'h00000044;
   let RSYS_INTCONFIGRORA(field) = field[31:16];
   let RSYS_INTCONFIGENABLE(field) = field[15:0];
endpackage // VmeAddressMap