Verilog語法知識點總結(轉)


1.1 概述

 

條目

說明

分類

1>> 面向設計的語句; // 可綜合。

2>> 面向測試的語句; //testbench ,不可綜合。

特點

設計語句 assign , always ,模塊例化,都對應實際電路,並行執行。

構造

 

 

 

 

1.2 模塊 Module

 

條目

說明

模塊名(端口列表)

整個電路的外特性,抽象為黑盒子;

端口方向

input , output ; inout ;

端口類型

wire , reg ;

端口類型是 wire 時可以省略。

例: input a ; // 端口方向為輸入,類型默認為 wire ;

 

 

 

 

 

1.3 數據類型

 

      1.3.1 wire/reg 線網

 

wire 和 reg 都是線類型,工程上沒區別;只是 always/initial 模塊中輸出定義需要為 reg 型;

注意:不要將 reg 類型與 D 觸發器混淆, reg 理解為因為代碼所產生的。

 

例如:

 

wire [7:0] a; // 定義了 8 位的 wire 型數據

wireb; // 定義了 1 位的 wire 型數據

reg [3:0]sum ; // 定義了一個 4 位的 reg 型數據

 

1.3.2 常量

 

類型

格式

說明

parameter

parameter 數據名 = 表達式

parameterMSB = 7 ;
// 定義參數 MSB 為常量 7 ;推薦大寫;

常量

< 位寬 >< 進制 >< 數字 >

二進制: B 或 b ;

十進制: D 或 d ;

八進制: O 或 o ;
十六進制: H 或 h ;

8’b1010_1100 (‘b 表示二進制 )
下畫線“ _”, 提高閱讀性。

< 數字 >

默認十進制;

4 值邏輯

0 : Logic Low

低電平;

1 : Logic High

高電平;

x : Unknow ;

不確定;

z : High Impedance ;

高阻態; // 三態門

 

1.4 運算符

 

     1.4.1 概述

 

運算符

說明

算術運算符

+ ( 加 ) , - (減), * (乘), / (除), % (取模);

每個運算符在電路中都是個模塊,如加法器,減法器;

!注意:除法,除 2^n ,是移位運算,

浮點運算就復雜了,因此浮點運算要專用除法器;

關系運算符

>, <, >=, <= , == (相等), ! = (不相等);

邏輯運算符

&& (邏輯與) . || (邏輯或) , ! (邏輯非);

條件判斷語句中,為避免歧義,邏輯運算符二邊推薦為 1bit ;

位運算符

& (與), | (或), ~ (非) , ^ (異或) ; ~^ (同或);

移位運算符

<< (左移), >> (右移);

歸約操作

& , ~& , | , ~| , ^, ~^;//unary reduction ;

條件運算符

?:

拼接運算符

{}

//{3{a[0]}}: 代表 3 根同樣的 a[0] 線, {a[0],a[0],a[0]}

 

1.5 設計語句

 

    1.5.1 assign (連續賦值)

 

實例

說明

assigny = ~ b ;

assign out = a==1 && c==1 ;

assign f = sel ? a : b ;

>> 實現可以用布爾函數描述的組合邏輯電路;

>>“=” 后面可以是任何布爾函數;

>> 並行執行;

典型錯誤 1 :

assigna = b + a;

避免出現反饋電路:變為了不可知時序邏輯電路;

 

 

 

 

 

1.5.2  always (過程塊)

 

a、賦值

 

賦值方式

說明

= ,阻塞賦值

always @ ( a or b or C or … )

begin

語句塊( = , if 語句, case 語句)

end

實現:組合邏輯電路;(注意!禁止用於時序邏輯電路)

always 塊內,阻塞賦值:是順序執行(類似 C );

敏感表: @ ( * ) //“*” 自動添加相關輸入信號;

避免出現 Latch (鎖存器)

分支語句( if 語句, case 語句)條件不滿時,會在電路中自動生成鎖存器來保存不滿足條件的值,因此要補全 if-else ,和 case 的 defalut 語句;

