包的定義
- 在大型的驗(yàn)證項(xiàng)目中谢翎,很容易出現(xiàn)模塊重名的情況捍靠。
- 對于重名的硬件模塊我們可以將它們置入到不同編譯的庫中。
- 對于重名的軟件類岳服、方法等剂公,我們可以將它們置入到不同的包中。
- 我們可能使用不同的驗(yàn)證IP吊宋,我們也無法預(yù)測這些類名是否可能重名。
- 通過包(package)可以將關(guān)聯(lián)的類和方法并入到同一個(gè)邏輯集合中。
- 為了使得可以在多個(gè)模塊(硬件)或者類(軟件)之間共享用戶定義的類型璃搜,SV添加了包(package)拖吼。
- 用戶自定義的類型譬如類、方法这吻、變量吊档、結(jié)構(gòu)體、枚舉類等都可以在package...endpackage中定義.
package definitions;
parameter VERSION = "1.1";
typedef enum{ADD,SUB,MUL} opcodes_t;
typedef struct {
logic [31:0] a,b;
opcodes_t opcode;
} instruction_t;
function automatic [31:0] multiplier (input [31:0] a, b);
return a * b;
endfunction
endpackage
- module唾糯、interface怠硼、class等可以使用包中定義或者聲明的內(nèi)容。
- 可以通過域的索引符號
::
直接引用移怯。
definitions::parameter
definitions::instruction_t inst
- 可以指定索引一些需要的包中定義的類型到指定的域中香璃。
module M
import definitions:: instruction_t;
instruction_t inst;
endmodule
- 通過通配符*來將包中所有的類別導(dǎo)入到指定的域中。
module M
import definitions :: *
instruction_t inst;
endmodule
- 可以通過域的索引符號
::
直接引用舟误。
module ALU(input definitions::instruction_t IW,
input logic clock,
output logic [31:0] result);
always_ff @(posedge clock) begin
case (IW.opcode)
definitions::ADD:result = IW.a + IW.b;
definitions::SUB : result = IW.a - IW.b;
definitions::MUL :result =
definitions::multiplier(IW.a, IW.b);
endcase
end
endmodule
一般使用這種直接引用類型比較繁瑣葡秒,是為了特意強(qiáng)調(diào)某些類型、變量是來自某個(gè)包嵌溢,避免了重名以及方便代碼閱讀眯牧。
- 可以指定索引一些需要的包中定義的類型到指定的域中。
module ALU(...);
import definitions::ADD;
import definitions::SUB;
import definitions::MUL;
import definitions::multiplier;
always_comb begin
case(IW.opcode)
ADD :result = IW.a + IW.b;
SUB:: result = IW.a - IW.b;
MUL : result = multiplier(IW.a, IW.b);
endcase
end
endmodule
例如赖草,在ALU模塊中先導(dǎo)出了枚舉值A(chǔ)DD,SUB,MUL和函數(shù)multiplier.
因此就可以在always語句塊中就可以直接使用這些類型了学少。
如果覺得從包中逐一導(dǎo)出比較繁瑣:[也可以采用下面的方法]
image.png
示例問題:
image.png
- 然而這兩個(gè)package 中同名的類,它們的內(nèi)容是不相同的秧骑,實(shí)現(xiàn)的也是不同的功能旱易。
- 由于我們將這些重名的類歸屬到不同的package中編譯,這樣如果要使用不同package中的的同名類腿堤,他們只需要注明要使用哪一個(gè)package中的阀坏。
module mcdf_tb;
chnl_pkg:: monitor mon1 = new();
arb_pkg:: monitor mon2 = new();
endmodule
由于類名本身有沖突,這使得在引用類的時(shí)候笆檀,不得不使用直接索引的方式忌堂,這在兩個(gè)包中導(dǎo)出多個(gè)類型時(shí)就不方便了。在實(shí)際代碼中一般建議包中的類型名稱帶有包名的前綴
因此可以通過通配符索引類型的方式來導(dǎo)入到模塊中
image.png
- 從上述的簡單例子來看酗洒,package這個(gè)容器可以對類型做一個(gè)隔離的作用
- package的意義在于將軟件(類士修、類型、方法等)封裝在不同的域中樱衷,以此來與全局的域進(jìn)行隔離棋嘲。
包與庫的區(qū)分
- 庫是編譯的產(chǎn)物,硬件(module 矩桂、interface沸移、program)都會編譯到庫中,如果不指定編譯庫的話,會被編譯進(jìn)入默認(rèn)的庫中雹锣。
- 庫可以容納硬件類型网沾,也可以容納軟件類型,例如類蕊爵、方法和包
- 包只能容納軟件類型例如類辉哥、方法和參數(shù)