两种verilog实现4位乘法器

repeat版本

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// school:neusoft 
// Engineer: yzh
// Create Date: 2019/10/12 16:11:54

//////////////////////////////////////////////////////////////////////////////////


module mult(
    input clk,
    input [3:0] A,
    input [3:0] B,
    input start, 
    input reset_n,
    output reg [7:0] product,
    output   ready,
   output reg [6:0] seg,
    output reg [7:0] AN
    );
  reg [16:0] cnt400;  // 用于产生400Hz时钟的计数器
  reg [1:0] cnt_seg;  // 用于控制4个数码管开关
  reg [3:0] seg_data;  // 数码管显示的数字
  reg clk400;  // 400Hz时钟
  reg [3:0] A_reg;
  reg [7:0] B_reg;
  reg [2:0] cnt;

 
  always@(posedge clk,posedge start)//P17是按钮开关
  begin
         if(start==1'b1)begin
     //      ready = 0 ;
                A_reg <= A;
                B_reg <= B;
                product = 0;
      
                repeat(4) begin
           
                    if(A_reg[0]) begin 
                              product = product +  B_reg;
                    end
           
                    A_reg = A_reg>>1;
                    B_reg = B_reg<<1;      
               end 
      
     //  ready = 1;
      
        end
       
      // else if(ready==1)
      // led=ready;
  end
 
 always @(posedge clk) begin
   if (reset_n == 1'b0) begin
           cnt400 <= 0; clk400 <= 1'b0;
   end
   else begin
            if (cnt400 >= 124999) begin
               cnt400 <= 17'd0; clk400 = ~clk400;
            end
            else begin
             cnt400 <= cnt400 + 1;
            end
   end
 end
 
 always @(posedge clk400  )
  begin
  
    if (reset_n == 1'b0) begin
             cnt_seg <= 2'b00;
    end
    else begin
             cnt_seg <= cnt_seg + 1;  
    end
end
  
  always @(cnt_seg)
begin
  
  case (seg_data )
 4'd0 : seg <= 7'b0000001;   //0
            4'd1 : seg <= 7'b1001111;   //1
            4'd2 : seg <= 7'b0010010;   //2
            4'd3 : seg <= 7'b0000110;   //3
            4'd4 : seg <= 7'b1001100;   //4
            4'd5 : seg <= 7'b0100100;   //5
            4'd6 : seg <= 7'b0100000;   //6
            4'd7 : seg <= 7'b0001111;   //7
            4'd8 : seg <= 7'b0000000;   //8
            4'd9 : seg <= 7'b0000100;   //9
            4'd10: seg <= 7'b0001000;   //a
            4'd11: seg <= 7'b1100000;   //b
            4'd12: seg <= 7'b0110001;   //c
            4'd13: seg <= 7'b1000010;   //d
            4'd14: seg <= 7'b0110000;   //e
            4'd15: seg <= 7'b0111000;   //f
            default : seg <= 7'b1111110;   //-
      
        endcase
 
 case (cnt_seg)
  2'b00: begin AN<= 8'b11111110;seg_data<= product[3:0] ; end
  2'b01: begin AN<= 8'b11111101;seg_data<= product[7:4]; end
  2'b10: begin AN <= 8'b11111011;seg_data<=A ; end
  2'b11: begin  AN <= 8'b11110111; seg_data<=B; end
   default:AN <= 8'b11110000;
   endcase
   
  if(reset_n == 1'b0) 
  begin
       AN <= 8'b11110000;
       seg_data<=0;
  end
end

endmodule

没有repeat的正经版本:

//////////////////////////////////////////////////////////////////////////////////
// Company: neusoft
// Engineer: yzh
/////////////////////////////////////////////////////////////////////////////////
module mult(
    input clk,
    input [3:0] A,
    input [3:0] B,
    input start, 
    input reset_n,
    output reg [7:0] product,
    output  ready,
   output reg [6:0] seg,
    output reg [7:0] AN
    );
  reg [16:0] cnt400;  // 用于产生400Hz时钟的计数器
  reg [1:0] cnt_seg;  // 用于控制4个数码管开关
  reg [3:0] seg_data;  // 数码管显示的数字
  reg clk400;  // 400Hz时钟
  reg [3:0] A_reg;
  reg [7:0] B_reg;
  reg [2:0] cnt;
  reg flag;
initial begin

  product = 0;
  cnt=0;
end

 assign ready=(cnt==0)?1:0;
 
  always@(posedge clk,posedge start)//P17是按钮开关
  begin
         if(start==1'b1)begin
               cnt=1;
               A_reg = A;
               B_reg = B;
                product=0; 
         end
         else begin
              if(ready==0)begin
           
                     if(A_reg[0]) begin 
                              product = product +  B_reg;
                             
                    end
                  
                    A_reg = A_reg>>1;
                    B_reg = B_reg<<1; 
                     cnt=cnt+1; 
                    if(cnt==5)
                 
                    cnt=0; 
    
               end 
              
            end
        
       
 
  end
 
always @(posedge clk) begin
   if (reset_n == 1'b0) begin
           cnt400 <= 0; clk400 <= 1'b0;
   end
   else begin
            if (cnt400 >= 124999) begin
               cnt400 <= 17'd0; clk400 = ~clk400;
            end
            else begin
             cnt400 <= cnt400 + 1;
            end
   end
 end
 
 always @(posedge clk400  )
  begin
  
    if (reset_n == 1'b0) begin
             cnt_seg <= 2'b00;
    end
    else begin
             cnt_seg <= cnt_seg + 1;  
    end
end
  
  always @(cnt_seg)
begin
  
  case (seg_data )
 4'd0 : seg <= 7'b0000001;   //0
            4'd1 : seg <= 7'b1001111;   //1
            4'd2 : seg <= 7'b0010010;   //2
            4'd3 : seg <= 7'b0000110;   //3
            4'd4 : seg <= 7'b1001100;   //4
            4'd5 : seg <= 7'b0100100;   //5
            4'd6 : seg <= 7'b0100000;   //6
            4'd7 : seg <= 7'b0001111;   //7
            4'd8 : seg <= 7'b0000000;   //8
            4'd9 : seg <= 7'b0000100;   //9
            4'd10: seg <= 7'b0001000;   //a
            4'd11: seg <= 7'b1100000;   //b
            4'd12: seg <= 7'b0110001;   //c
            4'd13: seg <= 7'b1000010;   //d
            4'd14: seg <= 7'b0110000;   //e
            4'd15: seg <= 7'b0111000;   //f
            default : seg <= 7'b1111110;   //-
      
        endcase
 
 case (cnt_seg)
  2'b00: begin AN<= 8'b11111110;seg_data<= product[3:0] ; end
  2'b01: begin AN<= 8'b11111101;seg_data<= product[7:4]; end
  2'b10: begin AN <= 8'b11111011;seg_data<=A ; end
  2'b11: begin  AN <= 8'b11110111; seg_data<=B; end
   default:AN <= 8'b11110000;
   endcase
   
  if(reset_n == 1'b0) 
  begin
       AN <= 8'b11110000;
       seg_data<=0;
  end
end

  
endmodule

你可能感兴趣的:(嵌入式系统)