verilog实现乘法器

verilog实现乘法器

以下介绍两种实现乘法器的方法:串行乘法器和流水线乘法器。

1)串行乘法器
两个N位二进制数x、y的乘积用简单的方法计算就是利用移位操作来实现。

其框图如下:

 

其状态图如下:

 

其实现的代码如下:

module multi_CX(clk, x, y, result);
02	     
03	    inputclk;
04	    input [7:0] x, y;
05	    output [15:0] result;
06	
07	    reg [15:0] result;
08	
09	    parameter s0 = 0, s1 = 1, s2 = 2;
10	    reg [2:0] count = 0;
11	    reg [1:0] state = 0;
12	    reg [15:0] P, T;
13	    reg [7:0] y_reg;
14	
15	    always @(posedge clk) begin
16	        case (state)
17	            s0: begin
18	                count <= 0;
19	                P <= 0;
20	                y_reg <= y;
21	                T <= {{8{1'b0}}, x};
22	                state <= s1;
23	            end
24	            s1: begin
25	                if(count == 3'b111)
26	                    state <= s2;
27	                else begin
28	                    if(y_reg[0] == 1'b1)
29	                        P <= P + T;
30	                    else
31	                        P <= P;
32	                    y_reg <= y_reg >> 1;
33	                    T <= T << 1;
34	                    count <= count + 1;
35	                    state <= s1;
36	                end
37	            end
38	            s2: begin
39	                result <= P;
40	                state <= s0;
41	            end
42	            default: ;
43	        endcase
44	    end
45	
46	endmodule
缺点:乘法功能是正确的,但计算一次乘法需要8个周期,因此可以看出串行乘法器速度比较慢、时延大。

优点:该乘法器所占用的资源是所有类型乘法器中最少的,在低速的信号处理中有广泛的使用。

2)流水线乘法器

一般的快速乘法器通常采用逐位并行的迭代阵列结构,将每个操作数的N位都并行地提交给乘法器。但是一般对于FPGA来讲,进位的速度快于加法的速度,这种阵列结构并不是最优的。所以可以采用多级流水线的形式,将相邻的两个部分乘积结果再加到最终的输出乘积上,即排成一个二叉树形式的结构,这样对于N位乘法器需要log2(N)级来实现,
一个8位乘法器,其原理图如下图所示:

 

其实现的代码如下:

module multi_4bits_pipelining(mul_a, mul_b, clk, rst_n, mul_out);
    input [3:0] mul_a, mul_b;
    input clk;
    input rst_n;
    output [15:0] mul_out;

    reg [15:0] mul_out;
    reg [15:0] stored0;
    reg [15:0] stored1;
    reg [15:0] stored2;
    reg [15:0] stored3;
    reg [15:0] stored4;
    reg [15:0] stored5;
    reg [15:0] stored6;
    reg [15:0] stored7;

    reg [15:0] mul_out01;
    reg [15:0] mul_out23;

    reg [15:0] add01;
    reg [15:0] add23;
    reg [15:0] add45;
    reg [15:0] add67;

    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            mul_out <= 0;
            stored0 <= 0;
            stored1 <= 0;
            stored2 <= 0;
            stored3 <= 0;
            stored4 <= 0;
                    stored5 <= 0;
            stored6 <= 0;
            stored7 <= 0;

            add01 <= 0;
            add23 <= 0;
            add45 <= 0;
            add67 <= 0;
    end
    else begin
        stored0 <= mul_b[0]? {8'b0, mul_a} : 16'b0;
        stored1 <= mul_b[1]? {7'b0, mul_a, 1'b0} : 16'b0;
        stored2 <= mul_b[2]? {6'b0, mul_a, 2'b0} : 16'b0;
        stored3 <= mul_b[3]? {5'b0, mul_a, 3'b0} : 16'b0;
        stored4 <= mul_b[0]? {4'b0, mul_a, 4'b0} : 16'b0;
        stored5 <= mul_b[1]? {3'b0, mul_a, 5'b0} : 16'b0;
        stored6 <= mul_b[2]? {2'b0, mul_a, 6'b0} : 16'b0;
        stored7 <= mul_b[3]? {1'b0, mul_a, 7'b0} : 16'b0;
        add01 <= stored1 + stored0;
        add23 <= stored3 + stored2;
        add45 <= stored5 + stored4;
        add67 <= stored7 + stored6;

        mul_out01 <= add01 + add23;
        mul_out23 <= add45 + add67;

        mul_out <= mul_out01 + mul_out23;

    end
    end
endmodule

流水线乘法器比串行乘法器的速度快很多很多,在非高速的信号处理中有广泛的应用。至于高速信号的乘法一般需要利用FPGA芯片中内嵌的硬核DSP单元来实现。

注:本文大部分内容转自乘法器的Verilog HDL实现 - 我心狂野 - 博客园

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值