资讯详情

数字IC-1.10 手撕代码之整数乘法和二范数(Verilog HDL数字加减法练习好帮手)

1.数字加减法操作 、绝对值,乘数或除数为2^n乘除运算-归纳

2.二范数开根号码实战 out = (a*a b*b)^1/2 :JPL近似法

3.整数乘法代码实战 out = a*b :LUT 乘法器-通过搜索整数平方表来实现


1.数字加减法操作 、绝对值、被乘数或被除数为2^n乘除运算-归纳

以 DATA_WIDTH=8 以位有符号数为例。

:out = {a[DATA_WIDTH - 1], a} {b[DATA_WIDTH - 1], b};

:out = {a[DATA_WIDTH - 1], a} { ~b[DATA_WIDTH - 1], ~ b 1'b1};

:out = a[DATA_WIDTH - 1] ? (~a 1'b1) : a;

:out ={a[DATA_WIDTH - 1], a[DATA_WIDTH-(n 1):0], n'b0} ;//n'b0 N位宽的0数据不是有效语法,使用时需要常量数字

:out = {(n 1)'b({a[DATA_WIDTH - 1]), a[DATA_WIDTH-(n 1):0]} ; //(n 1)'b({a[DATA_WIDTH - 1]) 表示n 一位宽,每位都是a的符号位,数据。这是为了应对a的负数

2.二范数开根号码实战 out = (a*a b*b)^1/2 :JPL近似法(点击查看理论)

`timescale 1ns / 1ns  module sqrt_x2_y2#(parameter DATA_WIDTH=8)(     input   wire                                  sys_clk  ,     input   wire                                  sys_rst_n,     input   wire  [DATA_WIDTH-1:0]  dataa    ,     input   wire  [DATA_WIDTH-1:0]  datab    ,     output reg   [DATA_WIDTH-1:0]  ampout );  wire [DATA_WIDTH-1:0]    dataa_abs ; wire [DATA_WIDTH-1:0]    datab_abs ;  wire                                    a_than_b  ;  wire  [DATA_WIDTH-1:0]      dataabs_max,dataabs_min ; wire  [DATA_WIDTH-1:0]     absmin_3 ;    // 求绝对值    assign dataa_abs = dataa[DATA_WIDTH-1]  ? (~dataa   1'b1) : dataa ;  assign datab_abs = datab[DATA_WIDTH-1] ? (~datab   1'b1) : datab;     assign a_than_b  = dataa_abs > datab_abs;    //比较数据大小 assign {dataabs_max, dataabs_min} = dataa_abs > datab_abs ?  {dataa_abs, datab_abs} : {datab_abs, dataa_abs}  ;  //计算 3倍min值  assign absmin_3 =  {dataabs_min[DATA_WIDTH-1], dataabs_min}                                   {dataabs_min[DATA_WIDTH-1],dataabs_min[DATA_WIDTH-2:0],1'b0} ;           ///按条件接近公式  3min>data_abs_max  always @(posedge sys_clk)    begin         if(!sys_rst_n)             ampout <= #1 'd0;         else if(absmin_3 > dataabs_max)// 7/8a   1/2 b              ampout <= #1 {1'b0,dataabs_max} - {4'b0,dataabs_max[DATA_WIDTH-2:3]}   {2'b0,dataabs_min[DATA_WIDTH-2:1]} ;          else // a   1/8 b              ampout <= #1  {1'b0,dataabs_max}  {4'b0,dataabs_min[DATA_WIDTH-2:3]} ;    end               endmodule

`timescale 1ns / 1ns module tb_sqrt( );     parameter DATA_WIDTH = 8;           reg                                    sys_clk   ;      reg                                    sys_rst_n;      reg    [DATA_WIDTH-1:0]  dataa    ;      reg    [DATA_WIDTH-1:0]  datab    ;      wire  [DATA_WIDTH-1:0]  out        ;             initial begin         sys_clk        = 1'b0;         sys_rst_n  <= 1'b0;         #40          sys_rst_n <= 1'b1;         #100         #1000         $stop();     end          always #10 sys_clk = ~sys_clk;          always @(posedge sys_clk) begin         if(!sys_rst_n)             dataa <= 8'd1;          else             dataa <= 8'd3;     end          always @(posedgesys_clk) begin
         if(!sys_rst_n)
            datab <= 8'd1;
         else
            datab <= 8'd4;
    end
    
    sqrt_x2_y2
    #( .DATA_WIDTH  (DATA_WIDTH))
    tb_sqrt_inst
    (
        .sys_clk     (sys_clk    ) ,
        .sys_rst_n  (sys_rst_n),
        .dataa       (dataa     ) ,
        .datab       (datab     ),
        .ampout   (out          )
    );
endmodule

3、整数乘法代码实战 out = a*b : LUT 乘法器-用查找整数平方表实现(点击查看理论)

        这个例子不限于正负同号相乘,也可用于异号相乘。

 

`timescale 1ns / 1ns

module lut_mult
(
    input clk,
    input [7:0] in_1,
    input [7:0] in_2,
    output reg [15:0]  out
);
   reg [7:0]   add;
   reg [7:0]   sub;
   reg [15:0] out_data;
   wire          p_n;
   wire[2:0]  p_n_m;
    
    // 计算输出符号
    assign p_n   = in_1[7]^in_2[7];
    assign p_n_m = {p_n, p_n, p_n};
   
   always @(*) begin
         // 正数相加和相减
         add = {in_1[7], in_1 } + { in_2[7], in_2};
         sub = {in_1[7], in_1 }+ { ~in_2[7],~ in_2+1'b1};
         // 将 a + b 的结果取正
		 add  = add[7] ? (~add+1'b1) : add;
			// 将 a - b 的结果取正
		 sub  = sub[7] ? (~sub+1'b1) : sub;
		 // 平方相减除4
         out_data    = { 1'b0,get_256_pow(add) }+{1'b1, ~get_256_pow(sub) +1'b1};
         out_data    =  {p_n_m, out_data[14:2]} ;
   end
   
     always @(posedge clk)
         out <= #1 out_data;
// 查找表  LUT
/*
python 数据生成代码

f = open('log.txt','w')
for i in range(256):
    f.write("       17'd"+str(i)+" :  get_256_pow = 19'd"+str(i*i)+" ;\n")
f.close()
*/
function [16:0]  get_256_pow;
    input  [8:0] n;
    begin
        case(n)
                  9'd0 :  get_256_pow = 17'd0 ;
       9'd1 :  get_256_pow = 17'd1 ;
       9'd2 :  get_256_pow = 17'd4 ;
       9'd3 :  get_256_pow = 17'd9 ;
       9'd4 :  get_256_pow = 17'd16 ;
       9'd5 :  get_256_pow = 17'd25 ;
       9'd6 :  get_256_pow = 17'd36 ;
       9'd7 :  get_256_pow = 17'd49 ;
       9'd8 :  get_256_pow = 17'd64 ;
       9'd9 :  get_256_pow = 17'd81 ;
       9'd10 :  get_256_pow = 17'd100 ;
       9'd11 :  get_256_pow = 17'd121 ;
       9'd12 :  get_256_pow = 17'd144 ;
       9'd13 :  get_256_pow = 17'd169 ;
       9'd14 :  get_256_pow = 17'd196 ;
       9'd15 :  get_256_pow = 17'd225 ;
       9'd16 :  get_256_pow = 17'd256 ;
       9'd17 :  get_256_pow = 17'd289 ;
       9'd18 :  get_256_pow = 17'd324 ;
       9'd19 :  get_256_pow = 17'd361 ;
       9'd20 :  get_256_pow = 17'd400 ;
       9'd21 :  get_256_pow = 17'd441 ;
       9'd22 :  get_256_pow = 17'd484 ;
       9'd23 :  get_256_pow = 17'd529 ;
       9'd24 :  get_256_pow = 17'd576 ;
       9'd25 :  get_256_pow = 17'd625 ;
       9'd26 :  get_256_pow = 17'd676 ;
       9'd27 :  get_256_pow = 17'd729 ;
       9'd28 :  get_256_pow = 17'd784 ;
       9'd29 :  get_256_pow = 17'd841 ;
       9'd30 :  get_256_pow = 17'd900 ;
       9'd31 :  get_256_pow = 17'd961 ;
       9'd32 :  get_256_pow = 17'd1024 ;
       9'd33 :  get_256_pow = 17'd1089 ;
       9'd34 :  get_256_pow = 17'd1156 ;
       9'd35 :  get_256_pow = 17'd1225 ;
       9'd36 :  get_256_pow = 17'd1296 ;
       9'd37 :  get_256_pow = 17'd1369 ;
       9'd38 :  get_256_pow = 17'd1444 ;
       9'd39 :  get_256_pow = 17'd1521 ;
       9'd40 :  get_256_pow = 17'd1600 ;
       9'd41 :  get_256_pow = 17'd1681 ;
       9'd42 :  get_256_pow = 17'd1764 ;
       9'd43 :  get_256_pow = 17'd1849 ;
       9'd44 :  get_256_pow = 17'd1936 ;
       9'd45 :  get_256_pow = 17'd2025 ;
       9'd46 :  get_256_pow = 17'd2116 ;
       9'd47 :  get_256_pow = 17'd2209 ;
       9'd48 :  get_256_pow = 17'd2304 ;
       9'd49 :  get_256_pow = 17'd2401 ;
       9'd50 :  get_256_pow = 17'd2500 ;
       9'd51 :  get_256_pow = 17'd2601 ;
       9'd52 :  get_256_pow = 17'd2704 ;
       9'd53 :  get_256_pow = 17'd2809 ;
       9'd54 :  get_256_pow = 17'd2916 ;
       9'd55 :  get_256_pow = 17'd3025 ;
       9'd56 :  get_256_pow = 17'd3136 ;
       9'd57 :  get_256_pow = 17'd3249 ;
       9'd58 :  get_256_pow = 17'd3364 ;
       9'd59 :  get_256_pow = 17'd3481 ;
       9'd60 :  get_256_pow = 17'd3600 ;
       9'd61 :  get_256_pow = 17'd3721 ;
       9'd62 :  get_256_pow = 17'd3844 ;
       9'd63 :  get_256_pow = 17'd3969 ;
       9'd64 :  get_256_pow = 17'd4096 ;
       9'd65 :  get_256_pow = 17'd4225 ;
       9'd66 :  get_256_pow = 17'd4356 ;
       9'd67 :  get_256_pow = 17'd4489 ;
       9'd68 :  get_256_pow = 17'd4624 ;
       9'd69 :  get_256_pow = 17'd4761 ;
       9'd70 :  get_256_pow = 17'd4900 ;
       9'd71 :  get_256_pow = 17'd5041 ;
       9'd72 :  get_256_pow = 17'd5184 ;
       9'd73 :  get_256_pow = 17'd5329 ;
       9'd74 :  get_256_pow = 17'd5476 ;
       9'd75 :  get_256_pow = 17'd5625 ;
       9'd76 :  get_256_pow = 17'd5776 ;
       9'd77 :  get_256_pow = 17'd5929 ;
       9'd78 :  get_256_pow = 17'd6084 ;
       9'd79 :  get_256_pow = 17'd6241 ;
       9'd80 :  get_256_pow = 17'd6400 ;
       9'd81 :  get_256_pow = 17'd6561 ;
       9'd82 :  get_256_pow = 17'd6724 ;
       9'd83 :  get_256_pow = 17'd6889 ;
       9'd84 :  get_256_pow = 17'd7056 ;
       9'd85 :  get_256_pow = 17'd7225 ;
       9'd86 :  get_256_pow = 17'd7396 ;
       9'd87 :  get_256_pow = 17'd7569 ;
       9'd88 :  get_256_pow = 17'd7744 ;
       9'd89 :  get_256_pow = 17'd7921 ;
       9'd90 :  get_256_pow = 17'd8100 ;
       9'd91 :  get_256_pow = 17'd8281 ;
       9'd92 :  get_256_pow = 17'd8464 ;
       9'd93 :  get_256_pow = 17'd8649 ;
       9'd94 :  get_256_pow = 17'd8836 ;
       9'd95 :  get_256_pow = 17'd9025 ;
       9'd96 :  get_256_pow = 17'd9216 ;
       9'd97 :  get_256_pow = 17'd9409 ;
       9'd98 :  get_256_pow = 17'd9604 ;
       9'd99 :  get_256_pow = 17'd9801 ;
       9'd100 :  get_256_pow = 17'd10000 ;
       9'd101 :  get_256_pow = 17'd10201 ;
       9'd102 :  get_256_pow = 17'd10404 ;
       9'd103 :  get_256_pow = 17'd10609 ;
       9'd104 :  get_256_pow = 17'd10816 ;
       9'd105 :  get_256_pow = 17'd11025 ;
       9'd106 :  get_256_pow = 17'd11236 ;
       9'd107 :  get_256_pow = 17'd11449 ;
       9'd108 :  get_256_pow = 17'd11664 ;
       9'd109 :  get_256_pow = 17'd11881 ;
       9'd110 :  get_256_pow = 17'd12100 ;
       9'd111 :  get_256_pow = 17'd12321 ;
       9'd112 :  get_256_pow = 17'd12544 ;
       9'd113 :  get_256_pow = 17'd12769 ;
       9'd114 :  get_256_pow = 17'd12996 ;
       9'd115 :  get_256_pow = 17'd13225 ;
       9'd116 :  get_256_pow = 17'd13456 ;
       9'd117 :  get_256_pow = 17'd13689 ;
       9'd118 :  get_256_pow = 17'd13924 ;
       9'd119 :  get_256_pow = 17'd14161 ;
       9'd120 :  get_256_pow = 17'd14400 ;
       9'd121 :  get_256_pow = 17'd14641 ;
       9'd122 :  get_256_pow = 17'd14884 ;
       9'd123 :  get_256_pow = 17'd15129 ;
       9'd124 :  get_256_pow = 17'd15376 ;
       9'd125 :  get_256_pow = 17'd15625 ;
       9'd126 :  get_256_pow = 17'd15876 ;
       9'd127 :  get_256_pow = 17'd16129 ;
       9'd128 :  get_256_pow = 17'd16384 ;
       9'd129 :  get_256_pow = 17'd16641 ;
       9'd130 :  get_256_pow = 17'd16900 ;
       9'd131 :  get_256_pow = 17'd17161 ;
       9'd132 :  get_256_pow = 17'd17424 ;
       9'd133 :  get_256_pow = 17'd17689 ;
       9'd134 :  get_256_pow = 17'd17956 ;
       9'd135 :  get_256_pow = 17'd18225 ;
       9'd136 :  get_256_pow = 17'd18496 ;
       9'd137 :  get_256_pow = 17'd18769 ;
       9'd138 :  get_256_pow = 17'd19044 ;
       9'd139 :  get_256_pow = 17'd19321 ;
       9'd140 :  get_256_pow = 17'd19600 ;
       9'd141 :  get_256_pow = 17'd19881 ;
       9'd142 :  get_256_pow = 17'd20164 ;
       9'd143 :  get_256_pow = 17'd20449 ;
       9'd144 :  get_256_pow = 17'd20736 ;
       9'd145 :  get_256_pow = 17'd21025 ;
       9'd146 :  get_256_pow = 17'd21316 ;
       9'd147 :  get_256_pow = 17'd21609 ;
       9'd148 :  get_256_pow = 17'd21904 ;
       9'd149 :  get_256_pow = 17'd22201 ;
       9'd150 :  get_256_pow = 17'd22500 ;
       9'd151 :  get_256_pow = 17'd22801 ;
       9'd152 :  get_256_pow = 17'd23104 ;
       9'd153 :  get_256_pow = 17'd23409 ;
       9'd154 :  get_256_pow = 17'd23716 ;
       9'd155 :  get_256_pow = 17'd24025 ;
       9'd156 :  get_256_pow = 17'd24336 ;
       9'd157 :  get_256_pow = 17'd24649 ;
       9'd158 :  get_256_pow = 17'd24964 ;
       9'd159 :  get_256_pow = 17'd25281 ;
       9'd160 :  get_256_pow = 17'd25600 ;
       9'd161 :  get_256_pow = 17'd25921 ;
       9'd162 :  get_256_pow = 17'd26244 ;
       9'd163 :  get_256_pow = 17'd26569 ;
       9'd164 :  get_256_pow = 17'd26896 ;
       9'd165 :  get_256_pow = 17'd27225 ;
       9'd166 :  get_256_pow = 17'd27556 ;
       9'd167 :  get_256_pow = 17'd27889 ;
       9'd168 :  get_256_pow = 17'd28224 ;
       9'd169 :  get_256_pow = 17'd28561 ;
       9'd170 :  get_256_pow = 17'd28900 ;
       9'd171 :  get_256_pow = 17'd29241 ;
       9'd172 :  get_256_pow = 17'd29584 ;
       9'd173 :  get_256_pow = 17'd29929 ;
       9'd174 :  get_256_pow = 17'd30276 ;
       9'd175 :  get_256_pow = 17'd30625 ;
       9'd176 :  get_256_pow = 17'd30976 ;
       9'd177 :  get_256_pow = 17'd31329 ;
       9'd178 :  get_256_pow = 17'd31684 ;
       9'd179 :  get_256_pow = 17'd32041 ;
       9'd180 :  get_256_pow = 17'd32400 ;
       9'd181 :  get_256_pow = 17'd32761 ;
       9'd182 :  get_256_pow = 17'd33124 ;
       9'd183 :  get_256_pow = 17'd33489 ;
       9'd184 :  get_256_pow = 17'd33856 ;
       9'd185 :  get_256_pow = 17'd34225 ;
       9'd186 :  get_256_pow = 17'd34596 ;
       9'd187 :  get_256_pow = 17'd34969 ;
       9'd188 :  get_256_pow = 17'd35344 ;
       9'd189 :  get_256_pow = 17'd35721 ;
       9'd190 :  get_256_pow = 17'd36100 ;
       9'd191 :  get_256_pow = 17'd36481 ;
       9'd192 :  get_256_pow = 17'd36864 ;
       9'd193 :  get_256_pow = 17'd37249 ;
       9'd194 :  get_256_pow = 17'd37636 ;
       9'd195 :  get_256_pow = 17'd38025 ;
       9'd196 :  get_256_pow = 17'd38416 ;
       9'd197 :  get_256_pow = 17'd38809 ;
       9'd198 :  get_256_pow = 17'd39204 ;
       9'd199 :  get_256_pow = 17'd39601 ;
       9'd200 :  get_256_pow = 17'd40000 ;
       9'd201 :  get_256_pow = 17'd40401 ;
       9'd202 :  get_256_pow = 17'd40804 ;
       9'd203 :  get_256_pow = 17'd41209 ;
       9'd204 :  get_256_pow = 17'd41616 ;
       9'd205 :  get_256_pow = 17'd42025 ;
       9'd206 :  get_256_pow = 17'd42436 ;
       9'd207 :  get_256_pow = 17'd42849 ;
       9'd208 :  get_256_pow = 17'd43264 ;
       9'd209 :  get_256_pow = 17'd43681 ;
       9'd210 :  get_256_pow = 17'd44100 ;
       9'd211 :  get_256_pow = 17'd44521 ;
       9'd212 :  get_256_pow = 17'd44944 ;
       9'd213 :  get_256_pow = 17'd45369 ;
       9'd214 :  get_256_pow = 17'd45796 ;
       9'd215 :  get_256_pow = 17'd46225 ;
       9'd216 :  get_256_pow = 17'd46656 ;
       9'd217 :  get_256_pow = 17'd47089 ;
       9'd218 :  get_256_pow = 17'd47524 ;
       9'd219 :  get_256_pow = 17'd47961 ;
       9'd220 :  get_256_pow = 17'd48400 ;
       9'd221 :  get_256_pow = 17'd48841 ;
       9'd222 :  get_256_pow = 17'd49284 ;
       9'd223 :  get_256_pow = 17'd49729 ;
       9'd224 :  get_256_pow = 17'd50176 ;
       9'd225 :  get_256_pow = 17'd50625 ;
       9'd226 :  get_256_pow = 17'd51076 ;
       9'd227 :  get_256_pow = 17'd51529 ;
       9'd228 :  get_256_pow = 17'd51984 ;
       9'd229 :  get_256_pow = 17'd52441 ;
       9'd230 :  get_256_pow = 17'd52900 ;
       9'd231 :  get_256_pow = 17'd53361 ;
       9'd232 :  get_256_pow = 17'd53824 ;
       9'd233 :  get_256_pow = 17'd54289 ;
       9'd234 :  get_256_pow = 17'd54756 ;
       9'd235 :  get_256_pow = 17'd55225 ;
       9'd236 :  get_256_pow = 17'd55696 ;
       9'd237 :  get_256_pow = 17'd56169 ;
       9'd238 :  get_256_pow = 17'd56644 ;
       9'd239 :  get_256_pow = 17'd57121 ;
       9'd240 :  get_256_pow = 17'd57600 ;
       9'd241 :  get_256_pow = 17'd58081 ;
       9'd242 :  get_256_pow = 17'd58564 ;
       9'd243 :  get_256_pow = 17'd59049 ;
       9'd244 :  get_256_pow = 17'd59536 ;
       9'd245 :  get_256_pow = 17'd60025 ;
       9'd246 :  get_256_pow = 17'd60516 ;
       9'd247 :  get_256_pow = 17'd61009 ;
       9'd248 :  get_256_pow = 17'd61504 ;
       9'd249 :  get_256_pow = 17'd62001 ;
       9'd250 :  get_256_pow = 17'd62500 ;
       9'd251 :  get_256_pow = 17'd63001 ;
       9'd252 :  get_256_pow = 17'd63504 ;
       9'd253 :  get_256_pow = 17'd64009 ;
       9'd254 :  get_256_pow = 17'd64516 ;
       9'd255 :  get_256_pow = 17'd65025 ;
            default:    get_256_pow = 17'd1 ;
        endcase
    end
endfunction

endmodule

`timescale 1ns / 1ns

module tb_my_mux( );
    reg    clk;
    reg    [7:0] in_1;
    reg    [7:0] in_2;
    reg    start;
    wire [15:0] out;
    
    initial begin
        start = 1'b0;
        clk    = 1'b0;
         in_1 =8'd0;
         in_2 =8'd0;
        #40
         start <= 1'b1;
        #600
        start <= 1'b0;
        #400
        $stop();
    end
    
    always #10 clk = ~clk;
    
    always @(posedge clk) begin
        if(start)
            in_1 <=8'd0-8'd2;
         else
             in_1 <=8'd1;
    end
    
    always @(posedge clk) begin
        if(start)
            in_2 <=8'd4;
         else
             in_2 <=8'd1;
    end
   
lut_mult my_mux
(
    . clk  (clk),
    .in_1 (in_1),
    .in_2 (in_2),
   .out  (out)
);  
endmodule

标签: d142对射式光电传感器d150steel连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台