《Verilog數字系統設計教程》第3版 夏宇聞


目錄

目錄

第1章 Verilog的基本知識

數字電路系統設計:

  1. 從上到下(從抽象到具體)逐層描述自己的設計思想,用一系列分層的模塊來描述極其復雜的數字系統。
  2. 利用EDA工具逐層進行仿真驗證
  3. 將需要編程具體物理電路的模塊組合經過自由綜合工具轉換到門級電路網表
  4. ASIC或者FPGA實現功能。

Verilog HDL和VHDL的比較:

image-20200113224032952

重點是Verilog簡單啊,入門容易。


邏輯網表EDIF:

EDIF是電子設計交換格式(Electronic Design Interchange Format)的英文字頭縮寫。

EDIF綜合了多種格式中的最佳特性,1985年的EDIF100版本提供了門陣列、半導體集成電路設計和布線自動化交換信息的格式,而后的EDIF200版本是不同EDA廠家之間交換設計數據的標准格式。CAD框架標准解決的是不同EDA廠家工具集成和實時通信問題,EDIF格式解決的是用不同EDA廠家工具完成設計的數據交流問題。

EDIF文件包含一系列的庫(libraries),每個庫包含一系列的單元(cells),每個單元具有1個或多個視圖(views)。

這塊不禁讓人向導Concept HDL啊,library、cell、views。不會之前好難,會了之后真香。

視圖使用原理圖(Schematic)、版圖(layout)、行為(Behaviour)和文檔(Document)等格式(View Type)來描述。每個視圖具有一個接口(interface)和一個內容(contents),通過它們來清晰定義視圖。Cell單元還通過(view map)屬性和其他View視圖相連。


HDL設計流程圖:

image-20200113230208126

第2章 Verilog語法的基本概念

Verilog既是一種行為描述語言,也是一種結構描述語言。

  • 行為描述—邏輯—reg形變量
  • 結構描述—連線—wire型變量

Verilog模型:

Verilog模型可以是實際電路的不同級別的抽象,這些抽象的級別和他們所對應的模型類型共有以下五種。

  1. 系統級(system-level)
  2. 算法級(algorithm-level)
  3. RTL級(register transfer level)
  4. 門級(gate-level)
  5. 開關級(switch-level)

Verilog語言本身非常適合算法級RTL級的模型設計。


示例1

module muxtwo(out,a,b,sl)
    input a,b,sl;
    output out;
    reg out;
    always@(sl or a or b)
        if (! sl) out = a;
    	else out =b;
endmodule

image-20200113234000055

示例2

module muxtwo(out,a,b,sl)
    input a,b,sl;
    output out;
    wire nsl,sela,selb;
    	assign nsl = ~sl;//阻塞賦值
    	assign sela = a&nsl;
    	assign selb = b&sl;
    	assign out = sela|selb;
endmodule

image-20200114001626805

wire型變量賦值表示某個邏輯輸出連接到這個線上面了。

wire形變量,體現了Verilog結構描述的部分。

示例3

module muxtwo(out,a,b,sl)
    input a,b,sl;
    output out;
    not			u1(nsl,sl);
    and		#1	u2(sela,a,nsl);
    and		#2	u3(selb,b,sl);
    or		#3	u4(out,sela,selb);
endmodule

image-20200114001817806

把示例1或者示例2轉換為示例3的過程成為綜合,示例3很容易跟某種工藝基本元件對應起來。

后續需要理解的部分:

  1. 符合何種風格的Verilog模塊是可以綜合的。
  2. 何種風格的模塊是不可以綜合的。
  3. 不可以綜合的Verilog模塊有什么作用等。

前面講過,綜合后產生門級電路網表


示例4

module adder(cout,sum,a,b,cin);
    input [2:0] a,b;//[MSB:LSB],所以是3bit
    input cin;
    output cout;
    output [2:0] sum;
    assign {cout,sum} = a+b+cin;
    //{,}是什么運算符?起拼接的作用 如 a = {b[5],b[4:0]},意思為 b的最高位和b的低五位拼接起來,組成的a為6位
endmodule

做了一個3bit的加法器。

示例5

