2020年2月27日 星期四

Verilog 行為層次 Behavior Level 實際範例 Full Adder 全加器

Verilog 行為層次 Behavior Level 實際範例 Full Adder 全加器

源自於 https://hom-wang.gitbooks.io/verilog-hdl/content/Chapter_05.html

always敘述
驅動某值至reg( 等號的左式必為reg,右式可為net 或 reg )
行為層次的描述方式,可用於敘述組合邏輯和序向邏輯
事件與事件之間需用”or”或”逗號 , ”分開
當”事件”有變化時( 0→1、1→0 ),則會執行”敘述”
事件中可以使用正緣觸發posedge(0→1)和負緣觸發negedge(1→0)
若寫成always @(*) 或 always @* 代表always內任一變化即執行敘述
範例:

always @( 事件1, 事件2, … )
    begin
    敘述1;
    敘述2;
    … … …
end

 if-else敘述
範例:
if( 判斷條件1 )
    begin
        敘述1;
    end
else if( 判斷條件2 )
    begin
        敘述2;
    end
else
    begin
        敘述3;
    end

case、casex與casez敘述
expr可為定值或變數,可放連結運算子
不允許expr中有x或z
允許casez中的item值除了”0” “1”外,還可以使用z
允許casex中的item值除了”0” “1” “z”外,還可以使用x
範例:
case( expr )
 item 1:
  begin
   敘述1;
  end
 item 2:
  begin
   敘述2;
  end
 … … …
 default:
  敘述n;
endcase
應用:

/* 應用1 */
case( A )
    1’b0:       C = B;
    1’b1:       C = D;
    default:    C = E;
endcase

/* 應用2*/
case( A )
    2’bx1:      C = B;
    2’b1x:      C = D;
    default:    C = E;
endcase

/* 應用3*/
case( {A,B} )
    2’bx1:      C = B;
    2’b1x:      C = D;
    default:    C = E;
endcase

/* 應用4*/
case( 2’b01 )
    A:          Out = 3’b001;
    B:          Out = 3’b010;
    default:    Out = 3’b100;
endcase

 for敘述
變數通常宣告成integer的型態
範例:
for( 變數初值; 變數條件判斷; 變數增減 )
begin
    敘述;
end

Blocking/Non-Blocking敘述

Blocking ( = ),具有順序性,敘述會與先後有關係 ( 順序處理 )
Non-Blocking ( <= ),具有同時性,敘述與先後沒有關係 ( 平行處理 )
範例:
/* Blocking ( = ) */
輸出 = 輸入邏輯;

/* Non-Blocking( <= ) */
輸出 <= 輸入邏輯;
範例:

input In;
reg [3:0] A, B, C;

always @( posedge CLK ) begin

    /* Blocking */      // 有順序執行,同C概念
    A[0] = In;          // 1CLK後A[0] = In
    A[1] = A[0];        // 1CLK後A[1] = A[0] = In
    A[2] = A[1];        // 1CLK後A[2] = A[1] = A[0] = In
    A[3] = A[2];        // 1CLK後A[3] = A[2] = A[1] = A[0] = In

    /* Non-Blocking */  // 同時執行,此範例有資料平移的效果
    B[0] <= In;         // 1CLK後B[0]存進In, B[1]存進B[0](存In之前的值)
    B[1] <= B[0];       // 2CLK後B[1]存進In
    B[2] <= B[1];       // 3CLK後B[2]存進In
    B[3] <= B[2];       // 4CLK後B[3]存進In

    /* 混合 */          // 盡量不要常用
    C[0] <= In;         // 1CLK後C[0]存進In, C[1], C[2]存進C[0](存In之前的值)
    C[1] = C[0];        // 2CLK後C[1] = C[2] = C[3] = In
    C[2] = C[1];        //
    C[3] <= C[2];       //

end
實際範例 : 一位元全加器程式碼:

//=========================
module FA( A, B, Cin, Sum, Cout );

    input A, B, Cin;
    output reg Sum, Cout;

    always @( A, B, Cin ) begin
        { Cout, Sum } = A + B + Cin;
    end
endmodule
//=========================
// 時間單位 100ns, 時間精確度10 ps
`timescale 100ns/10ps
module Test_bench;
//     input A, B, Cin;
//     output Sum, Cout;
   
wire Sum, Cout;
reg  A=1'b0;
reg  B=1'b0;
reg  Cin=1'b0;


FA  DUT ( .A(A), .B(B), .Cin(Cin), .Sum(Sum), .Cout(Cout) );

// initial程序結構區塊, 產生A、B輸入信號波形
initial begin

$monitor( A, B, Cin, Sum, Cout );

 #100;    // 100ns
 A=1'b0;   B=1'b0  ; Cin=1'b1 ; // “001”

 #100;    // 200ns
 A=1'b0 ;  B=1'b1 ;  Cin=1'b0 ; // “010”

 #100;    // 300ns
 A=1'b0 ;  B=1'b1  ;   Cin=1'b1 ; // “011"

 #100;    // 400ns
 A=1'b1 ;  B=1'b0  ;   Cin=1'b0 ; // “100"

 #100;    // 500ns
 A=1'b1 ;  B=1'b0  ;   Cin=1'b1 ; // “101"

 #100;    // 600ns
 A=1'b1 ;  B=1'b1  ;   Cin=1'b0 ; // “110"

 #100;    // 700ns
 A=1'b1 ;  B=1'b1  ;   Cin=1'b1 ; // “111"


 end

initial
begin
  #800;   // 模擬終止時間  400 ns
    $stop;
end


endmodule

//=========================


沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...