2014年6月7日 星期六

Verilog ----基礎5

Verilog ----基礎5

       
       【例8.1$time $realtime  的區別 
      `timescale 10ns/1ns 
     module time_dif; 
     reg ts; 
     parameter delay=2.6; 
     initial 
         begin 
          #delay  ts=1; 
          #delay  ts=0; 
          #delay  ts=1; 
           #delay  ts=0; 
         end 
    initial  $monitor($time,,,"ts=%b",ts);   //使用函數$time 
endmodule 

  
  【例8.2$random 函數的使用 
 `timescale 10ns/1ns 
 module random_tp; 
 integer data; 
 integer i; 
 parameter delay=10; 
 initial $monitor($time,,,"data=%b",data); 
 initial begin 
      for (i=0; i<=100; i=i+1) 
     #delay  data=$random;         //每次產生一個亂數 
     end 
 endmodule 

  
  【例8.3 1 位全加器進位輸出UDP 元件 
primitive carry_udp(cout,cin,a,b); 
input cin,a,b; 
output cout; 
  table 
     //cin  a  b  :  cout                  //真值表 
       0   0   0  :    0; 
       0   1   0  :    0; 
       0   0   1  :    0; 
       0   1   1  :    1; 
       1   0   0  :    0; 
       1   0   1  :    1; 
       1   1   0  :    1; 
       1   1   1  :    1; 
 endtable 
 endprimitive 

  
  【例8.4 】包含x 態輸入的 1 位全加器進位輸出UDP 元件 
primitive carry_udpx1(cout,cin,a,b); 
input cin,a,b; 
output cout; 
      table 
            // cin  a  b  :  cout     //真值表 
                    0   0   0  :    0; 
                    0   0   1  :    0; 
                    0   1   0  :    0; 
                    0   1   1  :    1; 
                    1   0   0  :    0; 
                    1   0   1  :    1; 
                    1   1   0  :    1; 
                    1   1   1  :    1; 
                    0   0   x  :    0;  
  //只要有兩個輸入為0,則進位輸出肯定為
                    0   x   0  :    0; 
                    x   0   0  :    0; 
                    1   1   x  :    1;      
  //只要有兩個輸入為1,則進位輸出肯定為
                    1   x   1  :    1; 
                    x   1   1  :    1; 
          endtable 
     endprimitive 
      
      【例8.5 】用簡縮符“?”表述的1 位全加器進位輸出UDP 元件 
    primitive carry_udpx2(cout,cin,a,b); 
    input cin,a,b; 
    output cout; 
       table 
         // cin  a  b  :  cout                 //真值表 
           ?   0   0  :    0;            
 //只要有兩個輸入為0,則進位輸出肯定為
           0   ?   0  :    0; 
           0   0   ?  :    0; 
           ?   1   1  :    1;                
 //只要有兩個輸入為1,則進位輸出肯定為
           1   ?   1  :    1; 
           1   1   ?  :    1; 
       endtable 
     endprimitive 
      
      【例8.6 3 1 多路選擇器UDP 元件 
     primitive mux31(Y,in0,in1,in2,s2,s1); 
     input in0,in1,in2,s2,s1; 
     output Y; 
         table 
         //in0 in1 in2 s2 s1 : Y 
           0   ?   ?    0   0  :  0;      //s2s1=00 時,Y=in0 
           1   ?   ?    0   0  :  1; 
           ?   0   ?    0   1  :  0;      //s2s1=01 時,Y=in1 
           ?   1   ?    0   1  :  1; 
           ?   ?   0    1   ?  :  0;      //s2s1=1?時,Y=in2 
           ?   ?   1    1   ?  :  1; 
0   0   ?    0   ?  :  0; 
           1   1   ?    0   ?  :  1; 
      0   ?   0    ?   0  :  0; 
      1   ?   1    ?   0  :  1; 
           ?   0   0    ?   1  :  0; 
      ?   1   1    ?   1  :  1; 
      endtable 
endprimitive 

 【例8.7 】電平敏感的1 位元資料鎖存器UDP 元件 
primitive latch(Q,clk,reset,D); 
input clk,reset,D; 
output Q; 
reg Q; 
initial Q = 1'b1;    //初始化 
     table 
      // clk reset D : state  : Q 
           ?   1   ?  : ?  : 0 ;
 //reset=1,則不管其他埠為什麼值,輸出都為
           0   0   0  : ?  : 0 ;
 //clk=0,鎖存器把D 端的輸入值輸出 
           0   0   1  : ?  : 1 ; 
           1   0   ?  : ? : - ;  
