11 4x4查表乘法器——Verilog HDL练习
Rong晔
2021年05月20日 10:39
收录于文集
共16篇

 

设计目标:使用查表法实现4位乘法器。

 

设计思路:

首先限定了使用查表法实现。查表法的核心就是将乘法的所有可能结果存储起来,然后将两个相乘的数据组合起来作为地址,直接找到相应的结果。

然后4位乘法器的实现,一般是通过拆解位2位乘法器,即将高位宽数据分解成低位宽的数据再调用查表乘法器。

对于 2N 位数据 A,可分解为 A=A1×2^N+A2

此处我们是4位乘法器,所以A = 4×A1 + A2  ,B = 4×B1 + B2;

然后做乘法展开就有A×B = 16×A1×B1 + 4×A1×B2 + 4×A2×B1 + A2×B2;

只要把这个公式作为最后输出计算就可以了。

 

2位查表乘法器中,输入各有4种取值可能,所以共有16种可能【其中有8种重复】。

先单独写出2位查表乘法器模块,然后再调用。

描述语言:Verilog HDL

 

开发工具:Vivado 2019.2

 

工程链接:https://github.com/RongyeL/Verilog-HDL-Library/tree/main/11%20mult4x4

 

 

关键代码:

`timescale 1ns / 1ps

//==================================================================================================

//  Filename      : mult4x4.v

//  Created On    : 2021-05-14

//  Version       : V 1.0

//  Author        : Rongye

//  Description   : a 2 bits multiplier

//  Modification  :

//

//==================================================================================================

module MULT4x4(

    // INPUTS

        Clk,               // posedge active

        rst_n,             // negedge active

        a,             // 4 bits (0-15)

        b,             // 4 bits

    // OUTPUTS       

        out          // 8 bits

    );

    parameter N  = 4; // 4x4

 

    input              Clk;

    input              rst_n;

    input    [N-1:0]   a;

    input    [N-1:0]   b;

   

    output   [2*N-1:0] out;

   

    reg     [N/2-1:0]  a1,a2,b1,b2; // 2x2

    wire    [N-1:0]    out_a,out_b,out_c,out_d; 

       

    reg     [2*N-1:0]  out;

   

    always@(posedge Clk)

        if(!rst_n)begin

            a1 <= 'bx;

            a2 <= 'bx;

            b1 <= 'bx;

            b2 <= 'bx;

        end

        else begin

            a1 <= a[N-1:N-2];

            a2 <= a[N-3:N-4];

            b1 <= b[N-1:N-2];

            b2 <= b[N-3:N-4];

        end

   

    MULT2x2 MULT1(

            .Clk(Clk),        

            .rst_n(rst_n),         

            .a(a1),           

            .b(b1),            

            .out(out_a)         

            );

            

   MULT2x2 MULT2(

            .Clk(Clk),        

            .rst_n(rst_n),         

            .a(a1),           

            .b(b2),            

            .out(out_b)         

            );

           

   MULT2x2 MULT3(

            .Clk(Clk),        

            .rst_n(rst_n),         

            .a(a2),           

            .b(b1),            

            .out(out_c)         

            );

           

   MULT2x2 MULT4(

            .Clk(Clk),        

            .rst_n(rst_n),         

            .a(a2),           

            .b(b2),            

            .out(out_d)         

            );

  

    always@(posedge Clk)

        if(!rst_n)

            out <= 'bx;

        else

            out <= (out_a << 4) + (out_b << 2) + (out_c << 2) + out_d;

                

endmodule

 

`timescale 1ns / 1ps

//==================================================================================================

//  Filename      : mult2x2.v

//  Created On    : 2021-05-14

//  Version       : V 1.0

//  Author        : Rongye

//  Description   : a 2 bits multiplier

//  Modification  :

//

//==================================================================================================

 

module MULT2x2(

    // INPUTS

        Clk,               // posedge active

        rst_n,             // negedge active

        a,             // 2 bits

        b,             // 2 bits

    // OUTPUTS       

        out          // 4 bits

    );

    parameter N  = 2; // 2x2

 

    input              Clk;

    input              rst_n;

    input    [N-1:0]   a;

    input    [N-1:0]   b;

   

    output   [2*N-1:0] out;

 

    reg     [2*N-1:0]  out;

    reg     [2*N-1:0]  addr;

   

    always@(posedge Clk)begin

        addr <= {a,b};

        if(!rst_n)

            out <= 'bx;

        else            

            case(addr)

                4'h0:out <= 4&#​39;b0000;

                4'h1:out <= 4&#​39;b0000;

                4'h2:out <= 4&#​39;b0000;

                4'h3:out <= 4&#​39;b0000;

               

                4'h4:out <= 4&#​39;b0000;

                4'h5:out <= 4&#​39;b0001;

                4'h6:out <= 4&#​39;b0010;

                4'h7:out <= 4&#​39;b0011;

               

                4'h8:out <= 4&#​39;b0000;

                4'h9:out <= 4&#​39;b0010;

                4'ha:out <= 4&#​39;b0100;

                4'hb:out <= 4&#​39;b0110;

               

                4'hc:out <= 4&#​39;b0000;

                4'hd:out <= 4&#​39;b0011;

                4'he:out <= 4&#​39;b0110;

                4'hf:out <= 4&#​39;b1001;  

                default:out <= 'bx;        

            endcase

      end 

                

endmodule

仿真结果:

结果很容易看,计算都是正确的。

 

详情可见testbench文件。