input端口是輸入端口;output是輸出端口;還有inout端口。
inout端口用於雙向連接。如果使用多個inout端口驅動一個信號,sv將會根據所有驅動器的值,驅動強度來計算最終的值。
ref是對變量(不能是net)的應用,它的值是該變量最后一次賦的值。如果將一個變量連接到多個ref端口,就有可能產生競爭,因為多個模塊的端口都有可能更新同一個變量。
在sysytemverilog中,參數的傳遞方式可以指定為引用而不是復制,這種ref函數類型比input,output和inout更好用,首先你可以把數組傳遞給子程序;
使用ref和const傳遞數組,如下
function void print_checksum (const ref bit [31:0] a[]);
bit [31:0] checksum = 0;
for(int i=0; i<a.size(); i++)
checksum ^= a[i];
$display("the array checksum is %0d", checksum);
endfunction
以上實例中,用到了const修飾符,雖然數組變量a指向了調用程序中的數組,但是子程序不能修改數組的值,如果你試圖改變數組的值,編譯器將報錯。
systemverilog允許不帶ref進行數組的傳遞,這時數組會被復制到堆棧區中,這種操作的代價很高,除非是對特別小的數組。
systemverilog的語言參考手冊規定了ref參數只能用於帶自動存儲的子程序中(automatic funtion/automatic task/void function)。如果你對程序或模塊指定了automatic屬性,則整個程序內部都是自動存儲的。
ref參數的第二個好處是在任務里可以修改變量而且修改結果對調用他的函數是可見的。
task bus_read(input logic [31:0] addr, ref logic [31:0] data);
bus.request = 1'b1;
@(posedge bus.grant) bus.addr = addr;
@(posedge bus.enable) data = bus.data;
bus.request = 1'b0;
@(negedge bus.grant);
endtask
logic [31:0] addr, data;
initial fork
bus_read(addr, data);
thread2: begin
@data; //數據變化時觸發
$display("read %h from bus", data);
end
join