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;
always@(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;
always@(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;
always@(posedge CLK) begin // 生成D触发器的always块
  in1_d1R <= IN1;
  in2_d1R <= IN2;
  OUT     <= adder_out;
end
always@(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;
always@(posedge CLK) begin // 生成D触发器的always块
  in1_d1R <= IN1;
  in2_d1R <= IN2;
  in1_d2R <= in1_d1R;
  in2_d2R <= in2_d1R;
  OUT     <= adder_out;
end
always@(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;
 always@(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;
 
 always@(posedge CLK) begin 
  in1_dlr <= IN1;
  in2_dlr <= IN2;
  OUT <= mul_out;
 end

 always@(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

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/xxxisail/article/details/83475750