module compare(equal,a,b);
    output equal;
    input [1:0] a,b;//[MSB:LSB],所以是2bit
    assign equal = (a==b)?1:0;
    /*如果a、b兩個輸入信號相等,輸出為1,否則為0*/
endmodule

做了一個2bit數比較器。

示例6

module trist2(out,in,enable);
    output out;
    input in,enable;
    bufif1 mybuf(out,in.enable);
endmodule

pic need to be inserted

內部套了一個實例化的三態門選擇器,

示例7

module trist1(sout,sin,ena);
    output sout;
    input sin,ena;
    mytri tri_inst(.out(sout),.in(sin),.enable(ena));
endmodule

module mytri(out,in,enable);
    output out;
    input in,enable;
    	assign out = enable?in:'bz;//'bz是高阻?
endmodule

模塊引用示例,.表示被引用模塊的端口。名稱必須與被引用模塊的端口定義一致,小括號中表示與該端口連接的線路(wire型變量)。

以上三個例子都是可以綜合的。


第2版

第一章 數字信號處理、計算、程序、 算法和硬線邏輯的基本概念

第二章 Verilog HDL設計方法概述

第三章 Verilog HDL的基本語法

3.1.簡單的Verilog HDL模塊

3.1.1.簡單的Verilog HDL程序介紹

  • Verilog HDL程序是由模塊構成的。每個模塊的內容都是嵌在module和endmodule兩個
    語句之間。每個模塊實現特定的功能。模塊是可以進行層次嵌套的。正因為如此,才可
    以將大型的數字電路設計分割成不同的小模塊來實現特定的功能,最后通過頂層模塊
    調用子模塊來實現整體功能。
  • 每個模塊要進行端口定義,並說明輸入輸出口,然后對模塊的功能進行行為邏輯描述。
  • Verilog HDL程序的書寫格式自由,一行可以寫幾個語句,一個語句也可以分寫多行。
  • 除了endmodule語句外,每個語句和數據定義的最后必須有分號。
  • 可以用/...../和//.......對Verilog HDL程序的任何部分作注釋。一個好的,有使用價值的源程序都應當加上必要的注釋,以增強程序的可讀性和可維護性。

3.1.2.模塊的結構

Verilog的基本設計單元是“模塊”(block)。一個模塊是由兩部分組成的,一部分描述接口,另一部分描述邏輯功能,即定義輸入是如何影響輸出的。栗子如下:

module block (a,b,c,d);
    input a,b;
    output c,d;
    
    assign c= a | b ;
    assign d= a & b;
endmodule

3.1.3.模塊的端口定義

模塊的端口聲明了模塊的輸入輸出口。其格式如下:
module 模塊名(口1,口2,口3,口4, ………);

3.1.4.模塊內容

模塊的內容包括I/O說明、內部信號聲明、功能定義。

  • I/O說明的格式如下:

    module module_name(input port1,input port2,…output port1,output port2… );

  • 內部信號說明:

    reg [width-1 : 0] R變量1,R變量2 。。。。;

    wire [width-1 : 0] W變量1,W變量2 。。。。;

  • 功能定義:

    模塊中最重要的部分是邏輯功能定義部分。有三種方法可在模塊中產生邏輯

    • 用“assign”聲明語句,如:

      assign a = b & c;
      
    • 用實例元件,如:

      and and_inst( q, a, b );
      
    • 用“always”塊,如:

      always @(posedge clk or posedge clr)
          begin
          if(clr) q <= 0;
          else if(en) q <= d;
      end
      

3.2.數據類型及其常量、變量

四種基本數據類型:

  1. reg型
  2. wire型
  3. integer型
  4. parameter型

