32位乘法器verilog代码-FPGA常见问题论坛-FPGA CPLD-ChipDebug

32位乘法器verilog代码

 

1、32bit乘法器乘法器:乘法用运算符表示:左移一表示*2,左移两位表示*4,左移3位表示*8

2、设计原理:如:1111*1011 = (1111*0001) + (1111*0010 ) + (1111* 0000) + (1111*1000);解释:1111分别乘以1011的每一个数相加。

那么就可以判断每一位1011是否是1,是一那么就让1111位移对应位表示相乘;如:1111*0010表示左移两位;(走后全部加起来)。

代码设计:又可以在每一个周期左移一位1111,再判断1011每一位(每个周期也是左移判断一位)是否为1,如果是1,那么表示这一位可以相加。

3、参考代码

module mul(
    input  					clk		, //system clock 50MHz
    input  			 		rst_n	, //reset, low valid
    
    input			[31:0]  mul_a	, //
    input			[31:0]	mul_b	, //
    input                   mul_vld ,
 
    output					res_vld	, //
    output			[63:00]	res_mul	  //
);
 
reg     [64:0]  tmp_b;//最后输出结果
reg             data_vld;
reg     [64:0]  tmp_a;//{32'b0,a}
reg             mul_flag;
reg		[4:00]	cnt		; //Counter   32次
wire			add_cnt ; //Counter Enable
wire			end_cnt ; //Counter Reset 
//mul_vld_r
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        mul_flag <= 1'b0;
    end  
    else if(mul_vld)begin
        mul_flag <= 1'b1;
    end
    else if(end_cnt)begin
        mul_flag <= 1'b0;
    end
end //always end
 
//cnt  
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin  
        cnt <= 'd0; 
    end  
    else if(add_cnt)begin  
        if(end_cnt)begin  
            cnt <= 'd0; 
        end  
        else begin  
            cnt <= cnt + 1'b1; 
        end  
    end  
    else begin  
        cnt <= cnt;  
    end  
end 
assign add_cnt = mul_flag; 
assign end_cnt = add_cnt && cnt >= (32 - 1);
//tmp_a tmp_b
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        tmp_a <= 64'b0;
        tmp_b <= 64'b0;
    end
    else if(mul_vld)begin//初值
        tmp_a <= {32'b0,mul_a};
        tmp_b <= 64'b0;
    end
    else if(mul_flag)begin
        if(mul_b[cnt] == 1)begin
            tmp_b <= tmp_a + tmp_b;
        end
        tmp_a <= {tmp_a[62:0] ,1'b0};
    end
end //always end
 
//data_vld
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        data_vld <= 1'b0;
    end   
    else begin
        data_vld <= end_cnt;
    end
end //always end
assign  res_mul = tmp_b;
assign  res_vld = data_vld;
endmodule

 

请登录后发表评论

    没有回复内容