//clk=1,鎖存器的輸出保持原值,用符號“-”表示 
     endtable 
endprimitive 

 
 【例8.8】上升沿觸發的D 觸發器UDP 元件 
primitive DFF (Q,D,clk); 
output Q; 
input D,clk; 
reg Q; 
    table 
    //clk  D  : state : Q 
      (01)  0   : ? :   0;      //上升沿到來,輸出Q=D 
      (01)  1   : ? :   1; 
      (0x)  1   : 1 :   1; 
      (0x)  0   : 0 :   0; 
      (?0)  ?   : ? :   -;      //沒有上升沿到來,輸出Q 保持原值 
      ?   (??)  : ? :   - ;     //時鐘不變,輸出也不變 
       endtable 
    endprimitive 

      
【例8.9 】帶非同步置1 和非同步清零的上升沿觸發的D 觸發器UDP 元件 
    primitive DFF_UDP (Q,D,clk,clr,set); 
    output Q; 
    input D,clk,clr,set; 
    reg Q; 
          table 
          // clk  D      clr  set  : state : Q 
             (01)  1     0     0    : ? :     0; 
             (01)  1     0   x      : ? :     0; 
             ?      ?    0   x      : 0 :     0; 
             (01)  0     0     0    : ? :     1; 
             (01)  0     x     0    : ? :     1; 
             ?      ?    x     0    : 1 :     1; 
             (x1)  1     0     0    : 0 :     0; 
             (x1)  0     0     0    : 1 :     1; 
             (0x)  1     0     0    : 0 :     0; 
             (0x)  0     0     0    : 1 :     1; 
             ?      ?   1   ?   : ? :         1;   //非同步重定 
             ?      ?   0   1   : ? :         0;   //非同步置1 
             n      ?   0   0       : ? :     -; 
             ?      *    ?   ?   : ? :        -; 
             ?      ?    (?0) ?   : ? :       -; 
             ?      ?   ?    (?0): ? :        -; 
             ?      ?   ?      ?    : ? :    x; 
         endtable 
    endprimitive 
      
      【例8.12】延遲定義塊舉例 
     module delay(out,a,b,c); 
     output out; 
     input a,b,c; 
     and a1(n1,a,b); 
     or o1(out,c,n1); 
          specify 
           (a=>out)=2; 
           (b=>out)=3; 
           (c=>out)=1; 
      endspecify 
 endmodule 

  
  【例8.13】激勵波形的描述 
 'timescale 1ns/1ns 
module test1; 
reg A,B,C; 
initial 
      begin            //激勵波形描述 
           A = 0; B = 1; C = 0; 
     #100 C = 1; 
      #100 A = 1; B = 0; 
      #100 A = 0; 
      #100 C = 0; 
      #100 $finish; 
    end 

initial $monitor($time,,,"A=%d B=%d C=%d",A,B,C);    //顯示 
endmodule 

  
  【例8.15】用always 過程塊產生兩個時鐘信號 
module test2; 
reg clk1,clk2; 
parameter CYCLE = 100; 
always 
   begin 
                 {clk1,clk2} = 2'b10; 
      #(CYCLE/4)  {clk1,clk2} = 2'b01; 
      #(CYCLE/4)  {clk1,clk2} = 2'b11; 
      #(CYCLE/4)  {clk1,clk2} = 2'b00; 
      #(CYCLE/4)  {clk1,clk2} = 2'b10; 
    end 
initial $monitor($time,,,"clk1=%b clk2=%b",clk1,clk2); 
endmodule 

  
  【例8.17】記憶體在仿真程式中的應用 