3.2.1.常量

  1. 數字

    1. 整數

      整數常量的四種表示形式:

      1. 二進制整數(b或B)
      2. 十進制整數(d或D)
      3. 十六進制整數(h或H)
      4. 八進制整數(o或O)

      實際上常用的知識前三種。。

      數字表達方式:

      1. <位寬><進制><數字>這是一種全面的描述方式。
      2. <進制><數字>在這種描述方式中,數字的位寬采用缺省位寬(這由具體的機器系統
        決定,但至少32位)。
      3. <數字>在這種描述方式中,采用缺省進制十進制。
    2. x和z值

      在數字電路中,x代表不定值,z代表高阻值。一個x可以用來定義十六進制數的四位二進制數的狀態,八進制數的三位,二進制數的一位。z的表示方式同x類似。z還有一種表達方式是可以寫作?。在使用case表達式時建議使用這種寫法,以提高程序的可讀性。見下例:

      4'b10x0 //位寬為4的二進制數從低位數起第二位為不定值
      4'b101z //位寬為4的二進制數從低位數起第一位為高阻值
      12'dz //位寬為12的十進制數其值為高阻值(第一種表達方式)
      12'd? //位寬為12的十進制數其值為高阻值(第二種表達方式)
      8'h4x //位寬為8的十六進制數其低四位值為不定值

      對於0、x、z,可以表示十進制數的全部位;賦全0、全x或者全z可采用'b0、'bx或者'bz的方式;

      順帶,說道賦值,賦全1可采用賦~0或賦-1的方式較為簡潔。

    3. 負數

      一個數字可以被定義為負數,只需在位寬表達式前加一個減號,減號必須寫在數字定義表達式的最前
      面。注意減號不可以放在位寬和進制之間也不可以放在進制和具體的數之間。見下例:

      -8'd5 //這個表達式代表5的補數(用八位二進制數表示)
      8'd-5 //非法格式

    4. 下划線

      下划線可以用來分隔開數的表達以提高程序可讀性。但不可以用在位寬和進制處,只能用在具體的數
      字之間。見下例:

      16'b1010_1011_1111_1010 //合法格式
      8'b_0011_1010 //非法格式

  2. 參數(parameter)型

    看着類似宏定義!!不太一樣,可以使用#()將參數傳遞到module里面。

    在Verilog HDL中用parameter來定義常量,parameter型數據是一種常數型的數據,其說明格式如下:

    parameter 參數名1=表達式,參數名2=表達式, , 參數名n=表達式;

    模塊間傳遞參數:

    module Decode(A,F);
        parameter Width=1, Polarity=1;
        ……………
    endmodule
    
    module Top;
        wire[3:0] A4;
        wire[4:0] A5;
        wire[15:0] F16;
        wire[31:0] F32;
        Decode #(4,0) D1(A4,F16);//其中的#(4,0)向實例化的Decode模塊內部傳遞兩個參數值
        Decode #(5) D2(A5,F32);//其中的#(5)向實例化的Decode模塊內部傳遞一個參數值
    endmodule
    

    神奇!defparam語句在一個模塊中改變另一個模塊的參數

    module Test;
        wire W;
        Top T ( );
    endmodule
    
    module Top;
        wire W
        Block B1 ( );
        Block B2 ( );
    endmodule
    
    module Block;
    	Parameter P = 0;
    endmodule
    
    module Annotate;
        defparam//Test模塊里面實例化了一個Top模塊為T,T里面實例化的Block模塊B1、B2里面的參數都可以更改;
        //注意原始的模塊原型prototype申明里面的參數未改動
        Test.T.B1.P = 2,
        Test.T.B2.P = 3;
    endmodule
    

3.2.2.變量

兩個驅動源的表格:

