设计目标:使用查表法实现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'b0000;
4'h1:out <= 4'b0000;
4'h2:out <= 4'b0000;
4'h3:out <= 4'b0000;
4'h4:out <= 4'b0000;
4'h5:out <= 4'b0001;
4'h6:out <= 4'b0010;
4'h7:out <= 4'b0011;
4'h8:out <= 4'b0000;
4'h9:out <= 4'b0010;
4'ha:out <= 4'b0100;
4'hb:out <= 4'b0110;
4'hc:out <= 4'b0000;
4'hd:out <= 4'b0011;
4'he:out <= 4'b0110;
4'hf:out <= 4'b1001;
default:out <= 'bx;
endcase
end
endmodule
仿真结果:

结果很容易看,计算都是正确的。
详情可见testbench文件。