基本聯合體
在 SystemVerilog 中,聯合體只是信號,可通過不同名稱和縱橫比來加以引用。 其工作方式為通過 typedef 來聲明聯合,并提供不同標識符用于引用此聯合體。 這些標識符稱為“字段”。
例如:
typedef union packed {
logic [3:0] a;
logic [3:0] b;
} union_type;
union_type my_union;
復制代碼
以上代碼創建了一種新類型,名為“union_type”。
此類型的位寬為 4 位,可作為“a”或“b”來引用。
此外,代碼最后一行創建了一個新信號,名稱為“my_union”且類型為“union_type”。
其使用語法為“.”。
例如:
always@(posedge clk) begin
my_union.a end
always@(posedge clk) begin
out1 out2 end
復制代碼
在 Vivado 中運行此代碼時,原理圖如下所示:
圖 1:基本聯合體
請注意,my_union 位寬仍僅為 4 位,而以“a”或“b”來引用它的兩項賦值均采用相同邏輯。針對 my_union 的賦值使用的是“a”,而此聯合體的讀取結果針對 out1 和 out2 則分別使用“a”和“b”。
聯合體分兩種類型:打包 (packed) 和解包 (unpacked)。在上述示例中,我們指定的是打包聯合體。默認情況下,如果不指定類型,編譯器將假定它采用解包聯合體。打包聯合體與解包聯合體的差別在于,在打包聯合體中,其中所有標識符都必須采用打包類型,并且大小必須相同。在上述示例中,“a”和“b”位寬均為 4 位。但如果其中之一為 4 位,而另一個為 2 位,則該工具中將生成錯誤。而在解包聯合體中,標識符可采用解包類型并且大小無需相同。因此,在上述 4 位和 2 位聯合體示例中,刪除“packed”語句將使該工具能夠對 RTL 進行完整審查。總而言之,打包聯合體在綜合工具中所受支持更為廣泛,并且更便于概念化。對于本文中的前幾個聯合體示例,我們使用的是打包聯合體,但從此處開始直至文末,我們將展示解包聯合體示例。
含多維字段的聯合體
上述示例只是簡單演示了聯合體的作用。讓我們來看下較為復雜的聯合體示例:
typedef union packed {
logic [3:0] a;
logic [1:0][1:0] b;
} union_type;
union_type my_union
復制代碼
同上,首先對聯合體進行聲明,并創建類型為“union_type”的信號。差別在于,字段“a”位寬為 4 位,另一個字段“b”位寬同樣為 4 位,但后者排列為 2 個 2 位矢量。由于這兩個字段大小相同,并且字段“b”使用的是打包類型,因此這是一個合法的打包聯合體。其結構體如下所示:
圖 2:含多維陣列的聯合體
為此結構賦值的 RTL 如下所示:
always@(posedge clk) begin
my_union.a end
always@(posedge clk) begin
out1 out2 end
復制代碼
原理圖如下所示:
圖 3:多維聯合體的原理圖
含結構體的聯合體
聯合體還可配合結構體一起使用。就像所有打包聯合體一樣,結構體大小必須與聯合體中的任何其它類型的大小相同。 例如:
typedef union packed {
logic [9:0] data;
struct packed {
bit op1;
bit [2:0] op2;
bit [1:0] op3;
bit op4;
bit [2:0] op5;
} op_modes;
} union_type;
union_type my_union;
復制代碼
此 RTL 介紹的聯合體包含 2 個位寬均為 10 位的字段。第一個字段為名為“data”且位寬為 10 位的矢量。第二個字段采用包含 5 個字段的結構體,這些字段的大小總和同樣為 10 位。
為此創建的結構體如下所示:
圖 4:含結構體的聯合體
由于當前聯合體中包含結構體,因此其正確的引用方式是引用聯合體中的結構體:
always@(posedge clk) begin
my_mult end
復制代碼
解包聯合體
如果聯合體中的字段大小不同,或者如果聯合體中的字段本身使用的類型為解包類型,那么此類聯合體需聲明為解包聯合體。 對于前一種情況,如果指定的聯合體包含不同大小的字段,那么該聯合體本身大小將設置為最大字段的大小。 示例 RTL:
typedef union {
logic [5:0] a;
logic [3:0] b;
logic c;
} union_type;
union_type my_union;
復制代碼
這樣即可創建如下所示結構:
圖 5:含不同大小字段的解包聯合體
含結構體的解包聯合體
與打包聯合體相同,解包聯合體同樣可以使用結構體。
typdef struct {
bit [3:0] a1;
bit a2;
} s_1;
typedef union {
logic [7:0] b1;
s_1 b2;
} union_type
union_type my_union;
復制代碼
以上示例將創建一個含兩個字段的聯合體。其中一個字段為位寬 8 位的矢量“b1”,另一個字段為位寬 5 位的結構體,此結構體由一個位寬 4 位的矢量 a1 和一個位寬 1 位的矢量 a2 組成。 此聯合體將作為位寬 8 位的矢量來創建,如下所示:
圖 6:含結構體的解包聯合體
同上,由于聯合體中包含結構體,因此需按如下方式來引用信號:
always@(posedge clk) begin
my_union.b1 out1 out2 end
復制代碼
審核編輯:湯梓紅
-
Xilinx
+關注
關注
71文章
2167瀏覽量
121312 -
代碼
+關注
關注
30文章
4780瀏覽量
68529 -
編譯器
+關注
關注
1文章
1624瀏覽量
49108
發布評論請先 登錄
相關推薦
評論