wire/tri 0 1 x z
0 0 x x 0
1 x 1 x 1
x x x x x
z 0 1 x z
  1. wire型

    wire型數據常用來表示用於以assign關鍵字指定的組合邏輯信號。Verilog程序模塊中輸入輸出信號類型缺省時自動定義為wire型。wire型信號可以用作任何方程式的輸入,也可以用作“assign”語句或實例元件的輸出。

    wire型信號的格式同reg型信號的很類似。其格式如下:

    wire [n-1:0] 數據名1,數據名2,…數據名i; //共有i條總線,每條總線內有n條線路
    wire [n:1] 數據名1,數據名2,…數據名i;
    

    栗子:

    wire a; //定義了一個一位的wire型數據
    wire [7:0] b; //定義了一個八位的wire型數據
    wire [4:1] c, d; //定義了二個四位的wire型數據
    
  2. reg型

    寄存器是數據儲存單元的抽象。reg類型數據的缺省初始值為不定值,x。

    reg型數據常用來表示用於 “always”模塊內的指定信號, 常代表觸發器。 通常, 在設計中要由“always”塊通過使用行為描述語句來表達邏輯關系。在“always”塊內被賦值的每一個信號都必須定義成reg型。

    reg型數據的格式如下:

    reg [n-1:0] 數據名1,數據名2,… 數據名i;
    reg [n:1] 數據名1,數據名2,… 數據名i;
    

    栗子

    reg rega; //定義了一個一位的名為rega的reg型數據
    reg [3:0] regb; //定義了一個四位的名為regb的reg型數據
    reg [4:1] regc, regd; //定義了兩個四位的名為regc和regd的reg型數據
    
  3. memory型

    當一個reg型數據是一個表達式中的操作數時,它的值被當作是無符號值,即正值。例如:當一個四位的寄存器用作表達式中的操作數時,如果開始寄存器被賦以值-1,則在表達式中進行運算時,其值被認為是+15。

    數組中的每一個單元通過一個數組索引進行尋址。在Verilog語言中沒有多維數組存在。其格式如下:

    reg [n-1:0] 存儲器名[m-1:0];
    reg [n-1:0] 存儲器名[m:1];
    

3.3. 運算符及表達式

3.3.1.基本的算術運算符

算術運算符:+、-、*、/、%

3.3.2.位運算符

  • 取反~

    原bit ~原bit
    0 1
    1 0
    x x
  • 按位與&

    & 0 1 x
    0 0 0 0
    1 0 1 x
    x 0 x x
  • 按位或|

    | 0 1 x
    0 0 1 x
    1 1 1 1
    x x 1 x
  • 按位異或^(XOR)

    ^ 0 1 x
    0 0 1 x
    1 1 0 x
    x x x x
  • 按位同或^~

    ^~ 0 1 x
    0 1 0 x
    1 0 1 x
    x x x x
  • 不同長度的數據進行位運算

    自動的將兩者按右端對齊.位數少的操作數會在相應的高位用0填滿,以使兩個操作數按位進行操作.

3.3.3 邏輯運算符

邏輯運算符:!、&&、||

邏輯運算符中"&&"和"||"的優先級別低於關系運算符,"!" 高於算術運算符。不確定的加括號准沒錯。

3.3.4.關系運算符

關系運算符:>、<、>=、<=。

3.3.5.等式運算符

等式運算符: ==、!、===、!==

Case等式運算符:

=== 0 1 x z
0 1 0 0 0
1 0 1 0 0
x 0 0 1 0
z 0 0 0 1

邏輯等式運算符:

== 0 1 x z
0 1 0 x x
1 0 1 x x
x x x x x
z x x x x

3.3.6.移位運算符

a >> n 或 a << n;

a代表要進行移位的操作數,n代表要移幾位。這兩種移位運算都用0來填補移出的空位。

3.3.7.位拼接運算符(Concatation)

位拼接運算符{};

{信號1的某幾位,信號2的某幾位,..,..,信號n的某幾位}

位拼接還可以用重復法來簡化表達式。見下例:

{4{w}} //這等同於{w,w,w,w}

3.3.8.縮減運算符(reduction operator)

栗子:

reg [3:0] B;
reg C;
C = &B;
//相當於:
C =( (B[0]&B[1]) & B[2] ) & B[3];

3.3.9.優先級別

3.3.10.關鍵詞

3.4 賦值語句和塊語句

3.4.1 賦值語句

兩種賦值方式:

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

3.4.2 塊語句

verilog主要的模塊之間都是並行執行的,例如各個always之間、always與assign之間、assign之間,如果你在一個always中要對a賦值,而在另一個always中要使用a的值,這時候就要注意了,兩者並行的,處理先后不能確定。

