有没有办法在SystemVerilog中的结构中嵌入常量?

时间:2015-05-04 19:05:54

标签: verilog system-verilog

在一个完美的世界中,我可以将一个localparam范围扩展到一个结构的内部:

typedef struct {
  logic [10:0] mantissa;
  localparam exponent = -10;
} my_fixed_point_type;

但是,这不是合法的SystemVerilog。我调查过使用const int(非法),枚举(没有作用于结构,需要“存储”)。

我可能会考虑在结构中嵌入一个int,并且相信综合工具会注意到值只是被初始化,并将它们剥离掉,但是一些综合工具也可能忽略初始化。

到目前为止我发现的唯一方法实际上就是这个令人厌恶的词语:

typedef struct {
  logic [10:0] mantissa;
  logic [25:0] _hidden;
} my_fixed_point_type;

`define FP_EXPONENT(var) $bits(var._hidden)

由于永远不会读取_hidden,所以我很有信心它会在精化时被剥离,而_hidden的位宽可用于隐藏(无符号)整数常量。难看!

当然必须有一种更好的方法,以一种在综合中保留的方式将常量范围限定为结构,但不占用任何实际位。或者,我是否必须参加SystemVerilog 2016委员会?

3 个答案:

答案 0 :(得分:1)

您可以做很多事情,但不知道为什么要这样做,很难推荐一个好的解决方案。以下是一些建议:

您可以为typedef

定义初始值
typedef struct {
  logic [10:0] mantissa;
  int exponent = -10;
} my_fixed_point_type;

或使用匿名枚举类型来防止任何其他值被分配给它

   typedef struct {
      logic [10:0] mantissa;
      enum {value=-10} exponent = value;
    } my_fixed_point_type;

或我们对使用此类型声明的变量的连续赋值

   typedef struct {
      logic [10:0] mantissa;
      int exponent;
    } my_fixed_point_type; 

my_fixed_point_type fpv;
assign fpv.exponent = -10;

答案 1 :(得分:0)

_hidden可以使用logic signed [25:0] _hidden;

签名

可以使用always_comb var._hidden = -10;来制作半常数 assign也可以有效,但与always_comb不同,模拟器不需要为多个驱动程序提供错误。

另一种方法是使用interface而不是结构,您可以使用const或参数(甚至函数)。

我不确定合成器的优化程度如何;你需要实验。我的猜测是interface,参数将使用结构更好地剥离未使用的信号。

答案 2 :(得分:0)

你有没有找到解决办法?我刚开始构建一个定点库,并希望使用一个结构来保存信号的[完整,整数和小数]宽度。我甚至都没有尝试做任何花哨的事情,我只是想在结构中收集参数,因此很容易访问它们。不幸的是,无论我做什么,工具都会抱怨,因为他们认为结构内容不是一成不变的 - 即使我只分配过一次。

例如:

typedef struct { int w, i, q; } fxpt;
fxpt dw = '{16, 1, 15}; 
wire signed [dw.w-1:0] din;

或者即使我接受每个信号都有不同的结构,所以很明显一切都是不变的:

typedef struct { int w=18, i=1, q=17; }  dw_constant;
dw_constant dw; 
wire signed [dw.w-1:0] din;

我现在正在恢复直接在代码中使用参数,例如:

parameter integer dw[0:2] = '{16, 1, 15};
wire signed [dw[0]-1:0] din;

请注意,我没有在代码片段中访问.i和.q参数,因此它可能看起来有点无用,但在进行乘法/加法时,这些字段非常重要。