基于查找表的4位二进制数乘法器设计

1. 设计要求:

  设计一个4位二进制数乘法器,采用查找表实现。

2. 设计分析

2.1 架构设计

  4位乘法器的框图如下图所示。其中,a[3:0]为被乘数,b[3:0]为乘数,m[7:0]为积,即乘法结果。

 

 

2.2 查找表

  查表法,就是建一个表,里面存放了所有的乘法结果,乘数和被乘数用来作为地址去里面的乘积,此种方法可以大大提高乘法的速率,但是当乘法位数很大时会要求产生很大的表格,所以此种方法适合位数较小的乘法,特别适合有一个乘数为固定的乘法,如滤波器中的乘法就可以采用此种方法设计…

  具体操作如下:设 A,B 为两个 4 位二进制数,则 A,B 各有16种取值可能,乘积有 16*16=256 种可能。我们先将{A,B}对应的 256 种可能结果存储起来,然后对于每一特点的输入组合{A,B},找到对应的输出即可。该方式速度很快,只取决于读取存储器的速度,但是预存结果要占用较多资源,因此是面积换取速度思想的体现。同时,随着乘数位宽的增加,需要存储的结果迅速增加,不利于实现,因此该方式适用于位宽很小的情况。但是我们可以将高位宽的数据分解成低位宽的数据再调用查找表乘法器。

3. 设计实现

 1 module rom_mult_4bit(
 2     input     wire                     clk,
 3     input     wire     [3:0]            a,
 4     input     wire     [3:0]            b,
 5     
 6     output     wire     [7:0]            m
 7 );
 8 
 9     rom_mult_data rom_mult_data_inst(
10         .address                    ({a,b}),
11         .clock                    (clk),
12         .q                            (m)
13     );
14 
15 endmodule 

MATLAB生成16*16的乘法口诀表,对ROM_IP进行初始化。

 1 clear all;clc;close all;
 2 depth = 256;            %存储器的深度
 3 width = 8;              %存储器的宽度
 4 fid = fopen('rom_mult_4bit.mif','w');%fopen函数以写方式打开文件,如不存在,自动创建
 5 fprintf(fid, 'DEPTH=%d;\n', depth); %fprintf函数可以将数据按指定格式写入到文本文件中
 6 fprintf(fid, 'WIDTH=%d;\n', width); %数据的格式化输出:fprintf(fid, format, variables)
 7 fprintf(fid, 'ADDRESS_RADIX=UNS;\n');%\n是换行,使光标下移一格
 8 fprintf(fid, 'DATA_RADIX=UNS;\n');
 9 fprintf(fid, 'CONTENT BEGIN\n');
10 for a = 0 : 15
11    for b = 0 : 15
12        addr = a * 16 + b;       %在Verilog中,等价于{a[3:0],b[3:0]}
13        num = a * b;
14        fprintf(fid, '%d : %d;\n',addr,num);
15    end
16 end
17 fprintf(fid, 'END;');
18 fclose(fid);

4. 仿真测试

 1 `timescale 1ns/1ps
 2 
 3 module rom_mult_4bit_tb();
 4 
 5     reg                         clk;
 6     reg         [3:0]            a;
 7     reg         [3:0]            b;
 8     
 9     wire         [7:0]            m;
10     wire         [7:0]            tb_m;
11     reg         [7:0]            tb_m_r;
12     reg    [7:0]            tb_m_rr;
13     
14     assign tb_m = a * b;
15     
16     always@(posedge clk)begin
17         tb_m_r     <= tb_m;
18         tb_m_rr    <= tb_m_r;
19     end
20     
21     rom_mult_4bit rom_mult_4bit_inst(
22         .clk                    (clk),
23         .a                        (a),
24         .b                        (b),
25     
26         .m                        (m)
27     );
28 
29     initial clk = 1'b0;
30     always #10 clk = ~clk;
31     
32     initial begin
33         a = 4'd0; b = 4'd0;
34         #20;
35         repeat(10)begin
36             a = {$random}%16;
37             b = {$random}%16;
38             #20;
39         end
40         #50;
41         $stop;
42     end
43     
44 endmodule 

 

参考文献:
(1)(49条消息) 查找表乘法器_sinat_37532077的博客-CSDN博客

(2)陪您一起学习FPGA-郝旭帅团队_哔哩哔哩_bilibili

posted @ 2021-08-18 19:39  豌豆茶  阅读(711)  评论(0编辑  收藏  举报