塊語句有兩種,一種是begin_end語句,通常用來標識順序執行的語句,用它來標識的塊稱為順序塊。一種是fork_join語句,通常用來標識並行執行的語句, 用它來標識的塊稱為並行塊。

  1. 順序塊

    這里面的內容都是順序執行的,比如b=a; c=b,先執行一條,再執行下一條,那就是c=a了如果里面有兩組if/else,就是先執行前一組,再執行后一組。但是如果是非阻塞,那就要特殊對待,多個非阻塞賦值是在一個塊結束時一起執行的,比如b<=a; c<=b,那就跟之前不同了,當執行c<=b 時b還沒有變化成a的值,因此這個賦值的結果是b被賦值前的值,這兩條語句其實是獨立的、並行的。好處是放得先后順序沒關系,只要在一個塊內,隨便寫。

    順序塊有以下特點:

    1. 塊內的語句是按順序執行的,即只有上面一條語句執行完后下面的語句才能執行。
    2. 每條語句的延遲時間是相對於前一條語句的仿真時間而言的。
    3. 直到最后一條語句執行完,程序流程控制才跳出該語句塊。

    順序塊的格式如下:

    begin
        //語句1;
        //語句2;
        //......
        //語句n;
    end
    //或者
    begin:塊名
       	//塊內聲明語句
        //語句1;
        //語句2;
        //......
        //語句n;
    end
    
  2. 並行塊

    並行塊有以下四個特點:

    1. 塊內語句是同時執行的,即程序流程控制一進入到該並行塊,塊內語句則開始同時並行
      地執行。
    2. 塊內每條語句的延遲時間是相對於程序流程控制進入到塊內時的仿真時間的。
    3. 延遲時間是用來給賦值語句提供執行時序的。
    4. 當按時間時序排序在最后的語句執行完后或一個disable語句執行時,程序流程控制跳
      出該程序塊。

    並行塊的格式如下:

    fork//fork真有意思,分叉,fork()函數生成子進程也是分叉!!join,是又匯合了啊。。
        //語句1;
        //語句2;
        //......
        //語句n;
    join
    //或者
    fork:塊名
       	//塊內聲明語句
        //語句1;
        //語句2;
        //......
        //語句n;
    join
    
  3. 塊名

    在VerilgHDL語言中,可以給每個塊取一個名字,這樣做的原因有以下幾點。

    1. 這樣可以在塊內定義局部變量,即只在塊內使用的變量。
    2. 這樣可以允許塊被其它語句調用,如被disable語句。
    3. 在Verilog語言里,所有的變量都是靜態的,即所有的變量都只有一個唯一的存儲地址,因此進入或跳出塊並不影響存儲在變量內的值。
  4. 起始時間和結束時間

    在並行塊和順序塊中都有一個起始時間和結束時間的概念。對於順序塊,起始時間就是第一條語句開始被執行的時間,結束時間就是最后一條語句執行完的時間。而對於並行塊來說,起始時間對於塊內所有的語句是相同的,即程序流程控制進入該塊的時間,其結束時間是按時間排序在最后的語句執行完的時間。

3.5.條件語句

3.5.1. if_else語句

六點說明:

  1. 三種形式的if語句中在if后面都有“表達式” ,一般為邏輯表達式或關系表達式。系統對表達式的值進行判斷,若為0,x,z,按“假”處理,若為1,按“真”處理,執行指定的語句。
  2. 第二、第三種形式的if語句中,在每個else前面有一分號,整個語句結束處有一分號。
  3. 在if和else后面可以包含一個內嵌的操作語句(如上例),也可以有多個操作語句,此時用begin和end這兩個關鍵詞將幾個語句包含起來成為一個復合塊語句。
  4. 允許一定形式的表達式簡寫方式。
  5. if語句的嵌套
  6. if_else例子

3.5.2. case語句

一般形式如下:

case(表達式) <case分支項> endcase
casez(表達式)<case分支項> endcase
casex(表達式)<case分支項> endcase

case, casez, casex 的真值表:

case 0 1 x z
0 1 0 0 0
1 0 1 0 0
x 0 0 1
z 0 0 0 1
casez 0 1 x z
0 1 0 0 1
1 0 1 0 1
x 0 0 1 1
z 1 1 1 1
casex 0 1 x z
0 1 0 1 1
1 0 1 1 1
x 1 1 1 1
z 1 1 1 1

3.5.3.由於使用條件語句不當在設計中生成了原本沒想到有的鎖存器

栗子:

