一、移位相加法实现乘法的原理
从被乘数的左边(最低位)开始,如果第 i 位为 1,则乘数左移 i (i = 0,1,2,······,size -1)位之后与之前的值相加,若最低位为 0 ,则保持不变,直至被乘数的最高位。
如:a = b = 101
a x b = 25
sum = 0;
101 第0位为 1, sum = sum + a << 0
101 第1位为 0 ,sum = sum
101 第3位为 1, sum = sum + a << 2
二、移位相加法实现8bit乘法器源码
1 // ********************************************************************************* 2 // Project Name : mul_add 3 // Email : 4 // Create Time : 2020/07/18 20:20 5 // Module Name : mul_add 6 // editor : qing 7 // Version : Rev1.0.0 8 // ********************************************************************************* 9 10 module mul_add( 11 input sclk , 12 input s_rst_n , 13 14 input start , 15 input [7:0] x , // 乘数 16 input [7:0] y , // 被乘数 17 18 output reg [15:0] result 19 ); 20 21 //========================================================================\ 22 // =========== Define Parameter and Internal signals =========== 23 //========================================================================/ 24 reg [7:0] cnt ; 25 reg [15:0] x_r ; // 乘数的中间变量 26 reg flag ; 27 reg [15:0] result_r ; 28 29 //============================================================================= 30 //**************************** Main Code ******************************* 31 //============================================================================= 32 33 always @(*) begin 34 x_r = {8'd0,x}; 35 end 36 37 always @(posedge sclk or negedge s_rst_n) begin // cnt 38 if(!s_rst_n) 39 cnt <= 0; 40 else if(start == 1'b1) 41 cnt <= 7; 42 else if(cnt == 0) 43 cnt <= cnt; 44 else 45 cnt <= cnt - 1'b1; 46 end 47 48 always @(posedge sclk or negedge s_rst_n) begin 49 if(!s_rst_n) 50 flag <= 1'b0; 51 else if(start == 1'b1) 52 flag <= 1'b1; 53 else if(cnt == 0) 54 flag <= 1'b0; 55 end 56 57 always @ (posedge sclk or negedge s_rst_n) begin 58 if(s_rst_n == 1'b0) begin 59 result_r <= 0; 60 end 61 else if(flag == 1'b1)begin 62 case(cnt) 63 8'd7:begin 64 if(y[0] == 1'b1) 65 result_r <= result_r + x_r; 66 else 67 result_r <= result_r; 68 end 69 8'd6:begin 70 if(y[1] == 1'b1) 71 result_r <= result_r + (x_r << 1); 72 else 73 result_r <= result_r; 74 end 75 8'd5:begin 76 if(y[2] == 1'b1) 77 result_r <= result_r + (x_r << 2); 78 else 79 result_r <= result_r; 80 end 81 8'd4:begin 82 if(y[3] == 1'b1) 83 result_r <= result_r + (x_r << 3); 84 else 85 result_r <= result_r; 86 end 87 8'd3:begin 88 if(y[4] == 1'b1) 89 result_r <= result_r + (x_r << 4); 90 else 91 result_r <= result_r; 92 end 93 8'd2:begin 94 if(y[5] == 1'b1) 95 result_r <= result_r + (x_r << 5); 96 else 97 result_r <= result_r; 98 end 99 8'd1:begin 100 if(y[6] == 1'b1) 101 result_r <= result_r + (x_r << 6); 102 else 103 result_r <= result_r; 104 end 105 8'd0:begin 106 if(y[7] == 1'b1) 107 result_r <= result_r + (x_r << 7); 108 else 109 result_r <= result_r; 110 end 111 default:begin 112 result_r <= 0; 113 end 114 endcase 115 end 116 else 117 result_r <= 0; 118 end 119 120 //assign result = ((cnt == 0) && (flag == 1'b1)) ? result_r : result; 121 122 always @(posedge sclk or negedge s_rst_n) begin 123 if(!s_rst_n) 124 result <= 0; 125 else if(cnt == 0 && flag == 1'b1) 126 result <= result_r; 127 end 128 129 130 endmodule