乘法器的Verilog HDL实现
原文链接:http://www.cnblogs.com/shengansong/archive/2011/05/23/2054401.html
1. 串行乘法器
两个N位二进制数x、y的乘积用简单的方法计算就是利用移位操作来实现。
module multi_CX(clk, x, y, result); input clk; input [7:0] x, y; output [15:0] result; reg [15:0] result; parameter s0 = 0, s1 = 1, s2 = 2; reg [2:0] count = 0; reg [1:0] state = 0; reg [15:0] P, T; reg [7:0] y_reg; always @(posedge clk) begin case (state) s0: begin count <= 0; P <= 0; y_reg <= y; T <= {{8{1'b0}}, x}; state <= s1; end s1: begin if(count == 3'b111) state <= s2; else begin if(y_reg[0] == 1'b1) P <= P + T; else P <= P; y_reg <= y_reg >> 1; T <= T << 1; count <= count + 1; state <= s1; end end s2: begin result <= P; state <= s0; end default: ; endcase end endmodule
乘法功能是正确的,但计算一次乘法须要8个周期。因此能够看出串行乘法器速度比較慢、时延大。但这样的乘法器的长处是所占用的资源是全部类型乘法器中最少的,在低速的信号处理中有着广泛的应用。
2.流水线乘法器
一般的高速乘法器通常採用逐位并行的迭代阵列结构,将每一个操作数的N位都并行地提交给乘法器。可是一般对于FPGA来讲。进位的速度快于加法的速度,这样的阵列结构并非最优的。所以能够採用多级流水线的形式。将相邻的两个部分乘积结果再加到终于的输出乘积上,即排成一个二叉树形式的结构,这样对于N位乘法器须要lb(N)级来实现。
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 [7:0] mul_out; reg [7:0] mul_out; reg [7:0] stored0; reg [7:0] stored1; reg [7:0] stored2; reg [7:0] stored3; reg [7:0] add01; reg [7:0] add23; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin mul_out <= 0; stored0 <= 0; stored1 <= 0; stored2 <= 0; stored3 <= 0; add01 <= 0; add23 <= 0; end else begin stored0 <= mul_b[0]? {4'b0, mul_a} : 8'b0; stored1 <= mul_b[1]? {3'b0, mul_a, 1'b0} : 8'b0; stored2 <= mul_b[2]? {2'b0, mul_a, 2'b0} : 8'b0; stored3 <= mul_b[3]? {1'b0, mul_a, 3'b0} : 8'b0; add01 <= stored1 + stored0; add23 <= stored3 + stored2; mul_out <= add01 + add23; end end endmodule
从图中能够看出,流水线乘法器比串行乘法器的速度快非常多非常多,在非快速的信号处理中有广泛的应用。至于快速信号的乘法一般须要利用FPGA芯片中内嵌的硬核DSP单元来实现。