<= ,非阻塞賦值

always @ ( posedge clk or negedge rst_n )

begin

語句塊( <= , if 語句, case 語句)

end

實現:時序邏輯電路;(注意!禁止用於組合邏輯電路)

always 塊內,阻塞賦值:並行執行;

 

b、if 語句

 

條目

說明

格式 1

if( 條件 )begin

語句 1;

語句 2 ;

end

else begin

語句 1 ;

語句 2 ;

end

格式 2

if( 條件 )begin

語句 1;

語句 2 ;

end

else if begin

語句 1 ;

語句 2 ;

end

else begin

語句 1 ;

語句 2

end

特點

分支語句,各個分支條件不同;順序執行判斷;

注意

if-else 成對使用;

 

c、case 語句

 

條目

說明

格式

case( 表達式 )

常量表達式 1:begin

語句;

end

常量表達式 2:begin

語句;

end

常量表達式 3:begin

語句;

end

default :

語句;

endcase

特點

分支語句,各個分支條件相同;並行執行判斷;

注意

default 語句不可省略;

 

 

d、代碼 & 硬件

 

條目

說明

映射

賦值語句 -> 邏輯函數; // 加法器,減法器等;

邊沿型條件分支 -> D 觸發器;

條件分支 -> 多路選擇器;

示例

 

 

 

 

1.5.3 模塊例化

 

 

a、作用

 

系統設計時,建議遵循以下設計原則:

 

 

 

 

 

 

b、常見的典型錯誤如下所示:

 

 

 

 

 

 

1.5.4 全加器

 

全加器頂層: w1 , w2 , w3 :模塊之間連線;

 

 

半加強: 2 種描述方法,如下:

 

 

 

 

描述方式

描述方式

說明

位置關聯

AND u1(a, b, and_out);

名字關聯

AND u1(.a(a), .b(b), .o ( and_out ) ); // 推薦使用

 

 

1.6 測試語句

     

     1.6.1 結構

 

Testbench

 

 

 

 

 

 

 

1.6.2 特殊符號

 

語句

說明

`< 標識符 >

表示:

編譯引導語,用於指導仿真編譯器在編譯時采取一些特殊處理;

編譯引導語句一直保持有效,直到被取消或重寫;

`timescale

`timescale < 時間單位 >/< 時間精度 >

例 1 :

`timescale 1ns/1ns // 時間單位 1ns ;時間精度 1ns ;

#2 // 延時 2 ×1=2ns ;

#2.1// 延時 2.1 × 1 = 2.1ns, 精確到 1ns ,為 2ns ;

例 2 :

`timescale 1ns/100ps // 時間單位 1ns ;時間精度 100ps ;

#2 // 延時 2 ×1= 2ns ;

#2.1// 延時 2.1 × 1 = 2.1ns, 精確到 100s ,為 2.1ns ;

`define

 

`include

`include “global.v”

包含另一個文件,完整拷貝過來;

