Ch5 行為層次 Behavior Level

5.1 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

5.2 if-else敘述

範例:

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

5.3 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

5.4 for敘述

  • 變數通常宣告成integer的型態

範例:

for( 變數初值; 變數條件判斷; 變數增減 )
begin
    敘述;
end

5.5 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

5.6 實際範例

一位元全加器程式碼:

module Full_Adder( A, B, Cin, Sum, Cout );

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

    wire W1, W2, W3;

    always @( A, B, Cin ) begin
        { Cout, Sum } = A + B + Cin;
    end

endmodule