日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Verilog 之并行,數據類型,操作符號等相關基礎歸納

作者:yb_voyager 更新時間: 2022-09-05 編程語言

本文為相關讀書筆記,做個人理解之用

文章目錄

    • 組合邏輯電路與時序邏輯電路
    • 同步時序邏輯和異步時序邏輯
    • Verilog并行語句
    • Verilog 數據類型
    • Verilog的操作符號

組合邏輯電路與時序邏輯電路

組合邏輯: 數字電路滿足任意時刻的輸出僅僅取決于該時刻的輸入;

時序邏輯: 數字電路任意時刻的輸出取決于當前輸入以及電路原有的狀態;

時序邏輯電路中肯定有組合邏輯的成分存在, 組合邏輯不能有時序邏輯的功能;

同步時序邏輯和異步時序邏輯

時序邏輯按信號間關系分為同步時序邏輯和異步時序邏輯,簡稱同步邏輯,異步邏輯;

異步邏輯中肯定由同步邏輯存在,

同步時序邏輯

狹義: 一個時鐘信號驅動的設計, 所有的記憶元素(寄存器, RAM, Latch)都被同一個時鐘信號驅動,輸出同時變化;

廣義: 允許數字電路中存在多個時鐘,但其之間存在固定的因果關系,或其驅動的記憶單元在電路上完全隔離;

異步時序邏輯

異步時序邏輯電路 — 輸入輸出端口不全來自或導入一個時鐘或若干具備因果的時鐘所驅動的記憶元素;

Verilog并行語句

module中的語句部分都是并行的,并行語句如下:

module <module_name>(<port_list>);
    <verilog 連續賦值語句>;
    <verilog 程序塊語句>;
    <verilog 實例化語句>;
    <verilog 生成語句>;
    <verilog 函數調用語句>;
    <verilog 模塊說明語句>;
