SystemVerilog(零):Verilog數據類型、語法、例程

聲明:本篇文章部分參考

https://www.cnblogs.com/protogenoi/p/8926993.html  Verilog筆記.1.基本語法   作者:Protogenoi 

一、Verilog語言整體印象

1、模塊是基本描述單位。端口默認是線網數據類型。端口長度聲明,默認1位。output [0:3] Z;4位

實例化:指調用軟件自帶的模塊(如內置門級元件)和自己編寫的模塊。

2、描述設計:有四種方式

1. 數據流描述方式:assign:連續賦值語句,語句併發。編譯器指令:` timescale 1ns /100ps 時間單位、時間精度

2. 行爲描述方式:過程語句initial、always。只有reg(寄存器)類型能在兩種語句中賦值。順序執行。

always=事 件控制(判斷條件)+順序過程。always語句塊可以理解爲while語句嗎?

3. 結構化描述方式:原語,硬件級, xor、and和or的實例語句

4. 混合設計描述方式:門實例語句,模塊實例語句、連續賦值語句,過程語句。

過程賦值vs連續賦值:

1.過程賦值改變寄存器的狀態,是時序邏輯,用在initial和always裏面;

2.連續賦值是組合邏輯,驅動線型變量(wire)

3、設計模擬:激勵、控制、存儲響應、設計驗證

1. 激勵和控制可以由初始化語句產生 

4、抽象模型分級

系統級:用高級語言結構實現設計模塊的外部性能的模型。

算法級:用高級語言結構實現設計算法的模型。

RTL級:描述數據在存儲器之間流動和如何處理這些數據的模型。

門級:描述邏輯門與邏輯門之間的連接的模型。

開關級:描述器件中三極管和存儲節點以及它們連接的模型。

二、Verilog語言要素

1、Verilog內置的12個門級元件,模塊可以實例引用門級模型, 對結構進行實例化描述。

                                                        

2、運算符 

(1) 算術運算符 +,-,*,/,%  

(2) 賦值運算符 =,<=

賦值語句:組合邏輯,順序執行,阻塞賦值,使用=賦值。時序邏輯,並行執行,非阻塞賦值,使用<=賦值。                      

(3) 關係運算符> ,<,>=,<=

(4) 邏輯運算符 &&, ||, ! (與或非)

(5) 條件運算符 ?:

(6) 位運算符 ~, | , ^ ,& ,^~ (取反、或、異或、與、同或)

(7) 移位運算符 << ,>>

(8) 拼接運算符 {}

3、特殊標識符

$開始的標識符表示系統任務/函數 。

ps: 函數vs任務。任務可以返回0或多個值,函數返回一個值。函數在0時刻執行,不允許延遲,任務可以帶有延遲。

'開始的標識符是編譯器指令。編譯器指令在整個編譯過程中有效(類似於宏定義) 

4、操作數

四種基本值:0,1,x,z:假,真,未知,高阻態。

三類常量:整形、實數型、字符串型。

整形表示法:

(1)十進制表示:<數字>   默認採用十進制

(2)基數表示法:<位寬>'<進制><數字>    位寬表示佔用二進制位數 (bodh:二八十十六)

5、數據類型

(1)線網和寄存器

Verilog兩大類數據類型:線網和寄存器,線網有11鍾類型,寄存器有5鍾類型。

線網類型:表示結構化元件間的物理連線,值由驅動元件決定。

寄存器類型:在always和initial語句賦值過程中的存儲單元。五種寄存器類型:reg,integer,time,real,realtime。

區別:wire只能由assign連續賦值語句中賦值,reg只能在initial/always過程賦值語句中賦值。

更多參考:https://www.cnblogs.com/wzd5230/p/3847481.html  verilog中wire與reg類型的區別

reg [msb:lsb] reg1   msb:lsb表示位數範圍,大小方向都可以。

reg [0:3] MyMem [0:64]   存儲器(寄存器數組)MyMem爲64個4位寄存器的數組。線網類型沒有對應點的存儲器類型。

(2)參數

定義一個標誌符代表一個常量(三種類型,如上),常用於定義延遲時間和變量寬度。

parameter <標誌符> =  <常量>

三、語句、子程序

1、賦值語句:Verilog中信號有兩種賦值方式

(1)連續賦值語句:assign  用於對線網進行賦值,等價於門級描述。

  1. 左值必須爲一個線網類型的變量或向量,不能是寄存器類型。
  2. 輸出值隨輸入值變化而隨時變化。
  3. 操作數可以是線網或寄存器或函數調用。
  4. 必須用“=”阻塞賦值進行賦值。

(2)過程賦值語句:=,<=

  •  非阻塞賦值方式( 如 b <= a; )
  1. 塊結束後才完成賦值操作。
  2. b的值並不是立刻就改變的。
  3. 這是一種比較常用的賦值方法。(特別在編寫可綜合模塊時)
  • 阻塞賦值方式( 如 b = a; )
  1. 賦值語句執行完後,塊才結束。
  2. b的值在賦值語句執行完後立刻就改變的。
  3. 可能會產生意想不到的結果。

2、塊語句:將多條語句結合在一起。塊語句有兩種,一種是begin_end語句,通常用來標識順序執行的語句,用它來標識的塊稱爲順序塊。一種是fork_join語句,通常用來標識並行執行的語句,用它來標識的塊稱爲並行塊

3、條件語句:if_else語句、case語句。略。

4、過程語句:initial、always。

        initial語句常用於仿真中的初始化,initial過程塊中的語句僅執行一次;always語句則是不斷重複執行的。

  每一條initial語句和always語句都是獨立的執行過程,彼此並行執行,執行順序於在模塊內的書寫順序無關,並且,每條initial和always語句過程語句都是在仿真時間0時刻同時開始的。

5、編譯預處理 `與系統指令#

