Verilog:如何优雅地编写相当于 table 的结构

Verilog: how to elegantly write the equivalent of a table of struct

我有以下 C 代码:

typedef struct label {
    uint16_t first;
    uint8_t second;
} label;
label labelsr[2][64];

labelsr[1][3].second = 0;

我想以最优雅的方式将其翻译成 Verilog。到目前为止,我带来了以下内容。还有更好的吗?

//(16 + 8) * 64 * 2 = 3072
`define LABELSR_STRUCT_SIZE 3072:0
`define ADVL 24
`define ADVLS 1536
`define FIRSTSTART 0
`define FIRSTEND 15
`define SECONDSTART 16
`define SECONDEND 23
`define FIRST(i, j) `FIRSTEND + i * `ADVLS + j * `ADVL : `FIRSTSTART + i * `ADVLS + j * `ADVL
`define SECOND(i, j) `SECONDEND + i * `ADVLS + j * `ADVL : `SECONDSTART + i * `ADVLS + j * `ADVL
reg [`LABELSR_STRUCT_SIZE] labelsr;

labelsr[`SECOND(1, 3)] <= 0;

最优雅的方法是使用具有完全相同的 C 语法的 SystemVerilog。所有现代工具都支持这一点。

嗯......它永远不会优雅,但你可以稍微清理一下。我假设您想要经典的 Verilog,而不是 SystemVerilog。

您需要使用 'indexed part select'。如果你想要myvec的8个降序位,并且MSB是msb,那么写myvec[msb -: 8]。所以 myvec[20 -: 8]myvec[20:13]。这可能会去掉一半的代码。

并且不要低估您的合成器 - 它可能会以最佳方式执行此类操作,即使您不费心为它分解所有内容。

另请注意 3072:0 应为 3071:0

我建议去掉 verilog 中的结构符号。它可能会大大简化所有事情

`define INDEX(i, j) (i * 64 + j)
module A;
  parameter SSIZE = 2 * 64; 
  reg [15:0] first[SSIZE];
  reg [7:0] second[SSIZE];

  always @*
      second[`INDEX(1,3)] = 0; 
endmodule

如果您可以访问系统 verilog 编译器,请使用 struct:

typedef struct packed { 
  logic [15:0] first;
  logic [7:0] second;
} label_t;

module A;
 label_t label[2][64]; 
 always @*
   label[1][3].second = 0;
endmodule

好吧,icarus 0.10 不会 编译最后一个示例。