在一个完美的世界中,我可以将一个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委员会?
答案 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参数,因此它可能看起来有点无用,但在进行乘法/加法时,这些字段非常重要。