注意:本文所有內(nèi)容皆來源于Xilinx工程師,
BY Alan Schuler
基本聯(lián)合
在 SystemVerilog 中,聯(lián)合只是信號,可通過不同名稱和縱橫比來加以引用。
其工作方式為通過 typedef 來聲明聯(lián)合,并提供不同標識符用于引用此聯(lián)合。 這些標識符稱為“字段”。
例如:
typedef union packed {
logic [3:0] a;
logic [3:0] b;
} union_type;
union_type my_union;
以上代碼創(chuàng)建了一種新類型,名為“union_type”。
此類型的位寬為 4 位,可作為“a”或“b”來引用。
此外,代碼最后一行創(chuàng)建了一個新信號,名稱為“my_union”且類型為“union_type”。
其使用語法為“
例如:
always@(posedge clk) begin
my_union.a < = in1;
end
always@(posedge clk) begin
out1 < = my_union.a;
out2 < = my_union.b;
end
在 Vivado 中運行此代碼時,原理圖如下所示:

請注意,my_union 位寬仍僅為 4 位,而以“a”或“b”來引用它的兩項分配均采用相同邏輯。 針對 my_union 的分配使用的是“a”,而此聯(lián)合的讀取結(jié)果針對 out1 和 out2 則分別使用“a”和“b”。
聯(lián)合分兩種類型:打包 (packed) 和解包 (unpacked)。在上述示例中,我們指定的是打包聯(lián)合。 默認情況下,如果不指定類型,編譯器將假定它采用解包聯(lián)合。打包聯(lián)合與解包聯(lián)合的差別在于,在打包聯(lián)合中,其中所有標識符都必須采用打包類型,并且大小必須相同。 在上述示例中,“a”和“b”位寬均為 4 位。 但如果其中之一為 4 位,而另一個為 2 位,則該工具中將生成錯誤。 而在解包聯(lián)合中,標識符可采用解包類型并且大小無需相同。 因此,在上述 4 位和 2 位聯(lián)合示例中,刪除“packed”語句將使該工具能夠?qū)?RTL 進行完整審查。 總而言之,打包聯(lián)合在綜合工具中所受支持更為廣泛,并且更便于概念化。 對于本文中的前幾個聯(lián)合示例,我們使用的是打包聯(lián)合,但從此處開始直至文末,我們將展示解包聯(lián)合示例。
含多維字段的聯(lián)合
上述示例只是簡單演示了聯(lián)合的作用。 讓我們來看下較為復雜的聯(lián)合示例:
typedef union packed {
logic [3:0] a;
logic [1:0][1:0] b;
} union_type;
union_type my_union;
同上,首先對聯(lián)合進行聲明,并創(chuàng)建類型為“union_type”的信號。 差別在于,字段“a”位寬為 4 位,另一個字段“b”位寬同樣為 4 位,但后者排列為 2 個 2 位矢量。 由于這兩個字段大小相同,并且字段“b”使用的是打包類型,因此這是一個合法的打包聯(lián)合。
其結(jié)構(gòu)如下所示:

為此結(jié)構(gòu)分配的 RTL 如下所示:
always@(posedge clk) begin
my_union.a < = in1;
end
always@(posedge clk) begin
out1 < = my_union.b[0];
out2 < = my_union.b[1];
end
原理圖如下所示:

含結(jié)構(gòu)的聯(lián)合
聯(lián)合還可配合結(jié)構(gòu)一起使用。 就像所有打包聯(lián)合一樣,結(jié)構(gòu)大小必須與聯(lián)合中的任何其他類型的大小相同。
例如:
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 介紹的聯(lián)合包含 2 個位寬均為 10 位的字段。 第一個字段為名為“data”且位寬為 10 位的矢量。 第二個字段采用包含 5 個字段的結(jié)構(gòu),這些字段的大小總和同樣為 10 位。
為此創(chuàng)建的結(jié)構(gòu)如下所示:

由于當前聯(lián)合中包含結(jié)構(gòu),因此其正確的引用方式是引用聯(lián)合中的結(jié)構(gòu):
always@(posedge clk) begin
my_mult < = my_union.op_modes.op2 * my_union.op_modes.op5;
end
解包聯(lián)合
如果聯(lián)合中的字段大小不同,或者如果聯(lián)合中的字段本身使用的類型為解包類型,那么此類聯(lián)合需聲明為解包聯(lián)合。
對于前一種情況,如果指定的聯(lián)合包含不同大小的字段,那么該聯(lián)合本身大小將設置為最大字段的大小。
示例 RTL:
typedef union {
logic [5:0] a;
logic [3:0] b;
logic c;
} union_type;
union_type my_union;
這樣即可創(chuàng)建如下所示結(jié)構(gòu):

含結(jié)構(gòu)的解包聯(lián)合
與打包聯(lián)合相同,解包聯(lián)合同樣可以使用結(jié)構(gòu)。
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;
以上示例將創(chuàng)建一個含兩個字段的聯(lián)合。其中一個字段為位寬 8 位的矢量“b1”,另一個字段為位寬 5 位的結(jié)構(gòu),此結(jié)構(gòu)由一個位寬 4 位的矢量 a1 和一個位寬 1 位的矢量 a2 組成。
此聯(lián)合將作為位寬 8 位的矢量來創(chuàng)建,如下所示:

同上,由于聯(lián)合中包含結(jié)構(gòu),因此需按如下方式來引用信號:
always@(posedge clk) begin
my_union.b1 <= in1;
out1 <= my_union.b2.a1;
out2 <= my_union.b2.a2;
end
編輯:hfy
-
編譯器
+關注
關注
1文章
1672瀏覽量
51598 -
Vivado
+關注
關注
19文章
857瀏覽量
71106
發(fā)布評論請先 登錄
深度協(xié)同創(chuàng)新:解析超聲切割領域的“聯(lián)合實驗室”合作模式
一個經(jīng)典的結(jié)構(gòu)體和聯(lián)合體共用的實例
Labview 解析dxf文件并顯示
Labview 解析dxf文件并顯示<一>
IMU+多相機高速聯(lián)合自動標定方案
請問RT-Thread與stm32cubemx聯(lián)合開發(fā)的原理是什么?
SMT與DIP在PCBA加工中的關鍵差異解析
AT組件無法正確解析bin文件怎么解決?
中軟國際攜手華為發(fā)布醫(yī)藥聯(lián)合解決方案
用于各種設備協(xié)議間做報文轉(zhuǎn)換的網(wǎng)關是什么
國際汽車聯(lián)合會一行到訪中汽中心
C語言中結(jié)構(gòu)體與聯(lián)合體的深度解析:內(nèi)存布局與應用場景
"大模型+智能體"雙驅(qū)動!中控技術×大華股份成立視覺AI聯(lián)合實驗室
SystemVerilog 中各種不同的聯(lián)合解析
評論