//有鎖存器
always @(al or d)
begin
    if(al) a<=d;
end
//無鎖存器
always @(al or d)
begin
    if(al) a<=d;
    else q<=0;
end
//****************************************
//有鎖存器
always @(sel[1:0] or a or b)
    case (sel[1:0])
        2'b00: q<=a;
        2'b11: q<=b;
    endcase
//無鎖存器
always @(sel[1:0] or a or b)
    case (sel[1:0])
        2'b00: q<=a;
        2'b11: q<=b;
        default: q<='b0;
    endcase

避免偶然生成鎖存器的錯誤。如果用到if語句,最好寫上else項。如果用case語句,最好寫上default項。遵循上面兩條原則,就可以避免發生這種錯誤,使設計者更加明確設計目標,同時也增強了Verilog程序的可讀性。

3.6.循環語句

四類循環語句:

  1. forever 連續執行的語句。

    forever循環語句常用於產生周期性的波形,用來作為仿真測試信號。它與always語句不同處在於不能獨立寫在程序中,而必須寫在initial塊中。

  2. repeat 連續執行一條語句n次。

    repeat(次數表達式) 語句;

  3. while 執行一條語句直到某個條件不滿足。如果一開始條件不滿足則一次都不執行。

    while(表達式) 語句;

  4. for 通過以下三個步驟來決定語句的循環執行。

    1. 先給控制循環次數的變量賦初試值
    2. 判定控制循環的表達式的值,為假則跳出循環,為真則執行指定的語句,轉到第三步。
    3. 執行一條語句來修正控制循環變量次數的變量的值,然后返回第二步。

3.7.結構說明語句

四種結構說明語句:

  1. initial 說明語句

    一個模塊中可以有多個initial塊,它們都是並行運行的。initial塊常用於測試文件和虛擬模塊的編寫,用來產生仿真測試信號和設置信號記錄等仿真環境。

  2. always 說明語句

    always@(敏感事件列表) 用於描述時序邏輯

    敏感事件上升沿 posedge,下降沿 negedge,或電平敏感事件列表中可以包含多個敏感事件,但不可以同時包括電平敏感事件和邊沿敏感事件;
    不可以同時包括同一個信號的上升沿和下降沿,這兩個事件可以合並為一個電平敏感事件。

    凡是always塊內輸出,都要定義成reg型的。
    由這一點也可以看出,定義成reg型的不一定全是寄存器。

    沿觸發的always塊常常描述時序邏輯, 如果符合可綜合風格要求可用綜合工具自動轉換為表示時序邏輯的寄存器組和門級邏輯,而電平觸發的always塊常常用來描述組合邏輯和帶鎖存器的組合邏輯,如果符合可綜合風格要求可轉換為表示組合邏輯的門級邏輯或帶鎖存器的組合邏輯。一個模塊中可以有多個always塊,它們都是並行運行的。


task和function說明語句不同點

任務和函數有些不同,主要的不同有以下四點:

  • 函數只能與主模塊共用同一個仿真時間單位,而任務可以定義自己的仿真時間單位。
  • 函數不能啟動任務,而任務能啟動其它任務和函數。
  • 函數至少要有一個輸入變量,而任務可以沒有或有多個任何類型的變量。
  • 函數返回一個值,而任務則不返回值。

栗子:

定義一任務或函數對一個16位的字進行操作讓高字節與低字節互換,把它變為另一個字(假定這個任務或函數名為: switch_bytes)。

//任務,返回的新字Byte是通過輸出端口的變量實現
switch_bytes(old_word,new_word);
//函數,返回的新字Byte是通過函數本身返回值實現
new_word = switch_bytes(old_word);

