SystemVerilog中有没有一种方法可以直接将模块的输出转换为所需的类型而无需中间变量?

问题描述 投票:0回答:1

本质上,我试图找出一种方法,使我不必在 RTL 中使用这种笨拙的解决方法来让它干净地编译。在尝试了几种寻找答案但无果后,我决定尝试将问题留给专家。

考虑以下简化示例,了解我必须做什么才能获得可综合 RTL 的干净编译。 (请原谅任何可能的小语法错误,因为我在实际设计中手动混淆了它,并且之后没有编译它)

typedef enum logic [1:0]
   {ENUM_A,
    ENUM_B,
    ENUM_C,
    ENUM_D
    } t_gen_enum;

module example
   (input  t_gen_enum enum_in,
    output t_gen_enum enum_out
    );

   logic [$bits(t_gen_enum)-1:0] enum_out_temp;

   STANDARD_CELL_BUF enum_out_buffer [$bits(t_gen_enum)-1:0]
      (.i(enum_in),
       .o(enum_out_temp));

   assign enum_out = t_gen_enum'(enum_out_temp);

endmodule

如果我尝试以连接到输入的相同方式连接枚举输出,我会从 vcs 收到如下警告。

Warning-[ENUMASSIGN] Illegal assignment to enum variable
<filename>, <line_number>
example, "STANDARD_CELL_BUF enum_out_buffer[($bits(t_gen_enum) - 1):0]( .i (enum_in),  .o (enum_out));"
  Only expressions of the enum type can be assigned to an enum variable. 
  The type wire is incompatible with the enum 't_gen_enum'
  Expression: o
  Use the static cast operator to convert the expression to enum type.

具体来说,它似乎能够处理分配给标准单元(这是一种老式电线类型)输入的枚举,但不能将多电线类型输出分配回枚举类型。

我尝试了明显错误的方法(以防万一)将类型直接转换到输出连接中,但这自然行不通。

module example
   (input  t_gen_enum enum_in,
    output t_gen_enum enum_out
    );

   STANDARD_CELL_BUF enum_out_buffer [$bits(t_gen_enum)-1:0]
      (.i(enum_in),
       .o(t_gen_enum'(enum_out)}));

endmodule

我还尝试了 this thread 的一项建议,该建议确实消除了来自 vcs 的编译警告,但我不完全清楚 enum_out 是否仍保持正式枚举。尝试此操作的示例代码如下。

module example
   (input  t_gen_enum enum_in,
    output t_gen_enum enum_out
    );

   STANDARD_CELL_BUF enum_out_buffer [$bits(t_gen_enum)-1:0]
      (.i(enum_in),
       .o({enum_out}));

endmodule

我的解决方法确实可以干净地编译,但感觉很笨拙。另一种解决方法相当干净,但我不确定使用 {} 语法连接后信号是否实际上仍然被枚举。

我可能会被这个问题困扰,但希望这里有人可能知道更好的方法。

enums casting system-verilog
1个回答
0
投票

中间赋值和大括号方法都是可以接受的。中间值更常见,因为它对其他人来说很容易理解。使用大括号将枚举转换为打包向量更加细致,因此当您看到它时,它旁边通常会有注释。

enum_out
仍被视为
{enum_out}
之外的枚举。证明这一点的最简单方法是在支持显示枚举名称的波形查看器中探测信号,或者在信号发生变化时将临时代码放入输出
enum_out.name()

花括号连接变量并将其视为无符号压缩数组,符合 IEEE1800-2017 § 11.4.12 连接运算符

串联被视为该部分的压缩位向量

有趣的是,串联只需要一个表达式,如 IEEE1800-2017 § A.8.1 Concatenations:

中所述

串联 ::=

{
表达式 {
,
表达式 }
}

然后考虑IEEE1800-2017 § 23.3.3.2 变量的端口连接规则**** 它指出:

— 输出端口可以连接到兼容数据类型的变量(或串联)。当变量连接到实例的输出端口时,应暗示连续赋值。对连接到输出端口的变量进行程序或连续赋值 实例是非法的。

相同位宽的 emum 在技术上是兼容的数据类型,但某些工具并不将其视为直接兼容的数据类型,因此它们会发出警告。通过在枚举周围添加大括号,它将其转换为打包向量,该向量是与数组模块直接兼容的数据类型。

第三种方法是使用方括号来获取所需映射位的范围。与大括号串联一样,方括号范围也被视为打包向量。

module example
   (input  t_gen_enum enum_in,
    output t_gen_enum enum_out
    );

   STANDARD_CELL_BUF enum_out_buffer [$bits(t_gen_enum)-1:0]
      (.i(enum_in),
       .o(enum_out[$bits(t_gen_enum)-1:0]));

endmodule
© www.soinside.com 2019 - 2024. All rights reserved.