2014年11月22日 星期六

Verilog ----基礎2

Verilog ----基礎2 

【例5.1】用case 語句描述的4 1 資料選擇器 
module mux4_1(out,in0,in1,in2,in3,sel); 
output out; 
input in0,in1,in2,in3; 
input [1:0] sel; 
reg out; 
always @(in0 or in1 or in2 or in3 or sel)    //敏感信號列表 
    case (sel) 
     2'b00:   out=in0; 
     2'b01:   out=in1; 
     2'b10:   out=in2; 
     2'b11:   out=in3; 
     default: out=2'bx; 
    endcase 
endmodule 

  
【例5.2 】同步置數、同步清零的計數器 
 module count(out,data,load,reset,clk); 
 output [7:0] out; 
 input [7:0] data; 
 input load,clk,reset; 
 reg [7:0] out; 
 always @(posedge clk)                  //clk上升沿觸發 
      begin 
      if (!reset)      out = 8'h00;    //同步清0,低電平有效 
      else if (load)   out = data;     //同步預置 
      else             out = out + 1;       //計數 
      end 
  endmodule 
  
【例5.3 】用always 過程語句描述的簡單算術邏輯單元 
`define add 3'd0 
`define minus 3'd1 
`define band 3'd2 
`define bor 3'd3 
`define bnot 3'd4 
  
    module alu(out,opcode,a,b); 
     output [7:0] out; 
     reg [7:0] out; 
     input [2:0] opcode;              //操作碼 
     input [7:0] a,b;               //運算元 
     always@(opcode or a or b)          //電平敏感的always  
         begin 
           case (opcode) 
            `add: out = a+b;            //加操作 
            `minus: out = a-b;          //減操作 
            `band: out = a&b;          //求與 
            `bor: out = a|b;             //求或 
            `bnot: out=~a;                //求反 
           default: out=8'hx;           //未收到指令時,輸出任意態 
           endcase 
         end 
    endmodule 

      