`restall

把所有設置的編譯引導恢復到缺省狀態;

 

#<num>;

#10; // 延遲 10 個時間單位

 

  1.6.3 語句

 

語句

說明

initial

塊語句:只執行一次, always 循環執行;不可綜合;

作用:

產生激勵信號;

檢查輸出波形;

賦初值;

forever

// 產生周期信號:

intial begin

clk = 0 ;

forever

#10 clk = ~clk; // 時鍾信號

end

 

1.6.4 系統任務和函數

 

條目

說明

$< 標識符 >

表示 Verilg 的系統任務和函數

$time

當前的仿真時間

$display

顯示信號值變化:只執行一次,打印當前時刻;

$display($time, “b% %b %b” , rst,clk,dout);

$monitor

監視信號值變化:所有過程時刻;

$monitor($time, “b% %b %b” , rst,clk,dout);

$stop

暫停仿真

$finish

結束仿真,釋放電腦資源;

 

1.7 代碼模板

 

      1.7.1 組合邏輯電路

 

條目

說明

assign

assign add_cnt = flag==1; // 用於簡單的組合邏輯電路;

always

always @(*)begin// 統一采用“ *” 為敏感列表;

( =,if,case )語句; // 只能使用“ =” 賦值

end

 

1.7.2 時序邏輯電路

 

a、計數器模板 1

 

3 段式模板

模板 1

1

計數段

always @( posedge cllk or negedge rst_n) begin

if (!rst_n)

cnt <= 0; // 初值規定為 0

else if (add_cnt)begin// 【位置 1 】

if(end_cnt)

cnt <= 0;

else

cnt <= cnt + 1;

end

end

2

加 1 條件

assingadd_cnt = d==1; //d==1 :什么時候開始數脈沖

3

結束條件

assing end_cnt = add_cnt&& cnt == X-1; // X: 數多少個脈沖

 

b、計數器模板 2

 

3 段式模板

模板 1

1

計數段

always @( posedge cllk or negedge rst_n) begin

if (!rst_n)

cnt <= 0; // 初值規定為 0

else if (add_cnt) begin// 【位置 1 】

if(end_cnt)

cnt <= 0;

else

cnt <= cnt + 1;

end

else

cnt <= 0; // 不連續,需要清 0 時,使用模板 2 ;

end

2

加 1 條件

assingadd_cnt = d==1; //d==1 :什么時候開始數脈沖

3

結束條件

assing end_cnt = add_cnt&& cnt == X-1; // X: 數多少個脈沖

 

c、 4 段式狀態機模板

 

段號

代碼

1

// 初始化,次態賦值給現態,明確當前狀態;

always @(posedge clk or negedge rst_n) begin

if(!rst_n)

state_c <= S00;// 初始狀態

else

state_c <= state_n;

end

2

always @( * ) begin // 組合邏輯,描述狀態轉換目標

case(state_c)

S00: begin

if(s00_s20_start) // 條件名 S00->S20

state_n = S20;

else

state_n = state_c; // 方便拷貝

end

S20: begin

if(s20_s21_start)

state_n = S21;

else

state_n = state_c;

end

S21: begin

if(s21_s00_start)

state_n = S00;

else

state_n = state_c;

end

default: begin

state_n = S00;

end

endcase

end

3

// 具體的轉換條件內容

assign s00_s20_start = state_c==S00&& ( 條件 ) ;

assign s20_s21_start = state_c==S20&& ( 條件 );

assign s21_s20_start = state_c==S21&& ( 條件 );

4

根據轉態設計輸出:

1 個 always 設計 1 個輸出信號;

 

 

 

1.7.3 Testbench

 

 

 a、框架

 

條目

內容

模塊名

`timescale 1 ns/1 ns

module testbench_name();

信號定義

reg clk ; // 時鍾

reg rst_n; // 復位

reg[3:0] din0 ; //uut 的輸入信號 ,定義為 reg 型,在 initial 中

reg din1 ;

wire dout0;//uut 的輸出信號, 定義為 wire 型

wire[4:0] dout1;

parameter CYCLE = 20; // 參數定義,方便修改;

parameter RST_TIME = 3 ;

待測模塊例化

module_name uut( // 統一采用名字關聯

.clk ( clk ),

.rst_n ( rst_n ),

.din0 ( din0 ),

.din1 ( din1 ),

.dout0 ( dout0 ),

.dout1 ( dout1 )

);

激勵產生

// 復位,時鍾 ,等

顯示輸出結果

$display // 類似 printf ;

 

 

b、復位

 

復位

initial begin

rst_n = 1;

#2;

rst_n = 0;

#(CYCLE*RST_TIME);

rst_n = 1;

end

 

c、仿真時鍾

 

仿真時鍾

initial begin

clk = 0;

forever

#(CYCLE/2)

clk=~clk;

end

 

 

d、激勵信號

 

激勵信號

initial begin

#1;// 方便觀測

din1 = 0; // 賦初值

#(10*CYCLE);

// 開始賦值

end

 

以上就是總結的 Verilog 語法相關知識點,轉自明德揚論壇

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM