1. 程式人生 > >Verilog新手上路學生實驗

Verilog新手上路學生實驗

MUX41

verilog程式碼:

// module  top, 選擇器(mux)的程式碼,
module top(
  IN0       ,   // input 1
  IN1       ,   // input 2
  IN2       ,   // input 3
  IN3       ,   // input 4
  S0        ,   // select
  S1        , 
  OUT       );  // out data

input IN0,IN1,IN2,IN3;// 選擇器的四個輸入資料訊號
input S0,S1;              
output OUT;     // 選擇器的輸出資料訊號
reg    OUT;
// 生成組合邏輯的程式碼
always @ (IN0 or IN1 or IN2 or IN3 or S0 or S1) begin
case({S1,S0})

 2'b00:OUT<=IN0;

 2'b01:OUT<=IN1;

 2'b10:OUT<=IN2;

 2'b11:OUT<=IN3;

default: OUT<=IN0;
endcase
end
endmodule
// endmodule top

RTL檢視:
在這裡插入圖片描述
Flow Summary
在這裡插入圖片描述
在這裡插入圖片描述

4x4 crossbar switch circuit

verilog程式碼:

// module  top, a 4x4 crossbar switch circuit
module top(
  IN0       ,   // input 1
  IN1       ,   // input 2
  IN2       ,   // input 3
  IN3       ,   // input 4
  SEL0      ,   // select the output0 source 
  SEL1      ,   // select the output1 source 
  SEL2      ,   // select the output2 source 
  SEL3      ,   // select the output3 source 
  OUT0      ,   // output data 0
  OUT1      ,   // output data 1
  OUT2      ,   // output data 2
  OUT3      );  // output data 3

parameter WL = 16;
input [WL-1:0] IN0,IN1,IN2,IN3;
input SEL0,SEL1,SEL2,SEL3;
output[WL-1:0] OUT0,OUT1,OUT2,OUT3;

reg   [WL-1:0] OUT0,OUT1,OUT2,OUT3;
// get the OUT0
always @ (IN0 or IN1 or IN2 or IN3 or SEL0 or SEL1) begin
  if((SEL0)&&(SEL1))
    OUT0 = IN3;
  else if((!SEL0)&&(SEL1))
    OUT0 = IN2;
  else if((SEL0)&&(!SEL1))
	 OUT0 = IN1;
  else 
	 OUT0 = IN0;
end
// get the OUT1
always @ (IN0 or IN1 or IN2 or IN3 or SEL1 or SEL2) begin
  if((SEL1)&&(SEL2))
    OUT1 = IN3;
  else if((!SEL1)&&(SEL2))
    OUT1 = IN2;
  else if((SEL1)&&(!SEL2))
	 OUT1 = IN1;
  else
	 OUT1 = IN0;
end
// get the OUT2
always @ (IN0 or IN1 or IN2 or IN3 or SEL2 or SEL3) begin
  if((SEL2)&&(SEL3))
    OUT2 = IN3;
  else if((!SEL2)&&(SEL3))
    OUT2 = IN2;
  else if((SEL2)&&(!SEL3))
	 OUT2 = IN1;
  else 
	 OUT2 = IN0;
end
// get the OUT3
always @ (IN0 or IN1 or IN2 or IN3 or SEL3 or SEL0) begin
  if((SEL3)&&(SEL0))
    OUT3 = IN3;
  else if((!SEL3)&&(SEL0))
    OUT3 = IN2;
  else if((SEL3)&&(!SEL0))
	 OUT3 = IN1;
  else 
	 OUT3 = IN0;
end
endmodule
// endmodule top

RTL 檢視:
在這裡插入圖片描述
Flow Summary
在這裡插入圖片描述
在這裡插入圖片描述

優先編碼器

// module top, 8 input priority encoder with zero input check
module top(
  IN        ,   // input  
  OUT       );  // output 
input [7:0] IN;
output[3:0] OUT;

reg   [3:0] OUT;
// get the OUT
always @ (IN) begin
   if(IN[7])       // 第一優先
     OUT = 4'b0111;
   else if(IN[6])  // 第二優先
     OUT = 4'b0110;
   else if(IN[5])  // 第三優先
     OUT = 4'b0101;
   else if(IN[4])  // 第四優先
     OUT = 4'b0100;
	     else if(IN[3])  // 第五優先
     OUT = 4'b0011;
	     else if(IN[2])  // 第六優先
     OUT = 4'b0010;
	     else if(IN[1])  // 第七優先
     OUT = 4'b0001;
	     else if(IN[0])  // 第八優先
     OUT = 4'b0000;
   else            // 什麼都沒有檢測到
     OUT = 4'b1111; // 輸出值可自定義,不和上面的輸出值混淆即可
end
endmodule

RTL檢視:
在這裡插入圖片描述

4_16譯碼器

verilog 程式碼

module top(
  IN        ,   // input  
  OUT       );  // output 

input [3:0] IN;
output[15:0] OUT;

reg   [15:0] OUT;
// get the OUT
always @ (IN) begin
  case(IN)
    4'b0000: OUT = 16'b0000000000000001;
    4'b0001: OUT = 16'b0000000000000010;
    4'b0010: OUT = 16'b0000000000000100;
    4'b0011: OUT = 16'b0000000000001000;
    4'b0100: OUT = 16'b0000000000010000;
    4'b0101: OUT = 16'b0000000000100000;
    4'b0110: OUT = 16'b0000000001000000;
    4'b0111: OUT = 16'b0000000010000000;
	 4'b1000: OUT = 16'b0000000100000000;
    4'b1001: OUT = 16'b0000001000000000;
    4'b1010: OUT = 16'b0000010000000000;
    4'b1011: OUT = 16'b0000100000000000;
    4'b1100: OUT = 16'b0001000000000000;
    4'b1101: OUT = 16'b0010000000000000;
    4'b1110: OUT = 16'b0100000000000000;
    4'b1111: OUT = 16'b1000000000000000;
    //  full case 不需要寫default,否則一定要有default
  endcase
end
endmodule

RTL檢視:
在這裡插入圖片描述
Flow Summary
在這裡插入圖片描述
在這裡插入圖片描述

無符號加法器

4輸入4輸出無符號加法器
在這裡插入圖片描述
在這裡插入圖片描述
可見輸出等於輸入相加。

8輸入5輸出無符號加法器
在這裡插入圖片描述
在這裡插入圖片描述
可見其輸出時延稍大於4輸入的無符號加法器。

補碼加法器

4輸入4輸出補碼加法器

module top(
  IN1   ,
  IN2   ,
  OUT   );
input signed [3:0] IN1, IN2;
output signed [3:0] OUT;
reg signed [3:0] OUT;
[email protected](IN1 or IN2) begin // 生成組合邏輯的always 塊
  OUT = IN1 + IN2;
end
endmodule 

在這裡插入圖片描述
8輸入5輸出補碼加法器

module top(
  IN1   ,
  IN2   ,
  OUT   );
input signed [7:0] IN1, IN2;
output signed [7:0] OUT;
reg signed [4:0] OUT;
[email protected](IN1 or IN2) begin // 生成組合邏輯的always 塊
  OUT = IN1 + IN2;
end
endmodule 

在這裡插入圖片描述

帶流水線的加法器

8輸入5輸出帶流水線加法器

module top(
  IN1   ,
  IN2   ,
  CLK   ,
  OUT   );
input  [7:0] IN1, IN2;
input CLK;
output  [4:0] OUT;
reg [7:0] in1_d1R, in2_d1R;
reg  [4:0] adder_out, OUT;
[email protected](posedge CLK) begin // 生成D觸發器的always塊
  in1_d1R <= IN1;
  in2_d1R <= IN2;
  OUT     <= adder_out;
end
[email protected](in1_d1R or in2_d1R) begin // 生成組合邏輯的always 塊
  adder_out = in1_d1R + in2_d1R;
end
endmodule 

在這裡插入圖片描述
在這裡插入圖片描述
二級流水線加法器

module top(
  IN1   ,
  IN2   ,
  CLK   ,
  OUT   );
input  [7:0] IN1, IN2;
input CLK;
output  [4:0] OUT;
reg [7:0] in1_d1R, in2_d1R,in1_d2R, in2_d2R;
reg  [4:0] adder_out, OUT;
[email protected](posedge CLK) begin // 生成D觸發器的always塊
  in1_d1R <= IN1;
  in2_d1R <= IN2;
  in1_d2R <= in1_d1R;
  in2_d2R <= in2_d1R;
  OUT     <= adder_out;
end
[email protected](in1_d1R or in2_d1R) begin // 生成組合邏輯的always 塊
  adder_out = in1_d2R + in2_d2R;
end
endmodule 

在這裡插入圖片描述
在這裡插入圖片描述

乘法器

8輸入8輸出乘法器

////////////////////  有符號的補碼乘法器  /////////////////////////
module top(
  IN1   ,
  IN2   ,
  OUT   );
 input signed[7:0] IN1, IN2;
 output signed [7:0] OUT;
 reg signed[7:0] OUT;
 [email protected](IN1 or IN2) begin // 生成組合邏輯的always 塊
  OUT = IN1 * IN2;
end
endmodule 

在這裡插入圖片描述

流水線乘法器

////////////////////  流水線乘法器  /////////////////////////
module top(
  IN1   ,
  IN2   ,
  CLK   ,
  OUT   );
 input signed[3:0] IN1, IN2;
 input  CLK;
 output signed [7:0] OUT;
 
 reg signed[7:0] mul_out,OUT;
 reg signed[3:0] in1_dlr,in2_dlr;
 
 [email protected](posedge CLK) begin 
  in1_dlr <= IN1;
  in2_dlr <= IN2;
  OUT <= mul_out;
 end

 [email protected](in1_dlr or in2_dlr) begin 
   mul_out = in1_dlr * in2_dlr;
 end
endmodule

在這裡插入圖片描述

計數器

簡單計數器

//////////////////// 計數器程式碼  /////////////////////////

module top(
  CLK   , // 時鐘,上升沿有效
  OV    );// 計數溢位訊號,計數值為最大值時該訊號為1

input  CLK  ;
output OV;   

reg [3:0] cnt_next;
reg OV;
// 電路編譯引數,最大計數值
// 組合邏輯,生成cnt_next
parameter CNT_MAX_VAL =7;

always @ (posedge CLK ) begin
  if(cnt_next<CNT_MAX_VAL) begin
    OV <= 0;
    cnt_next <= cnt_next+1;
   end
   else begin
    OV <= 1;
    cnt_next <= 0;
   end
end
endmodule

在這裡插入圖片描述
在這裡插入圖片描述
複雜計數器

//////////////////// 計數器程式碼  /////////////////////////

module top(
  RST   , // 非同步復位, 高有效
  CLK   , // 時鐘,上升沿有效
  EN    , // 輸入的計數使能,高有效
  CLR   , // 輸入的清零訊號,高有效
  LOAD  , // 輸入的資料載入使能訊號,高有效
  DATA  , // 輸入的載入資料訊號
  CNTVAL, // 輸出的計數值訊號
  OV    );// 計數溢位訊號,計數值為最大值時該訊號為1

input RST   , CLK   , EN    , CLR   , LOAD  ;
input [3:0] DATA ;
output [3:0] CNTVAL;
output OV;   

reg [3:0] CNTVAL, cnt_next;
reg OV;
// 電路編譯引數,最大計數值
parameter CNT_MAX_VAL = 9;

// 組合邏輯,生成cnt_next
// 計數使能最優先,清零第二優先,載入第三優先
always @(EN or CLR or LOAD or DATA or CNTVAL) begin
    if(CLR) begin   // 清零有效
       cnt_next = 0;
    end
    else begin
        if(EN) begin // 使能有效
           if(LOAD) begin // 載入有效
               cnt_next = DATA;
           end
           else begin  // 載入無效,正常計數   
               if(CNTVAL < CNT_MAX_VAL) begin // 未計數到最大值, 下一值加1
                  cnt_next = CNTVAL + 1'b1;
               end
               else begin // 計數到最大值,下一計數值為0
                    cnt_next = 0;
               end
            end // else LOAD
        end  // else EN
        else begin  // 清零無效,計數值保持不動
             cnt_next = CNTVAL;
        end // else EN
	 end
end
// 時序邏輯 更新下一時鐘週期的計數值
// CNTVAL 會被編譯為D觸發器
always @ (posedge CLK or posedge RST) begin
  if(RST) 
    CNTVAL <= 0;
  else
    CNTVAL <= cnt_next;
end

// 組合邏輯,生成OV
always @ (CNTVAL) begin
  if(CNTVAL == CNT_MAX_VAL) 
    OV = 1;
  else
    OV = 0;
end

endmodule

在這裡插入圖片描述
在這裡插入圖片描述

狀態機

基本要求的識別序列1011的狀態機

module top(
  CLK       ,   // clock
  RST       ,   // reset
  //EN        ,
  IN        ,   
  OUT    );  

input  CLK , RST ;// EN   ; 
input  IN   ; 
output OUT    ;

parameter ST_State0 = 0;
parameter ST_State1 = 1;
parameter ST_State2 = 2;
parameter ST_State3 = 3;
parameter ST_State4 = 4;

reg [4:0]stateR       ;
reg [4:0]next_state   ;
reg         OUT       ;

always @ (IN or stateR ) begin//or EN
     // if(EN)begin
        case (stateR) 
        ST_State0 :begin if(IN) next_state =ST_State1 ; else next_state = ST_State0; end
        ST_State1 :begin if(IN) next_state =ST_State1 ; else next_state = ST_State2; end
        ST_State2 :begin if(IN) next_state =ST_State3 ; else next_state = ST_State0; end
	     ST_State3 :begin if(IN) next_state =ST_State4 ; else next_state = ST_State2; end
        ST_State4 :begin next_state = ST_State0;end
		  endcase
      //end
      //else
		  //  if(next_state!=ST_State0)
			  //  next_state=stateR;
end

always @ (stateR) begin
  if(stateR == ST_State4) 
    OUT = 1;
  else 
    OUT = 0;
end


always @ (posedge CLK or posedge RST)begin
  if(RST)
    stateR <= ST_State0;
  else
    stateR <= next_state;
end

endmodule

在這裡插入圖片描述
在這裡插入圖片描述
帶使能端的識別序列1011的狀態機

module top(
  CLK       ,   // clock
  RST       ,   // reset
  EN        ,
  IN        ,   
  OUT    );  

input  CLK , RST ,EN   ; 
input  IN   ; 
output OUT    ;

parameter ST_State0 = 0;
parameter ST_State1 = 1;
parameter ST_State2 = 2;
parameter ST_State3 = 3;
parameter ST_State4 = 4;

reg [4:0]stateR       ;
reg [4:0]next_state   ;
reg         OUT       ;

always @ (IN or stateR or EN ) begin
     if(EN)begin
        case (stateR) 
        ST_State0 :begin if(IN) next_state =ST_State1 ; else next_state = ST_State0; end
        ST_State1 :begin if(IN) next_state =ST_State1 ; else next_state = ST_State2; end
        ST_State2 :begin if(IN) next_state =ST_State3 ; else next_state = ST_State0; end
	     ST_State3 :begin if(IN) next_state =ST_State4 ; else next_state = ST_State2; end
        ST_State4 :begin next_state = ST_State0;end
	    endcase
      end
      else
		    if(next_state!=ST_State0)
			    next_state=stateR;
end

always @ (stateR) begin
  if(stateR == ST_State4) 
    OUT = 1;
  else 
    OUT = 0;
end


always @ (posedge CLK or posedge RST)begin
  if(RST)
    stateR <= ST_State0;
  else
    stateR <= next_state;
end

endmodule

在這裡插入圖片描述

移位暫存器

//////////////////// 併入串出移位暫存器  /////////////////////////
module top(
  RST   ,   // 非同步復位, 高有效
  CLK   ,   // 時鐘,上升沿有效
  EN    ,   // 輸入資料序列移位使能
  IN    ,   // 輸入序列資料
  LOAD  ,
  OUT   );  // 並行輸出資料

input RST, CLK, EN,LOAD ;
input [3:0] IN;
output OUT;
reg [3:0] shift_R;
reg  OUT;

always @ (posedge CLK or posedge RST or posedge LOAD) begin
    if(RST) 
       shift_R[3:0] <= 0;
    else begin
         if(LOAD) begin
	         shift_R[3:0]<=IN[3:0];
	      end
         else begin 
	           if(EN) begin 
	              OUT=shift_R[3];
                 shift_R[3:1] <= shift_R[2:0];
                 shift_R[0]   <= IN;
              end
              else begin 
                   shift_R[3:0] <= shift_R[3:0];
              end
			end
	 end		
end // always
endmodule

在這裡插入圖片描述
在這裡插入圖片描述