抄一些網上的說明:

  • task和function綜合出來的電路都是組合電路。。

  1. task 說明語句

    抄一些網上對task的說明:

    • module里可以含有task,但task里不可含有module;
    • task極少用在可綜合的設計中.因為task不支持always@xxxxxx,所以不能象c的函數那樣用.當然,task用在testbench很方便;【這塊有點不懂,是徹底不支持always還是不支持常用always實現的時序邏輯呢?】
    • task module之間的區別:主要的區別在於module可以實現很復雜的功能,里面可以包括時序和組合等各種設計要素;然而task卻不可以,task里面不可以有always這樣的語句,亦即task即使實現某種邏輯功能,也只能實現組合邏輯功能(如果寫成module就不局限於此)。還有task可以自己調用自己,並且這樣也有可能是可綜合的;而module是不可以自己例化自己的,這是不合法的,更不要說可否綜合。
  2. function 說明語句

    與任務相比較函數的使用有較多的約束,下面給出的是函數的使用規則:

    1. 函數的定義不能包含有任何的時間控制語句,即任何用#、@、或wait來標識的語句。
    2. 函數不能啟動任務。
    3. 定義函數時至少要有一個輸入參量。
    4. 在函數的定義中必須有一條賦值語句給函數中的一個內部變量賦以函數的結果值,該內部變量具有和函數名相同的名字。

3.8.系統函數和任務

3.8.1.$display和​$write任務

3.8.2.系統任務$monitor

3.8.3.時間度量系統函數$time

3.8.4.系統任務$finish

3.8.5.系統任務$stop

3.8.6.系統任務$readmemb和$readmemh

3.8.7.系統任務$random

3.9.編譯預處理

預處理命令以符號“ `”開頭(注意這個符號是不同於單引號“ '”的)。

3.9.1.宏定義 `define

3.9.2.“文件包含”處理`include

3.9.3.時間尺度 `timescale

