【Verilog 设计】Verilog 加法器设计

加法器

加法是基本的运算,在数字信号处理和数字通信的各种算法中被广泛应用。由于加法器使用频繁,所以其速度往往影响整个系统的运行速度。如果可实现快速的加法器的设计,则可以提高整个系统的运行速度。

以下介绍几种常见的加法器设计,提供 Verilog 设计并分析其优缺点。

行波进位加法器

这中加法器设计由多个 1 位全加器级联构成,依次从低位向高位传递,并输出最终的结果。

Verilog 实现

module add_1 (
    input  [3:0]  a,
    input  [3:0]  b,
    input         cin,
    output [3:0]  sum,
    output        cout;
);
add_full add_full_1(
    .a(a),
    .b(b),
    .cin(cin),
    .sum(sum),
    .cout(cin)
);
add_full add_full_1(
    .a(a[0]),
    .b(b[0]),
    .cin(cin),
    .sum(sum[0]),
    .cout(cin1)
);
add_full add_full_2(
    .a(a[1]),
    .b(b[1]),
    .cin(cin1),
    .sum(sum[1]),
    .cout(cin2)
);
add_full add_full_3(
    .a(a[2]),
    .b(b[2]),
    .cin(cin2),
    .sum(sum[2]),
    .cout(cin3)
);
add_full add_full_4(
    .a(a[3]),
    .b(b[3]),
    .cin(cin3),
    .sum(sum[3]),
    .cout(cin4)
);
module add_full(
    input        a,
    input        b,
    input        cin,
    output  reg  sum,
    output  reg  cout
);
always @(*) begin
    {cout,sum} = a + b + cin;
end
endmodule
endmodule

行波进位加法器设计优缺点

  • 优点:设计简单,初学者易学
  • 缺点:延时过大,如果加法的位宽过大,就会导致延时增加,n 位是 1 位的 n 倍,性能一般。

超前进位加法器

在上一种加法器的设计,最大的缺点就是位宽比较大的计算延时过大,要想提高运行速度就必须解决位宽带来的延时影响,超前进位加法器便可以有效解决以上的弊端。

对于全加器,一位全加器的本位值和进位输出可表示为:

sum = a ^ b ^ cin

cout = (a*b) + (a*cin) + (b*cin) = ab + (a+b)*cin

可知当 a 和 b 都为 1 时,进位输出cout为 1,而当其一为 1 时,进位输出 cout 为进位输入 cin。

这样令 G = a * b,P = a + b,则有 cout = a*b + (a+b)*cin = G + P*cin

由此就可以得到各个位的进位输出呈如下结果:

进一步推算:

sum = A ^ B ^ Cin = (A*B) ^ (A + B) ^ Cin = G ^ P ^ Cin

Verilog 实现

module add_u(
    input  [3:0]  a,
    input  [3:0]  b,
    input         cin,
    output [3:0]  sum,
    output        cout
);
wire  [3:0]  G;
wire  [3:0]  P;
wire  [3:0]  C;
//第0位
assign G[0] = a[0] & b[0];
assign P[0] = a[0] | b[0];
assign C[0] = cin;
assign sum[0] = G[0] ^ P[0] ^ C[0];
//第1位
assign G[1] = a[1] & b[1];
assign P[1] = a[1] | b[1];
assign C[1] = cin;
assign sum[1] = G[1] ^ P[1] ^ C[1];
//第2位
assign G[2] = a[2] & b[2];
assign P[2] = a[2] | b[2];
assign C[2] = cin;
assign sum[2] = G[2] ^ P[2] ^ C[2];
//第3位
assign G[3] = a[3] & b[3];
assign P[3] = a[3] | b[3];
assign C[3] = cin;
assign sum[3] = G[3] ^ P[3] ^ C[3];
//输出最终进位值
assign cout = C[3];
endmodule

数据流描述的加法器

这种方式实现起来就比较简单,直接采用全加器的形式进行描述,让综合工具自动识别形成电路。

Verilog 实现

module add(
    input [3:0]  a,
    input [3:0]  b.
    input        cin,
    output [3:0] sum,
    output       cout
);
assign {cout,sum} = a + b + cin;
endmodule

流水线加法器

在系统工作时为了尽可能的提高系统运行速度,保证数据的快速传输,流水线的设计是一种常见的设计方法。但是,如果在某些复杂逻辑功能的完成需要较长的延时,就会使系统难以运行在高的频率上。这种情况下,可使用流水线技术,即在长延时的逻辑功能块中插入触发器,使复杂的逻辑操作分步完成,减小每一部分的延时,从而使系统的运行频率得以提高。但是流水线的弊端在于增加了寄存器逻辑,进而消耗了更多的芯片内部资源。相当于用资源换速率,在资源允许的前提下,适当加入流水线的操作,可以显著提高系统的运行频率。

利用流水线的方法设计加法器可以显著提高系统的运行速度,以一个两级流水线的设计方法计算两个 8 位宽的数据相加。

module add(
    input             clk,
    input [7:0]       a,
    input [7:0]       b,
    input             cin,
    output reg [7:0]  sum,
    output reg        cout
);
reg [3:0]  a_reg;
reg [3:0]  b_reg;
reg [3:0]  sum1;
reg        cout1;
//计算低四位
always @(posedge clk) begin
    {cout1,sum1} = a[3:0] + b[3:0] + cin;
    a_reg = a[7:4];
    b_reg = b[7:4];
end
//计算高四位
always @(posedge clk) begin
    {cout1,sum[7:4]} = a_reg + b_reg + cout1;
    sum[3:0] = sum1;
end
endmodule 

将八位宽的数值计算拆分成两个四位数据的同步计算,可以提高计算速度,甚至可以差分成三份计算,这种视情况而定。

你可能感兴趣的:(Verilog,fpga开发,Verilog,硬件描述语言,数字IC,加法器)