endmodule
  • 連續賦值語句

    assign a = 1'b1;
    //簡寫:
    wire a = 1'b1;
    
    assign a = sel ? b : c;
    //簡寫:
    wire a = sel ? b : c;
    
  • 程序塊語句

    always@(<sensitive_list>)
    begin: <lable>
    	<statements>;
    end
    //<labe> : 程序塊標號
    //敏感列表邊沿事件:
    //寄存器的一個時鐘端口決定一個always敏感量表只能有一個時鐘的一個邊沿事件********;
    //異步復位的邊沿事件其實是電平敏感事件;
    
    • 純組合邏輯always

      只使用非阻塞 “=” 賦值符號;

      敏感量表不能使用posedge / negedge 關鍵字;

      敏感量表可以為 “*”,交由編譯器推斷;

    • 純時序always

      沒有什么注意的,遵循正常使用語法即可;

      always@( <edge_type> clk)
      begin
          <statements>
      end
      //使用阻塞賦值 <=
      
    • 具有同步復位的always

      always@( <edge_type> clk)
      begin
          if(!rst_n)
          	<statements>;
          else
          	<statements>;
      end
      
      
    • 具有異步復位的always

      always@( <edge_type> clk,<edge_type> rst)
      begin
          if(rst)
          	<statements>;
          else
          	<statements>;
      end
      //注意敏感量列表中的異步復位信號必須注明為沿事件, 因為敏感量表一旦出現沿事件(時鐘沿事件),就不允許出現描述組合邏輯的信號事件;
      
  • 實例化語句

    • 單獨實例化

      正常的子模塊例化語法,類似 類和對象的用法;

      模塊輸出只能連接線網, 輸入連接 寄存器 和線網;

    • 數組實例化

      應用于一個模塊多次的場景,語法如下:

      <module_name> <instance_name> <instance_array_range>
      (
          .<port_name_0> <variable_0>,
          .<port_name_1> <variable_1>,
          .<port_name_n> <variable_n>
      );
      
      //實例
      wire [3:0] a,b,c;
      module1 inst_module[3:0] 
      (
          .in0(a),
          .in1(b),
          .out(c)
      );
      //相當于:
      module1 inst_1 (.in0(a[3]),.in1(b[3]),out(c[3]));
      module1 inst_2 (.in0(a[2]),.in1(b[2]),out(c[2]));
      module1 inst_3 (.in0(a[1]),.in1(b[1]),out(c[1]));
      module1 inst_4 (.in0(a[0]),.in1(b[0]),out(c[0]));
      //上述端口也可公用信號
      
      

      使用數字實例化時要注意輸入的變量位寬等于多有實例對應位寬之和或等于模塊對應的位寬;

    • 實例參數重載

      對參數進行修改的動作;

      1. 內部重載

        實例化時進行對參數進行修改, 比較常用;

        module_1 #.(.<parameter_name> (name_value),...)
        inst_moudle_1(.a(a),.b(b));
        
      2. 外部重載

        允許才編譯的時候在修改參數的值;

        module_1 inst_module_1(.a(a),.b(b));
        defparam inst_module_1.parameter_name = value;
        
    • 端口賦值形式

      1. 映射賦值

        常用使用形式

        wire a,b,c;
        module_0 inst(.in0(a),.in1(b),.out(c));
        
      2. 位置賦值

        wire a,b,c;
        module_0 inst(a,b,c);
        
      3. 部分賦值

        wire a,b,c;
        module_0 inst(.in0(a),.out(c));
        module_0 inst(a,,c); //此時必須按照端口位置使用","進行占位
        
      4. 常數賦值

        //只能應用于輸入端口
        wire a,b,c;
        module_0 inst(.in0(a),.in1(1'b1),.out(c));
        
      5. 表達式賦值

        wire a,b,c;
        module_0 inst(.in0(a),.in1(~a),.out(c));
        
  • 生成語句

    • 循環生成

      genvar a;
      generate
          for(a = 0; a < 100;a = a + 1)
          begin:<lable> //此處的begin 不能省略
              <statement>;//可以時實例化語句也可以是連續賦值語句
          end
      endgenerate
      //for 循環可以嵌套
      //舉例:
      input [3:0] a,b;
      output [3:0] c,d;
      generate
      genvar i;
          for(i = 0;i < 4;i = i + 1)
          begin: test_gen
              module_1 inst(.a(a[i]),.b(b[i]),.c(c[i]));
              assign d[i] = a[i];
          end
      endgenerate
      

      變量必須用genvar進行定義;

      必須給循環段起一個名字,

    • 條件生成

      作用于編譯器行為,根據初始參數決定載入哪部分代碼進行編譯;參數再修改后必須進行重新編譯并不支持動態選擇;

      generate
          if(<condition>)
          begin:<lable_1>
      		<code>; 			           
          end
          else if(<condition>)
          begin:<lable_2>
              <code>;
          end
          else
          begin;<lable_3>
              <code>;
          end
       end
      
  • 函數調用語句

    function [<lower>:<upper>] <output_name>;
        input <name>;
        <other inputs>
        <variable declarations>
        begin
           <statements> 
        end
    endfunction
    //<output_name>即是輸出的變量名也是函數調用名, 其位寬由前面的范圍決定;
    //<variable declarations>只能聲明寄存器類型的變量
    //函數體中只能使用 阻塞賦值
    //函數調用中只能使用位置賦值, 并嚴格遵守input順序
    //函數調用在串行語句和并行語句中均可;
    //函數中可以調用別的函數;
    //遞歸函數用于仿真;
    //函數不能調用task;
    //盡量在仿真中使用函數為不是功能模塊中;
    
  • 模塊說明語句

    specify
        <參數定義>
        <時序檢查選項>
        <模塊中的組合邏輯管教到管腳的時間延遲>
        <模塊中的時序邏輯時鐘相關的時間延遲>
        <條件延遲語句, 類似條件生成語句>
    endspecify
    

Verilog 數據類型

Verilog 四值邏輯系統

邏輯1 : 表示邏輯高電平;

邏輯0 : 表示邏輯低電平;

不確定邏輯X : 表示不可推斷電平, 一般由于賦值沖突導致;

高組邏輯Z : 表示高阻態, 斷路;

寄存器數據類型

凡在程序塊中被賦值的變量,都必須是寄存器類型,寄存器類型及其子類型如下:

  • reg
reg <range> <variable_name>; //range 不寫默認 1bit
  • integer 整數類型 , 對應32位二進制表示 real 實數類型,一般不用
integer a; real a;

線網數據類型

  • wire
wire <range> <variable_name>;
  • tri 用法同wire . 需定義被三態門驅動的硬件連線時,用tri定義.表示這根線上會出現 Z狀態;

  • supply1/ supply0

    分別表示強行上拉到1, 或強行下拉到0. 理解為電源線和地線. verilog中常當做常數使用;

  • wand / triand

    表示線與邏輯, 二者區別類似wire與tri;

  • wor / trior

    表示線或邏輯, 二者區別類似wire與tri;

  • tri1 / tri0 / trireg

    分別表示當連線被置為高阻態時, 進行上拉 , 下拉 , 保持前值,;

參數數據類型

  • parameter 定義module里的一些常量參數

    parameter a = 100,b = 3'b100, c = a + 100;
    
  • localparam 定義module里的一些參數,與parameter參數不同在于上層模塊不能訪問此參數

    //如下的使用形式可以實現上層對下層模塊的修改
    parameter N = 100;
    localparam M = N + 1;
    
  • specparam 用于specify用來定義模塊的時序模型 ;

數組

<type> <type_range> <array_name> <array_range>;
//定義一個32bit寬,512個元素的存儲器
reg [31:0] array[511:0];
//數組的訪問, 不能使用C語言類似的訪問
wire [31:0] out;
assign out = array[256];
//數組的bit訪問
wire [0:0] out_bit;
assign out_bit = out[31];

常量

  1. 二進制表示法
<bit_width>'b <constant in binary>
wire a ;
assign a = 1'b1;
wire [7:0] b;
assign b = 8'b11110000;
//設置高阻狀態
assign b = 8'bzzzzZZZZ;
//沒有關于x的狀態的常量賦值,因為X狀態是由賦值沖突產生的,并不是由賦值產生;
  1. 八進制表示法
<bit_width>'o <constant in octonary>
wire [2:0] a;
assign a = 3'o5;  // o / O均可;
//高阻
wire [5:0] b;
assign b = 6'ozZ;//寫兩個,也可缺省
  1. 十進制表示法
<bit_width>'d <constant in decimal>
wire [7:0] a;
assign a = 8'd255;
//高阻
wire [15:0] b;
assign b = 16'dz;//只能寫1個 
  1. 十六進制表示法
<bit_width>'d <constant in hexadecimal>
wire [5:0] a;
assign a = 6'hFA;
assign a = 6'b11_1010;

整數

integer //也可使用 wire 和 reg
wire [7:0] q;
assign q = 128;
//不同于十進制表示法,負數可以如下:
assign a = -128;
assign a = 16'd-128;// error

Verilog的操作符號

  • Verilog 賦值運算符

    • 連續賦值符號 ,應用于線網類型
    assign <variable_name> = <expression>;
    
    input a;
    wire b;
    
    assign a = b;// 1
    wire a = b;	//  2
    //1 和2等價, 1稱作顯示地連續賦值, 2稱為隱式的連續賦值, 
    
    • 阻塞賦值符號 =

      應用于組合邏輯, 只能操作線網類型的變量;

      語句執行為順序執行,下條語句必須等待上條語句完成賦值之后再執行;

    • 非阻塞復制符號 <=

      應用于時序邏輯, 只能操作寄存器類型的變量;

      執行為順序執行, 但是上條語句未完成賦值操作時就開始執行下條語句的執行, 即其值得傳遞只能跨越一個寄存器;

    • 映射賦值符號 " . "

      兩個變量之間建立一種連接的關系

    • 位置賦值

      沒有顯示操作符號, 別用;

  • Verilog 按位運算符

    ~  邏輯非, 按位取反; 單目;
    &  邏輯與, 按位取與; 雙目; 
    |  邏輯或, 按位取或; 雙目;
    ^  邏輯異或 , 按位異或; 雙目;
    ~^ 邏輯同或 , 按位同或;
    
  • Verilog 歸約運算符

    注意 : 規約運算所有結果均為 1bit

    &   : 歸約與 , 按位從低到高相與;
    ~&  : 歸約與非 , 按位從低到高相與后去反;
    |   : 歸約或 ,按位從低到高進行邏輯或;
    ~|  : 歸約或非,對歸約或的結果進行邏輯反;
    ^   : 歸約異或, 
    ~^  : 歸約異或非;
    //與按位運算符區別在于(以異或為例):
    //按位運算符:
    wire [7:0] a,b,c;
    assign a = 8'hF1;
    assign b = 8'h1F;
    assign c = a ^ b; //c = 8'bEE;
    //歸約運算符:
    wire [3:0] a
    wire b;
    assign a = 4'h7;
    assign b = ^a; // b =1'b1;
    
  • Verilog 算術運算符

    parameter a =  2 ** 3; //a = 8 ; 盡量別用
    // + - * / % 
    
  • Verliog 關系運算符

    ==  //相等
    === //全等 (包含 X, Z狀態僅用于仿真)
    !=  //不等
    !== //不全等 (包含 X, Z狀態僅用于仿真)
    <   //小于
    <=  //小于等于
    >   //大于
    >=  //大于等于
    
  • Verilog 邏輯運算符

    !  //邏輯反, 
    && //邏輯與,雙目 , 同為true返回true, 否則false
    || //邏輯或 , 同為 false 返回 false, 否則 true
    
  • Verilog 迭代連接運算符

    顯示符號為 : “{}”

    • 連接功能
    wire a = 1'b1;
    wire [2:0] b = 3'b011;
    wire [3:0] c = {a,b}; //c = 4'b1011
    
    • 迭代功能
    wire [1:0] a = 2'b10;
    wire [7:0] b = {4{a}}; // b = 8'b10101010 = {a,a,a,a}
    
    • 混合功能
    wire a = 1'b1;
    wire [2:0] b = 3'b011;
    wire [7:0] c = {{5{a}},b}; //c = 8'b11111011
    wire [7:0] d = {2{a,b}};   //c = 8'b10111011
    
  • Verilog 移位運算符

    <<  //(無符號) 左移
    <<< //帶符號左移
    >>  //(無符號) 右移
    >>> //帶符號右移
    
    //類似C語言規則, 默認的wire, reg都理解為無符號數
    //integer 為有符號數, 左移: 左拋右補0, 右移: 右拋左補符號位
    //通常利用迭代符號完成相同功能;
    //移位是乘除法的實現基礎
    
  • Verilog 條件運算符

    //顯示符號 : "? :"
    //類似C語言的使用
    
  • Verilog 操作符的優先級

    //必要時查閱優先級表格
    //但是個人習慣必須按照邏輯使用 "()"確保邏輯準確性
    

原文鏈接:https://blog.csdn.net/weixin_43909139/article/details/126693021

欄目分類
最近更新