1. 程式人生 > 其它 >基於ROM的位分解4位二進位制數乘法器設計

基於ROM的位分解4位二進位制數乘法器設計

1 設計要求

  設計一個4位二進位制數乘法器,採用查詢表實現(這裡將高位寬的資料分解成低位寬的資料再呼叫查詢表乘法器)。

2 設計分析

2.1 架構設計

  4位乘法器的框圖如下圖所示。其中,clk為系統時鐘,rst_n系統復位,低電平有效,a[3:0]為被乘數,b[3:0]為乘數,out[7:0]為積。

2.2 原理分析

(1)ROM原理

乘法器的一種實現思想是採用ROM的方式,即將被乘數和乘數連線起來拼成地址,把兩者所有可能的乘積按照地址號存放在ROM的地址空間中,兩個數相乘時,根據兩者構成的地址從ROM索取乘積結果。

如兩個1bit的數相乘,可能的相乘方式有0x1,0x0,1x1,1x0,一共四種相乘方式,其對應的結果也有四種,即0,0,1,0。那麼如果將這四個結果存在ROM中,其實正好用01,00,11,10四個地址來定址。因此是可以把所有的乘積結果都包含在內的。

通俗的來說,兩個Nbit二進位制數相乘,其結果為2Nbit,這意味著ROM的深度為2^(2N),寬度為(2N),佔用的空間大小為2^(2N)x2N。以兩個4bit 的數相乘例子,其儲存空間大小為256x8bit。顯然隨著位寬的增長,存貯空間將以指數速度膨脹,這是這個方法的一個弊端。

(2)位分解原理

由於上述弊端的存在 ,一種改進方法就是進行位分解,將兩個大位寬的數相乘分解為多個小位寬的數相乘。例如,設 A,B 為兩個 8 位資料,可將 A 分解為 A=A1×16+A2,其中 A1 為高 4 位,A2 為低 4 位;同理 B=B1×16+B2,然後A×B=(A1×16+A2)×(B1×16+B2)=A1*B1*16*16 + A1*B2*16 + A2*B1*16 + A2*B2(此處可以用左移來表示)。這樣就將兩個 8 位數的相乘轉化為 4 組 4 位數相乘,然後再相加,其中乘以常數可以通過移位運算實現,大大地縮減了儲存空間,其硬體結構如下圖所示:

(3)4位二進位制數乘法器

根據公式 A=A1×2^N+A2 可得知 N=2;最後得到式子:

A*B=(A1*4+A2)*(B1*4+B2)=A1*B1*4*4+A1*B2*4+A2*B1*4+A2*B3

A[3:0]×B[3:0] = A[3:2]×B[3:2]+ A[1:0]×B[3:2] +

A[3:2]×B[1:0] + A[1:0]×B[1:0] = (outa *16) + (outb *4)+ (outc *4) + outd= (outa << 4) + (outb << 2) + (outc << 2) + outd;

2.3 架構設計

3 設計實現

3.1 頂層設計

 1 module rom_mult_4bit(
 2     input     wire                 clk,
 3     input     wire                 rst_n,
 4     input     wire     [3:0]        a,
 5     input     wire     [3:0]        b,
 6     
 7     output     reg     [7:0]        out
 8 );
 9     
10     wire         [3:0]            outa;
11     wire         [3:0]            outb;
12     wire         [3:0]            outc;
13     wire         [3:0]            outd;
14     
15     rom_mult_2bit rom_mult_2bit0(
16             .clk                    (clk),
17             .rst_n                (rst_n),
18             .a                        (a[3:2]),
19             .b                        (b[3:2]),
20             .out                    (outa)
21         );
22     
23     rom_mult_2bit rom_mult_2bit1(
24             .clk                    (clk),
25             .rst_n                (rst_n),
26             .a                        (a[3:2]),
27             .b                        (b[1:0]),
28             .out                    (outb)
29         );
30     
31     rom_mult_2bit rom_mult_2bit2(
32             .clk                    (clk),
33             .rst_n                (rst_n),
34             .a                        (a[1:0]),
35             .b                        (b[3:2]),
36             .out                    (outc)
37         );
38     
39     rom_mult_2bit rom_mult_2bit3(
40             .clk                    (clk),
41             .rst_n                (rst_n),
42             .a                        (a[1:0]),
43             .b                        (b[1:0]),
44             .out                    (outd)
45         );
46     
47     always@(posedge clk or negedge rst_n)begin
48         if(rst_n == 1'b0)
49             out <= 8'd0;
50         else
51             out <= (outa << 4) + (outb << 2) + (outc << 2) + outd;
52     end    
53 
54 endmodule 

3.2 基於rom的2位乘法器設計

 1 module rom_mult_2bit(
 2     input     wire                 clk,
 3     input     wire                 rst_n,
 4     input     wire     [1:0]        a,
 5     input     wire     [1:0]        b,
 6     
 7     output     reg     [3:0]        out
 8 );
 9 
10     always@(posedge clk or negedge rst_n)begin
11         if(rst_n == 1'b0)
12             out <= 4'd0;
13         else begin
14             case({a,b})
15                 4'b0000    :     out <= 4'd0;
16                 4'b0001    :     out <= 4'd0;
17                 4'b0010    :     out <= 4'd0;
18                 4'b0011    :     out <= 4'd0;
19                 
20                 4'b0100    :     out <= 4'd0;
21                 4'b0101    :     out <= 4'd1;
22                 4'b0110    :     out <= 4'd2;
23                 4'b0111    :     out <= 4'd3;
24                 
25                 4'b1000    :     out <= 4'd0;
26                 4'b1001    :     out <= 4'd2;
27                 4'b1010    :     out <= 4'd4;
28                 4'b1011    :     out <= 4'd6;
29                 
30                 4'b1100    :     out <= 4'd0;
31                 4'b1101    :     out <= 4'd3;
32                 4'b1110    :     out <= 4'd6;
33                 4'b1111    :     out <= 4'd9;
34                 default    : out <= 4'd0;
35             endcase
36         end
37     end
38     
39 endmodule 

4 模擬驗證

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

5 參考文獻:
(1)(49條訊息) 乘法器設計(二):基於ROM的乘法器設計_MaoChuangAn的部落格-CSDN部落格