3.9.4.條件編譯命令`ifdef、`else、`endif

3.10.小結

Verilog和c語言不同且需要着重理解的點:

  1. 塊與塊之間的並行執行的概念;
  2. task和function的概念。
  3. Verilog HDL還有許多系統函數和任務也是C語言中沒有的如:$monitor、$readmemb、$stop等等
  4. 其他

第四章 不同抽象級別的Verilog HDL模型

4.1.門級結構描述

4.1.1.與非門、或門和反向器等及其說明語法

八個基本的門類型GATATYPE:

  • and 與門
  • nand 與非門
  • or 或門
  • nor 或非門
  • xor 異或門
  • xnor 異或非門/同或門
  • buf 緩沖器
  • not 非門

4.1.2.用門級結構描述D觸發器

Code:

module flop
    (
        input data,clock,clear;
        output q,qb;
    )
    nand	#10 nd1(a,data,clock,clear),
    			nd2(b,ndata,clock),
                nd4(d,c,b,clear),
                nd5(e,c,nclock),
                nd6(f,d,nclock),
                nd8(qb,q,f,clear);
    nand	#9	nd3(c,a,d),
				nd7(q,e,qb);
    not 	#10	iv1(ndata,data),
				iv2(nclock,clock);
endmodule

image-20200130211039862

想要了解D flip-flop觸發器,需要先看一下D latch鎖存器,最好能先看看SR 鎖存器,既然都看了SR鎖存器了,順帶把555定時器也看一下最好。最能能一塊把觸發器flip-flop、鎖存器latch、寄存器register之間的區別和聯系一塊屢清楚。

4.1.3.由已經設計成的模塊來構成更高一層的模塊

上一小結編寫的flop模塊引用如下:

  1. flop f1op_d( d1, clk, clrb, q, qn);
  2. flop flop_d (.clock(clk),.q(q),.clear(clrb),.qb(qn),.data(d1));

栗子:

module hardreg(d,clk,clrb,q);
    input clk,clrb;
    input[3:0] d;
    output[3:0] q;
    flop f1(d[0],clk,clrb,q[0],),
    f2(d[1],clk,clrb,q[1],),
    f3(d[2],clk,clrb,q[2],),
    f4(d[3],clk,clrb,q[3],);
endmodule

4.1.4 用戶定義的原語(UDP)

對於數字系統的設計人員來說,只要了解UDP的作用就可以了,而對微電子行業的基本邏輯元器件設計工程師,必須深入了解UDP的描述,才能把所設計的基本邏輯元件,通過EDA工具呈現給系統設計工程師。

4.2.Verilog HDL的行為描述建模

4.2.1僅用於產生仿真測試信號的Verilog HDL行為描述建模

待補充

4.2.2.Verilog HDL建模在TOP-DOWN設計中的作用和行為建模的可綜合性問題

待補充

4.3.用Verilog HDL建模進行TOP-DOWN設計的實例

【重點待補充】

4.4.小結

目前,用門級和RTL級抽象描述的Verilog HDL模塊可以用綜合器轉換成標准的邏輯網表;用算法級描述的Verilog HDL模塊,只有部分綜合器能把它轉換成標准的邏輯網表;而用系統級描述的模塊,目前尚未有綜合器能把它轉換成標准的邏輯網表,往往只用於系統仿真。

第五章 基本運算邏輯和它們的 Verilog HDL 模型

5.1 加法器

待補充

5.2 乘法器

待補充

5.3 比較器

待補充

5.4 多路器

待補充

5.5 總線和總線操作

待補充

5.6 流水線(pipeline)

待補充

第六章 運算和數據流動控制邏輯

6.1 數字邏輯電路的種類

待補充

6.2 數字邏輯電路的構成

待補充

6.3 數據流動的控制

待補充

6.4 為什么在 Verilog HDL 設計中一定要用同步而不能用異步時序邏輯

待補充

第七章 有限狀態機和可綜合風格的Verilog HDL

有限狀態機(Finite-State Machine,FSM),又成為有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。筆者常在電機控制、通信協議解析等應用場景下應用FSM。 本文所講的是基於硬件描述語言Verilog HDL的有限狀態機的編寫技巧及規范。眾所周知FPGA以其並行性和可重構性為世人所知,而在當今的電子世界,基本所有的器件都是串行的,所以作為控制單元或者是可編程單元的FPGA需要進行並行轉串行與外界進行通信、控制等,而有限狀態機以其簡單實用、結構清晰而恰如其分的充當着這個角色。

7.1.有限狀態機

【重點待補充】

gantt section 設計 需求 :done, des1, 2014-01-06,2014-01-08 原型 :active, des2, 2014-01-09, 3d UI設計 : des3, after des2, 5d 未來任務 : des4, after des3, 5d section 開發 學習准備理解需求 :crit, done, 2014-01-06,24h 設計框架 :crit, done, after des2, 2d 開發 :crit, active, 3d 未來任務 :crit, 5d 耍 :2d section 測試 功能測試 :active, a1, after des3, 3d 壓力測試 :after a1 , 20h 測試報告 : 48h

7.2. 可綜合風格的Verilog HDL模塊實例:

7.2.1.組合邏輯電路設計實例

7.2.2. 時序邏輯電路設計實

7.2.3.狀態機的置位與復位

7.2.3.1. 狀態機的異步置位與復位

7.2.3.2. 狀態機的同步置位與復位

7.2.4.深入理解阻塞和非阻塞賦值的不同

7.2.5. 復雜時序邏輯電路設計實踐

第八章 可綜合的VerilogHDL設計實例

---簡化的RISC CPU設計簡介---

8.1.什么是CPU?

8.2. RISC CPU結構

八個基本部件:

1)時鍾發生器
2)指令寄存器
3)累加器
4)RISC CPU算術邏輯運算單元
5)數據控制器
6)狀態控制器
7)程序計數器
8)地址多路器

8.2.1時鍾發生器

8.2.2 指令寄存器

8.2.3.累加器

8.2.4.算術運算器

8.2.5.數據控制器

8.2.6.地址多路器

8.2.7.程序計數器

8.2.8.狀態控制器

8.2.9.外圍模塊

8.3. RISC_CPU 操作和時序

8.3.1.系統的復位和啟動操作

8.3.2.總線讀操作

8.3.3寫總線操作

8.4.RISC_CPU尋址方式和指令系統

8.5. RISC_CPU模塊的調試

8.5.1. RISC_CPU模塊的前仿真

8.5.2. RISC_CPU模塊的綜合

8.5.3.RISC_CPU模塊的優化和布局布線

第九章 虛擬器件和虛擬接口模型

9.1 虛擬器件和虛擬接口模塊的供應商

9.2 虛擬模塊的設計

9.3 虛擬接口模塊的實例

第十章 設計練習進階

【非常重要,多練習!!】


免責聲明!

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



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