SV和Verilog的語法類似,和C/C++也有些共性,基本SV可包含Verilog的所有規則,本文會在以下博文內容外做補充,若有相異處下文會特意指出。Verilog語法可參考該鏈接第1大節。鏈接:https://blog.csdn.net/qq_39815222/article/details/89601331
1. 數據類型
- 二值邏輯和四值邏輯
編碼時一定要注意操作符左右兩側的符號類型要一致
二值邏輯:包括 bit, byte, shortint, int, longint等,均爲有符號類型(bit除外);這些類型的值只包含{0,1},目的是模擬計算機驗證環境,提高仿真性能,節約空間。若有四值邏輯數給其賦值,x,z會默認被賦值爲0,因此二值邏輯數要遠離DUT
四值邏輯:包括logic, integer, reg, wire等,均爲無符號變量(integer除外);目的是模擬外部物理世界 - logic
用法既拓展了傳統的reg型,也可以像wire那樣連線,但既然被應用在驗證場景中,因此無需關心對應的邏輯是否被綜合爲寄存器還是線網,只需作爲簡單的變量賦值即可。
注意:當含有多驅動(multi-drive)的場景是必須使用wire型。 - 動態數組和聯合數組
int array[]; //動態數組,compile時長度不確定,simulation時長度確定
array = new[20]; //new分配空間
logic [31:0] array[*]; //聯合數組,目的是節約空間 - 隊列
概念類似C語言裏的隊列,用法也類似,可自由插入刪除數據,
shortint queue[$] = { 1,2,3 }
queue.insert(1,7); //{1,7,2,3}
queue.delete(1); //{1,2,3}
queue.push_front(6); //{6,1,2,3}
queue.push_back(7); //{6,1,2,3,7}
j = queue.pop_front; //{1,2,3,7} 同理pop_back - 結構體
類似C語言裏的結構體,包括概念和用法 - 枚舉
enum logic [1:0] {...} state; //可定義z,x狀態
2. 語句
- 循環語句
循環語句用於控制執行語句的執行次數,用於在仿真代碼中生成仿真激勵信號。
for(int i=0; i<=5; i++)... //for循環,相較於verilog,i可以內部定義,且作爲局部變量,作用範圍只限於for循環
while(i<5) begin...end //while循環,同樣存在do...while()
foreach(src[i]) //foreach循環,和for功能類似,但foreach多了可編譯的功能,及判斷條件裏可有變量
src[i] = i;
- randomize()
隨機函數
class1 example1 = new;
if( example1.randomize() == 1)...
- 一些關鍵詞
- automatic... ref...
用在function/task賦值
function automatic void f1( ref data ) //此處data和外部定義的data共用同一物理地址,因此兩值同時變化
endfunction //若希望內部值的改變不影響外部值的改變,可在內部定義爲const ref data - automatic和static
automatic變量類似於軟件中的局部變量,在它的作用域生命結束時被銷燬回收存儲空間
static變量若在仿真開始時被創建,在進程執行過程中自身不會被銷燬,且會被多個進程共享。 - inside
if((a==1)||(a==2)||(a==3)) 等價於if( a inside {1,2,3}) - time
描述時間,單位爲timescale定義的精度 - rand
rand隨機化比較常用
rand bit [7:0] data1; //data1值取0-255中的任意數
randc bit [7:0] data2; //data2取0-255中任意值,但每次取值都不一樣,只限於bit和enum類型
constraint range1{ //約束data1範圍
data1>100; data1<200;
data1>data2; } - dist { value1 := weight1 value2 :/ weight2 }
劃分權重,用在隨機化操作中
[1:2]:=40; //每個數權重都是40
[1:2]:/40; //每個數權重是20 - solve...before...
用在隨機數產生時,constraint魔窟啊裏面
solve y before x //先產生x,再產生y - semaphores
創建對象可複用 - mailbox
創建一個信箱,使通信數據在不同process交換,可理解成fifo
- 一些符號及搭配
- 通配符 .*
可以把相同名字的net和port連在一起
test test1( .a(a), .b(b), .c(c) ); //或者 test test1( .a, .b, .c );
等同於 test t1( .* ); - ==? / !=?
判斷符號兩邊是否像相等或不等,x,z處做通配處理 - ++
SV裏面可以用自增符 - 'value 賦值
data0 = 'x //SV中賦值可無需添加b,o,h等代表進制的符號
data1 = '1 //SV中可給某個值賦值全1,注意Verilog中不行 - int'( value)
強制類型轉換,int也可以是其他數據類型或unsigned,signed - value1'( value2 )
位寬強制轉換,value1是位寬值 - ##
延遲一個時鐘週期 - |->
在當前時鐘週期
3. 語句塊
- program
program可以將設計和驗證的調度區域通過顯式的方式來安排。
該語句塊可在module直接被例化,語句塊裏面不能出現和硬件相關的過程語句和實例(如always,module等),但是可以有initial,task等塊,program與二者的關係類似於C語言裏的C文件與主函數,子函數的關係。
program內部定義的變量賦值的方式應該採用阻塞賦值,在驅動外部的硬件信號時應該使用非阻塞賦值。
$exit()強制結束該系統函數所在的program
program execute_test
initial begin
...
end
task task1()
...
endtask
endprogram
- clocking Block
爲了避免冒險競爭,通常會把clk驅動的同步信號封裝在一個模塊裏,由interface調用。 - interface
接口作爲中間將stimulator / monitor和DUT連接,可以集合多個信號,簡化連接,方便調用。
interface可以包含過程語句(always和initial)和連續賦值語句
interface可以定義輸入輸出端口,若接口對不同連接模塊的方向不同,可以將端口定義在modpot中
interface signal_test( input bit clk ); //定義
logic [1:0] A, B;
logic reset;
clocking dram @( posedge clk)
input #1ps A;
input #5
output #6 B;
endclocking
modport user1( output A, input B, reset); //聲明的端口可以在不同的modport裏定義爲不同的輸入輸出模式
modport user2( clocking cb, input reset); //調用clocking,port輸入輸出和user1不一樣
endinterface
always #5 clk = ~clk;
signal_test.user1 signal1(clk); //聲明user1模式
signal_temp signal2( .A(signal1.A), ......); //interface互相直接連接
test test1( signal1 ); //interface與module連接