【例5.4 】用initial 過程語句對測試變數ABC 賦值 
     `timescale 1ns/1ns 
    module test; 
     reg A,B,C; 
     initial 
      begin 
                A = 0;  B = 1;  C = 0; 
      #50       A = 1;  B = 0; 
      #50       A = 0;   C = 1; 
      #50       B = 1; 
      #50       B = 0;   C = 0; 
      #50      $finish ; 
      end 
    endmodule 
      
      【例5.5 】用begin-end 串列塊產生信號波形 
     `timescale 10ns/1ns 
    module wave1; 
     reg wave; 
    parameter cycle=10; 
     initial 
      begin 
           wave=0; 
    #(cycle/2)  wave=1; 
    #(cycle/2)  wave=0; 
    #(cycle/2)  wave=1; 
    #(cycle/2)  wave=0; 
    #(cycle/2)  wave=1; 
    #(cycle/2)  $finish ; 
   end 
 initial $monitor($time,,,"wave=%b",wave); 
 endmodule 
  
  【例5.6 】用fork-join  並行塊產生信號波形 

 `timescale 10ns/1ns 
 module wave2; 
 reg wave; 
 parameter cycle=5; 
 initial 
   fork 
          wave=0; 
   #(cycle)    wave=1; 
   #(2*cycle)  wave=0; 
   #(3*cycle)  wave=1; 
   #(4*cycle)  wave=0; 
   #(5*cycle)  wave=1; 
   #(6*cycle)   $finish; 
   join 
 initial $monitor($time,,,"wave=%b",wave); 
 endmodule 
  
  【例5.7 】持續賦值方式定義的2 1 多路選擇器 
 module MUX21_1(out,a,b,sel); 
 input a,b,sel; 
 output out; 
 assign out=(sel==0)?a:b;  
           //持續賦值,如果sel 0,則out=a ;否則out=b 
 endmodule 

   【例5.8】阻塞賦值方式定義的2 1 多路選擇器 
 module MUX21_2(out,a,b,sel); 
 input a,b,sel; 
 output out; 
     reg out; 
     always@(a or b or sel) 
       begin 
          if (sel==0) out=a;          //阻塞賦值 
          else        out=b; 
       end 
     endmodule 

      【例5.9 】非阻塞賦值 
     module non_block(c,b,a,clk); 
     output c,b;  
     input clk,a; 
     reg c,b; 
     always @(posedge clk) 
          begin 
          b<=a; 
          c<=b; 
          end 
     endmodule 

      【例5.10】阻塞賦值 
     module block (c,b,a,clk); 
     output c,b; 
     input clk,a; 
     reg c,b; 
     always @(posedge clk) 
         begin 
          b=a; 
          c=b; 
         end 
     endmodule 
      
      【例5.11】模為60 BCD 碼加法計數器 
     module count60(qout,cout,data,load,cin,reset,clk); 
     output [7:0] qout; 
     output cout; 
     input [7:0] data; 
     input load,cin,clk,reset; 
     reg [7:0] qout; 
     always @(posedge clk)         //clk上升沿時刻計數 
                                               
  begin 
     if  (reset)       qout<=0;            //同步復位 
     else  if (load)   qout<=data;       //同步置數 
     else  if (cin) 
          begin 
           if (qout[3:0]==9)              //低位是否為 9,是則 
               begin 
               qout[3:0]<=0;              //0,並判斷高位是否為
               if (qout[7:4]==5)  qout[7:4]<=0; 
               else 
               qout[7:4]<=qout[7:4]+1;         //高位不為5,則加
               end 
               else            //低位不為 9,則加
              qout[3:0]<=qout[3:0]+1; 
          end 
  end 
assign cout=((qout==8'h59)&cin)?1:0;         //產生進位元輸出信號 
endmodule 


 【例5.12BCD 碼—七段數碼管顯示解碼器 
module decode4_7(decodeout,indec); 
output [6:0] decodeout; 
input [3:0] indec; 
reg [6:0] decodeout; 
always @(indec) 
  begin 
     case (indec)              //case語句進行解碼 
     4'd0:decodeout=7'b1111110; 
     4'd1:decodeout=7'b0110000; 
     4'd2:decodeout=7'b1101101; 
     4'd3:decodeout=7'b1111001; 
     4'd4:decodeout=7'b0110011; 
     4'd5:decodeout=7'b1011011; 
     4'd6:decodeout=7'b1011111; 
     4'd7:decodeout=7'b1110000; 
     4'd8:decodeout=7'b1111111;  
     4'd9:decodeout=7'b1111011; 
     default: decodeout=7'bx; 
     endcase 
  end 
endmodule 
        
         【例5.13】用casez 描述的資料選擇器 
       module mux_casez(out,a,b,c,d,select); 
       output out; 
       input a,b,c,d; 
       input [3:0] select; 
       reg out; 
       always @(select or a or b or c or d) 
           begin 
                      casez (select) 
                      4'b???1: out = a; 
                      4'b??1?: out = b; 
                      4'b?1??: out = c; 
                      4'b1???: out = d; 
                      endcase 
           end 
       endmodule 

        
         【例5.14】隱含鎖存器舉例 
       module buried_ff(c,b,a); 
       output c; 
       input b,a; 
       reg c; 
       always @(a or b) 
         begin 
               if ((b==1)&&(a==1))  c=a&b; 
         end 
       endmodule 
        
         【例5.15】用for 語句描述的七人投票表決器 
module voter7(pass,vote); 
       output pass; 
       input [6:0] vote; 
       reg [2:0] sum; 
       integer i; 
       reg pass; 
       always @(vote) 
         begin 
          sum=0; 
          for (i=0;i<=6;i=i+1)             //for語句 
          if (vote[i]) sum=sum+1; 
          if (sum[2])  pass=1;       //若超過4人贊成,則pass=1 
          else         pass=0; 
   end 
endmodule 

 
 【例5.16】用for 語句實現2 8 位數相乘 
module mult_for(outcome,a,b); 
parameter size=8; 
input [size:1] a,b;                           //兩個運算元 
output [2*size:1] outcome;                    //結果 
reg [2*size:1] outcome; 
integer i; 
always @(a or b) 
    begin 
     outcome=0; 
     for (i=1; i<=size; i=i+1)           //for語句 
     if (b[i])  outcome=outcome +(a <<  (i-1)); 
    end 
endmodule 

 
 【例5.17】用repeat 實現8 位二進位數字的乘法 
module mult_repeat (outcome,a,b); 
parameter size=8; 
input [size:1] a,b; 
output [2*size:1] outcome; 
reg [2*size:1] temp_a,outcome; 
reg [size:1] temp_b; 
always @(a or b) 
  begin 
          outcome=0; 
          temp_a=a; 
          temp_b=b; 
          repeat (size)     //repeat語句,size 為迴圈次數 
          begin 
           if (temp_b[1]) 
 //如果temp_b 的最低位為1,就執行下面的加法 
               outcome=outcome+temp_a; 
               temp_a=temp_a<<1;              //運算元a左移一位 
               temp_b=temp_b>>1;           //運算元b 右移一位 
          end 
       end 
      endmodule 

      
       【例5.18】同一迴圈的不同實現方式 
     module loop1;                     //方式
     integer i; 
     initial 
              for (i=0;i<4;i=i+1)             //for語句 
              begin 
              $display(“i=%h”,i); 
              end 
     endmodule 

      
     module loop2;                  //方式
     integer i; 
     initial begin 
              i=0; 
                 while (i<4)            //while語句 
                begin 
                 $display ("i=%h",i); 
                 i=i+1; 
                 end 
            end 
     endmodule 
      

     module loop3;                //方式
     integer i; 
     initial begin 
            i=0; 
            repeat (4)                  //repeat語句 
              begin 
              $display ("i=%h",i); 
              i=i+1; 
              end 
            end 
     endmodule 
      
       【例5.19】使用了`include 語句的 16 位加法器 
                                                   
 `include "adder.v" 
module adder16(cout,sum,a,b,cin); 
 output cout; 
parameter my_size=16; 
 output [my_size-1:0] sum; 
 input [my_size-1:0] a,b; 
 input cin; 
 adder my_adder(cout,sum,a,b,cin);    //調用adder模組 
 endmodule 

//下面是adder模組代碼 
module adder(cout,sum,a,b,cin); 
parameter size=16; 
 output cout; 
 output [size-1:0] sum; 
 input cin; 
 input [size-1:0] a,b; 
     assign {cout,sum}=a+b+cin; 
 endmodule 

 
  【例5.20 】條件編譯舉例 
module compile(out,A,B); 
 output out; 
 input A,B; 
 `ifdef  add                           //宏名為add 
      assign out=A+B; 
 `else 
      assign out=A-B; 
 `endif 

 endmodule  

沒有留言:

張貼留言

Messaging API作為替代方案

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