module ROM(addr,data,oe); 
output [7:0] data;                        //資料信號 
input [14:0] addr;                        //位址信號 
input oe;                                 //讀使能信號,低電平有效 
    reg [7:0] mem[0:255];                      //記憶體定義 
    parameter DELAY = 100; 
    assign #DELAY data=(oe==0) ? mem[addr] : 8'hzz; 
    initial $readmemh ("rom.hex",mem);         //從檔中讀入資料 
    endmodule 

      
      【例8.188 位元乘法器的仿真程式 
     `timescale 10ns/1ns 
    module mult_tp;                 //測試模組的名字 
    reg [7:0] a,b;                   //測試輸入信號定義為reg  
    wire [15:0] out;                //測試輸出信號定義為wire  
    integer i,j; 
    mult8 m1(out,a,b);                         //調用測試物件 
                                   //激勵波形設定 
    initial 
          begin 
           a=0;b=0; 
           for (i=1;i<255;i=i+1) 
           #10 a=i; 
          end 
    initial 
          begin 
           for (j=1;j<255;j=j+1) 
           #10 b=j; 
          end 
    initial                   //定義結果顯示格式 
          begin 
           $monitor($time,,,"%d * %d= %d",a,b,out); 
           #2560  $finish; 
          end 
    endmodule 

 module mult8(out, a, b);        //8位乘法器源代碼 
    parameter size=8; 
    input [size:1] a,b;             //兩個運算元 
    output [2*size:1] out;          //結果 
    assign out=a*b;                 //乘法運算符 
endmodule 

  
  【例8.198 位元加法器的仿真程式 
`timescale 1ns/1ns 
module add8_tp;             //仿真模組無埠列表 
reg [7:0] A,B;              //輸入激勵信號定義為reg  
reg cin; 
wire [7:0] SUM;           //輸出信號定義為wire  
wire cout; 
parameter DELY = 100; 
 add8  AD1(SUM,cout,A,B,cin);                //調用測試物件 
initial begin                               //激勵波形設定 
          A= 8'd0;       B= 8'd0;      cin=1'b0; 
#DELY    A= 8'd100;  B= 8'd200;  cin=1'b1; 
#DELY    A= 8'd200;  B= 8'd88; 
#DELY    A= 8'd210;  B= 8'd18;         cin=1'b0; 
#DELY    A= 8'd12;   B= 8'd12; 
#DELY    A= 8'd100;  B= 8'd154; 
#DELY    A= 8'd255;  B= 8'd255;  cin=1'b1; 
#DELY    $finish; 
end 

//輸出格式定義 
initial $monitor($time,,,"%d + %d + %b = {%b, %d}",A,B,cin,cout,SUM); 
endmodule 


module add8(SUM,cout,A,B,cin);     //待測試的8位元加法器模組 
output [7:0] SUM; 
output cout; 
input [7:0] A,B; 
input cin; 
assign {cout,SUM}=A+B+cin; 
endmodule 

  
  【例8.20 2 1 多路選擇器的仿真 
`timescale 1ns/1ns 
module mux_tp; 
reg a,b,sel; 
wire out; 
     MUX2_1 m1(out,a,b,sel);                      //調用待測試模組 
    initial 
    begin 
       a=1'b0; b=1'b0; sel=1'b0; 
    #5   sel=1'b1; 
    #5   a=1'b1;  sel=1'b0; 
    #5   sel=1'b1; 
    #5   a=1'b0; b=1'b1;  sel=1'b0; 
    #5   sel=1'b1; 
    #5   a=1'b1; b=1'b1; sel=1'b0; 
    #5   sel=1'b1; 
    end 
    initial $monitor($time,,,"a=%b b=%b sel=%b out=%b",a,b,sel,out); 
    endmodule 


    module MUX2_1(out,a,b,sel);    //待測試的21MUX模組 
    input a,b,sel; 
    output out; 
    not #(0.4,0.3) (sel_,sel);                   //#(0.4,0.3)為門延時 
    and #(0.7,0.6) (a1,a,sel_); 
    and #(0.7,0.6) (a2,b,sel); 
    or #(0.7,0.6) (out,a1,a2); 
    endmodule 

      
  【例8.21 8 位計數器的仿真 
    `timescale 10ns/1ns 
    module count8_tp; 
    reg clk,reset;            //輸入激勵信號定義為reg  
    wire [7:0] qout;           //輸出信號定義為wire  
    parameter DELY=100; 
    counter  C1 (qout,reset,clk);                //調用測試物件 
    always #(DELY/2) clk = ~clk;                 //產生時鐘波形 
    initial 
    begin                        //激勵波形定義 
               clk =0; reset=0; 
#DELY    reset=1; 
#DELY    reset=0; 
#(DELY*300)  $finish; 
end 
              //結果顯示 
initial $monitor($time,,,"clk=%d reset=%d qout=%d",clk,reset,qout); 
endmodule 
 

module counter(qout,reset,clk);     //待測試的 8位元計數器模組 
output [7:0] qout; 
input clk,reset; 
reg [7:0] qout; 
always @(posedge clk) 
    begin      if (reset)  qout<=0; 
               else           qout<=qout+1; 
    end 

endmodule  

沒有留言:

張貼留言

Messaging API作為替代方案

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