首先,对于普通的加法器,一般为串行加法器:
构成:把n位全加器串联起来,低位全加器的进位输出连接到相邻的高位全加器的进位输入。
特点:进位信号是由低位向高位逐级传递的,进位产生时间较长,且各加法器的和产生时间也不同,速度不高。
分析:该电路的缺点是,对于某一位的运算,需要先进行等待,直到来自低位的进位到达,才能开始本位的计算,因此将会引起较长的时间延迟。所以关键问题就是如何避免等待上一级进位信号,不如提前把进位信号分配给每一位直接运算?
下面介绍本文的重点:超前进位加法器:
设两个数 A , B
module fastAdder_4(sum,c_out,a,b,c_in);
//超前进位 四位加法器 代表并行结构
input[3:0] a,b,c_in;
output[3:0] sum,c_out;
wire[3:0] g,p; // g
wire[4:0] c;
assign p=a^b; //传播信号
assign g=a&b; //生成信号
// 分析 对于某一特定位 是否产生进位
// 取决于两个被加位 | 低位的进位和两个被加位 运算结果相&
assign c[0]=c_in;
assign c[1]=g[0]|(p[0]&c[0]); //进位
assign c[2]=g[1]|(p[1]&(g[0]|(p[0]&c[0])));
assign c[3]=g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))));
assign c[4]=g[3]|(p[3]&(g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))))));
assign sum = p^c[3:0];
assign c_out=c[4];
endmodule
测试代码
module fastAdder_4_tb;
reg [3:0] a,b;
reg c_in;
wire [3:0] sum;
wire c_out;
fastAdder_4 U3(.a(a),.b(b),.c_in(c_in),.sum(sum),.c_out(c_out));
initial
begin
a=4'b0001;b=4'b0101;c_in=1'b0;
#100 a=4'b0001;b=4'b0111;
#100 a=4'b0111;b=4'b1100;
#100 b=4'b1111;c_in=1'b1;
#100 a=4'b1101;b=4'b0100;
#100 a=4'b0000;b=4'b1001;c_in=1'b0;
#100 a=4'b1000;b=4'b0110;
end
endmodule
RTL视图:
仿真结果如下:
第一次写博客,目的是为了做笔记,加深印象,和大家分享我的收获。如果有逻辑不严谨,或者错误之处,大家可以交流一下,一起进步!
补充:
又搞到一个新知识点:关于“流水线超前进位加法器的设计”
关于流水线工作:大家可以去查找相关文档,大致的工作框图如下:
可以显著的减少吞吐延时,提高计算效率。
我直接放代码好了:
module fastadder_pipe(sum,c_out,a,b,c_in,clk);
input[3:0] a,b; input c_in,clk;
output reg[3:0] sum; output reg c_out;
reg c_out_temp, c_in_temp1,c_in_temp2;
reg[3:0] g,p;reg[4:1] c;
always@(posedge clk)
begin
p<=a^b;
g<=a&b;
end
always@(posedge clk)
begin
c_in_temp1<=c_in;
c_in_temp2<=c_in_temp1;
end
always@(posedge clk)
begin
c[1]=g[0]|(p[0]&c_in_temp1);
c[2]=g[1]|(p[1]&(g[0]|(p[0]&c_in_temp1)));
c[3]=g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c_in_temp1))))); c[4]=g[3]|(p[3]&(g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c_in_temp1)))))));
end
always@(posedge clk)
sum=p^{c[3:1],c_in_temp2};
always@(posedge clk)
begin
c_out_temp<=c[4];
c_out<= c_out_temp;
end
endmodule
端口不变 测试文件同上
RTL视图:
大家可以观察下,与上一个超前进位的加法器有什么区别,哈哈。