1)宏定義 `define

2)“文件包含”處理`include

3)時間尺度 `timescale

4)條件編譯命令`ifdef、`else、`endif

6、循環語句:forever,repeat,while,for

參考文獻:https://www.cnblogs.com/SYoong/p/5857367.html  Verilog學習筆記基本語法篇(六)········ 循環語句

7、子程序:task、function

參考文獻:https://blog.csdn.net/HengZo/article/details/49688677  Verilog之function使用說明

參考文獻:https://www.cnblogs.com/SYoong/p/5865546.html  Verilog學習筆記基本語法篇(九)任務和函數

8、實例語句

模塊實例語句:<模塊名> <標誌符>(<對應端口1>,<對應端口2>...)

內置門實例語句:<關鍵字> <標誌符>(<輸出端口>,<輸入端口1>...) 這裏的關鍵字也叫內置門原語xor等,標誌符也叫實例名稱,括號裏是信號列表。信號列表有位置管理和名稱關聯兩種。

四、demo

1、全加器:邏輯:A加數 B被加數 Cin低位進位 S和 Cout高位進位

2、行爲描述方式:

// 行爲描述,全加器
module FA(a,b,ci,s,co);
input a,b,ci;
output s,co;
reg s,co,t1,t2,t3;

always @(a or b or ci) begin
	s=(a ^ b)^ci;
	t1=a & b;
	t2=a & ci;
	t3=b & ci;
	co=(t1|t2)|t3;
end
endmodule
`timescale 1 ns/ 1 ns
module FA_test();
reg Pa,Pb,Pci;
wire Ps,Pco;
FA F1(Pa,Pb,Pci,Ps,Pco); //模塊實例語句:待測模塊名 引用名(信號端口一一對應,位置關聯)

initial begin: ONLY_ONCE
reg [3:0] i;
	for (i=0;i<8;i=i+1)
	begin
		#20 {Pa,Pb,Pci}=i;
	end
end
endmodule

3、流水燈

module waterled(
	input	clk,
	input	rst,
	output reg [3:0] led
	);
 
reg [7:0] times;	
 
always @ (posedge clk or negedge rst) // 時鐘信號計數
begin
	if(!rst)       
		times<=1'b0; // 電路未復位,計數器鎖定爲0
	else
		if(times<8'd10) // 電路復位開始計數,計數到10重置
			times<=times+1'b1;
		else
			times<=8'd0;
end
 
always @ (posedge clk or negedge rst) // 計數滿10,四位數組中的1進位一次
begin
	if(!rst)
		led<=4'b0001; // 電路未復位 led[0]=1
	else
		if(times==8'd10) // 計數滿10,led高位到低位,1向前進位
			led<={led[2:0],led[3]};
		else
			led<=led;
end
endmodule
`timescale 1 ns/ 1 ns
module waterled_test;

wire [3:0] led;
reg rst,clk10;
                         
waterled i1 (clk10,rst,led);  //例化語句

always #10 clk10=~clk10;  // 產生時鐘信號                                          

initial begin                                                                         
	clk10=1'b0;
	rst=1'b0;
	#100 rst=1'b1; // 100ns時,電路復位 
	#1000 $stop; // 1000ns時,仿真暫停                      
end                                                    

endmodule

4、function demo

module comb15; 

function ADD; 
	input A, B;
	ADD = A ^ B;
endfunction 


initial begin
$display("Hello  %b",ADD(1'b1,1'b0));
end

endmodule

輸出1

module comb15; 

function signed [1:0] ADD; 
	input A, B;
	reg S;  
	S = A ^ B;
endfunction 

reg [31:0] N,M;
reg H;
initial begin
N = 100;
M = 100;
H = 32'd100;
$display("Hello",100);
$display("Hello",32'd100);
$display("Hello%b",32'd100);
$display("Hello%b",8'd100);
$display("Hello\n",100);
$display("Hello",N);
$display("Hello",M);
$display("Hello",H);
end

endmodule

display需要begin..and, 超過1句也需要begin..and。

其他參考資料:

https://wenku.baidu.com/view/0d8a1bd4195f312b3169a59c.html  verilog中reg和wire類型的區別

https://zhidao.baidu.com/question/135703718.html  請Verilog高手幫助!wire賦值問題

http://bbs.eetop.cn/thread-313513-1-1.html signed的用法

https://vlab.ustc.edu.cn/guide/doc_verilog.html  Verilog語法

https://zhidao.baidu.com/question/437300882386090484.html  綜合和仿真

Verilog這門語言真的是。。。語法臃腫代碼效率低。。。這把設計和驗證分開是爲啥子。。。不能斷點調試看變量的值。。。沒有ide。。。 不重視縮進。。。函數名與返回值是一個。。。線網和寄存器類型奇奇怪怪。。。魔!鬼!啊!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章