各種好用的 SystemVerilog 語法 (05) - typedef (struct)

Share on:

本文內容採用創用 CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款授權.

懶得打前言了,總之發現 SystemVerilog typedef 真的是很有用的東西,所以繼續寫。

前面的文章提及了使用 typedef 以及 enum,可以節省大量的 code 以及降低出錯機率。這邊繼續使用 MIPS instruction 當作例子,展示 SystemVerilog 提供的 struct 功能,進一步降低 code 出錯的可能性。

假設我們已經針對 MIPS 的 rtype 定義好了這樣的整數型別 (logic/enum):

 1parameter MIPS_OPCODE_BIT = 6;
 2parameter MIPS_FUNCT_BIT = 6;
 3parameter MIPS_SHAMT_BIT = 5;
 4parameter MIPS_REG_INDEX_BIT = 5;
 5typedef enum logic [MIPS_OPCODE_BIT-1:0] {
 6   ...
 7} MipsOpcodeType;
 8typedef enum logic [MIPS_FUNCT_BIT-1:0] {
 9   ...
10} MipsFunctType;
11typedef logic [MIPS_SHAMT_BIT-1:0] MipsRegIndexType;
12typedef logic [MIPS_REG_INDEX_BIT-1:0] MipsShamtType;

那麼,我們便可用 struct packed 把相關相鄰的整數包成一個 struct 來使用,並且可以免費的把 instruction 拆開成各自的 field:

 1typedef struct packed {
 2   MipsOpcodeType funct;
 3   MipsRegIndexType rs;
 4   MipsRegIndexType rt;
 5   MipsRegIndexType rd;
 6   MipsShamtType shamt;
 7   MipsFunctType funct;
 8} MipsRtypeInstructionType;
 9
10logic [31:0] inst_flat;
11MipsRtypeInstructionType inst;
12assign inst = inst_flat;

可以看到這樣的寫法,遠比單獨宣告多個 field,然後各自 assign 還不容易出錯,也更簡短。另外,裡面 hardcoded 的 31 也是可以避免的,可以用 $bits 直接算出 struct 的總 bit 數。

1parameter MIPS_INST_BIT = $bits(MipsRtypeInstructionType);
2typedef logic [MIPS_INST_BIT-1:0] MipsInstructionType;