2014年6月7日 星期六

Verilog ----基礎3

Verilog ----基礎3

  【例6.1】加法計數器中的進程 
module count(data,clk,reset,load,cout,qout); 
 output cout; 
 output [3:0] qout; 
 reg [3:0] qout; 
 input [3:0] data; 
 input clk,reset,load; 
  always @(posedge clk)                //進程 1always 過程塊 
         begin 
          if (!reset)         qout= 4'h00;     //同步清0,低電平有效 
          else if (load)   qout= data;                 //同步預置 
          else                qout=qout + 1;           //加法計數 
         end 
     assign cout=(qout==4'hf)?1:0;  //進程2,用持續賦值產生進位元信號 
     endmodule 

      
      【例6.2 】任務舉例 
    module alutask(code,a,b,c); 
   input [1:0] code; 
    input [3:0] a,b; 
    output [4:0] c; 
    reg [4:0] c; 
    task my_and;             //任務定義,注意無埠列表 
    input [3:0] a,b;         //a,b,out名稱的作用域範圍為task任務內部 
    output [4:0] out; 
    integer i; 
        begin 
        for (i=3;i>=0;i=i-1) 
        out[i]=a[i]&b[i];            //按位與 
        end 
    endtask 

     
    always@(code or a or b) 
      begin 
       case (code) 
           2'b00: my_and(a,b,c); 
/* 調用任務my_and,需注意埠列表的順序應與任務定義中的一致,這裏的a,b,c 分別對應任務定義中的a,b,out */ 
           2'b01: c=a|b;                     // 
           2'b10: c=a-b;                     //相減 
           2'b11: c=a+b;                     //相加 
       endcase 
      end 
    endmodule 
  
  【例6.3 】測試程式 
 `include "alutask.v" 
 module alu_tp; 
 reg [3:0] a,b; 
 reg [1:0] code; 
 wire [4:0] c; 
 parameter DELY = 100; 
 alutask ADD(code,a,b,c);            //調用被測試模組 
 initial begin 
          code=4'd0; a= 4'b0000; b= 4'b1111; 
 #DELY   code=4'd0; a= 4'b0111; b= 4'b1101; 
 #DELY   code=4'd1; a= 4'b0001; b= 4'b0011; 
 #DELY   code=4'd2; a= 4'b1001; b= 4'b0011; 
 #DELY   code=4'd3; a= 4'b0011; b= 4'b0001; 
 #DELY   code=4'd3; a= 4'b0111; b= 4'b1001; 
 #DELY   $finish; 
 end 
 initial $monitor($time,,,"code=%b a=%b b=%b c=%b", code,a,b,c); 
 endmodule 

  【例6.4 】函數 
 function[7:0] get0; 
 input [7:0] x; 
 reg [7:0] count; 
 integer i; 
     begin 
      count=0; 
      for (i=0;i<=7;i=i+1) 
      if  (x[i]=1'b0)  count=count+1; 
      get0=count; 
     end 
 endfunction 

  
  【例6.5 】用函數和case 語句描述的編碼器 (不含優先順序) 
 module code_83(din,dout); 
 input [7:0] din; 
 output [2:0] dout; 

 function[2:0] code;         //函數定義 
 input [7:0] din;           //函數只有輸入輸出為函數名本身 
          casex (din) 
          8'b1xxx_xxxx : code = 3'h7; 
          8'b01xx_xxxx : code = 3'h6; 
          8'b001x_xxxx : code = 3'h5; 
          8'b0001_xxxx : code = 3'h4; 
          8'b0000_1xxx : code = 3'h3; 
          8'b0000_01xx : code = 3'h2; 
          8'b0000_001x : code = 3'h1; 
          8'b0000_000x : code = 3'h0; 
          default: code = 3'hx; 
          endcase 
     endfunction 
      
     assign dout = code(din) ;                   //函數調用 
     endmodule 
      
      【例6.6 】階乘運算函數 
    module funct(clk,n,result,reset); 
    output [31:0] result; 
    input [3:0] n; 
    input reset,clk; 
    reg [31:0] result; 
    always @(posedge clk)    //clk 的上升沿時執行運算 
      begin 
        if (!reset)  result<=0;            //復位 
        else  begin 
              result <= 2 * factorial(n);  //調用factorial 函數 
              end 
      end 

    function[31:0] factorial;     //階乘運算函數定義(注意無埠列表) 
    input [3:0] opa;     //函數只能定義輸入端,輸出埠為函數名本身 
    reg [3:0] i; 
        begin 
        factorial = opa ? 1 : 0; 
        for (i= 2; i <= opa; i = i+1)   
  //該句若要綜合通過opa應賦具體的數值 
        factorial = i* factorial;                //階乘運算 
       end 
endfunction 
endmodule 

  
  【例6.7 】測試程式 
 `define clk_cycle  50 
 `include "funct.v" 
 module funct_tp; 
 reg [3:0] n; 
 reg reset,clk; 
 wire [31:0] result; 
    initial                     //定義激勵向量 
    begin 
    n=0;  reset=1;  clk=0; 
    for (n=0;n<=15;n=n+1) 
    #100  n=n; 
    end 
 initial $monitor($time,,,"n=%d result=%d",n,result); 
                          //定義輸出顯示格式 
 always  #  `clk_cycle  clk=~clk;           //產生時鐘信號 
 funct funct_try (.clk(clk),.n(n),.result(result),.reset(reset)); 
                       //調用被測試模組 
 endmodule 

  
  【例6.8】順序執行模組
 module serial1(q,a,clk); 
 output q,a; 
 input clk; 
 reg q,a; 
 always @(posedge clk) 
     begin 
      q=~q; 
      a=~q; 
     end 
 endmodule 
  
  【例6.9 】順序執行模組
 module serial2(q,a,clk); 
 output q,a; 
       input clk; 
       reg q,a; 
        always @(posedge clk) 
            begin 
             a=~q; 
             q=~q; 
            end 
        endmodule 
         

          【例6.10】並行執行模組
        module paral1(q,a,clk); 
        output q,a; 
        input clk; 
        reg q,a; 
        always @(posedge clk) 
            begin 
                q=~q; 
            end 
        always @(posedge clk) 
            begin 
                a=~q; 
            end 
        endmodule 

         
          【例6.11】並行執行模組
        module paral2(q,a,clk); 
        output q,a; 
        input clk; 
        reg q,a; 
        always @(posedge clk) 
            begin 
                a=~q; 
            end  
        always @(posedge clk) 
            begin 
                q=~q; 
            end 
        endmodule 
          

沒有留言:

張貼留言

Messaging API作為替代方案

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