【问题标题】:Is there a way to embed a constant in a struct in SystemVerilog?有没有办法在 SystemVerilog 的结构中嵌入常量?
【发布时间】:2021-01-27 03:56:55
【问题描述】:

在一个完美的世界中,我可以将 localparam 范围限定为结构内部:

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

但是很可惜,这不是合法的 SystemVerilog。我已经使用 const ints(非法)、枚举(不限于结构,并且需要“存储”)进行了调查。

我可能会考虑只将一个 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 委员会提出这个问题?

【问题讨论】:

  • 我试图弄清楚为什么你不能只使用模块范围的参数。你想做什么?
  • 我正在尝试在 systemverilog 中构建一个定点库,其中指数被视为常量并由合成器编译掉。模块范围的参数不起作用,我需要一个范围为 typedef 的常量。

标签: verilog system-verilog


【解决方案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;

【讨论】:

  • 我会试试这个,看看综合工具是否像我希望的那样优化常量。如果没有,我会向工具供应商投诉。
【解决方案2】:

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

可以使用always_comb var._hidden = -10; 将其设为半常数
assign 也可以工作,但与always_comb 不同的是,模拟器不需要在多个驱动程序中给出错误。

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

我也不确定合成器的优化程度;你需要进行实验。我的猜测是带有参数的interface 会比使用结构更好地去除未使用的信号。

【讨论】:

  • 嗨,格雷格——谢谢你的回复,但你误解了丑陋的黑客——我使用 _hidden 的位宽来编码一个常数,而不是 _hidden 的内容。我同意,这很可怕,最好只将指数放入结构中,只要我能确信综合工具会将其优化掉。
【解决方案3】:

我也刚开始构建一个定点库,并想使用一个结构来保存信号的 [完整、整数和小数] 宽度。我什至没有尝试做任何花哨的事情,我只是想在一个结构中收集参数,以便轻松访问它们。不幸的是,无论我做什么,工具都会抱怨,因为他们认为结构内容不是恒定的——即使我只分配一次。

例如:

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;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2019-11-23
    • 2018-07-03
    • 2022-06-18
    • 2019-12-18
    • 2016-07-09
    相关资源
    最近更新 更多