串行进位加法器与超前进位加法器 verilog

串行进位加法器

半加器

module half_adder (
	input in1,
	input in2,
	output sum,
	output cout
);

assign sum = in1^in2;
assign cout = in1&in2;
	
endmodule

全加器

module full_adder (
	input in1,
	input in2,
	input cin,
	output sum,
	output cout
);

wire xor2;
assign xor2 = in1^ in2;				// reuse

assign sum = xor2^ cin;						

// assign cout = in1&in2| in1&cin| in2&cin;	// 3and 2or
// assign cout = in1&in2| cin&(in1|in2);		// one less and, 2and 2or
assign cout = (xor2&cin)| (in1&in2);				// resuse in1^in2, 2and 1or 
	
endmodule
module full_adder_comb (
	input in1,
	input in2,
	input cin,
	output sum,
	output cout
);

wire sum1;
wire sum2;

wire cout1;
wire cout2;

half_adder u1(
	.in1	(in1),
	.in2	(in2),
	.sum	(sum1),
	.cout	(cout1)
);

half_adder u2(
	.in1	(sum1),
	.in2	(cin),
	.sum	(sum2),
	.cout	(cout2)
);

assign sum = sum2;
assign cout = cout1| cout2;

endmodule

任意位数串行进位加法器

module serial_adder#(
	parameter WIDTH = 8
)(
	input [WIDTH-1:0] 	in1,
	input [WIDTH-1:0] 	in2,
	input 				cin,
	output	[WIDTH:0]	sum
);

wire [WIDTH:0]cout;
assign cout[0] = cin;

genvar i;
generate
	for(i=0; i<WIDTH; i=i+1)
	begin	:gf
		full_adder_comb ufa(
			.in1	(in1[i]),
			.in2	(in2[i]),
			.cin	(cout[i]),
			.sum	(sum[i]),
			.cout	(cout[i+1])
		);
	end
endgenerate

assign sum[WIDTH] = cout[WIDTH];
		

endmodule


tb

`timescale  1ns / 1ps

module tb_serial_adder;

// serial_adder Parameters
parameter PERIOD = 10;
parameter WIDTH  = 2;

// serial_adder Inputs
reg   [WIDTH-1:0]  in1                     = 0 ;
reg   [WIDTH-1:0]  in2                     = 0 ;
reg   cin                                  = 0 ;

// serial_adder Outputs
wire  [WIDTH:0]  sum                       ;


// initial
// begin
//     forever #(PERIOD/2)  clk=~clk;
// end

// initial
// begin
//     #(PERIOD*2) rst_n  =  1;
// end

serial_adder #(
    .WIDTH ( WIDTH ))
 u_serial_adder (
    .in1                     ( in1  [WIDTH-1:0] ),
    .in2                     ( in2  [WIDTH-1:0] ),
    .cin                     ( cin              ),

    .sum                     ( sum  [WIDTH:0]   )
);

initial
begin
	in1 = 8'b1111_0000;
	in2 = 8'b1111_0101;
	#10;
	in1 = 8'b1111_1111;
	in2 = 8'b1111_1111;
	cin = 1;
	#10;
	in1 = 8'b1111_1111;
	in2 = 8'b1001_1111;
	cin = 1;
	#10;
	in1 = 8'b1111_1111;
	in2 = 8'b1;
	cin = 1;
	#10;
	in1 = 8'b1111_1111;
	in2 = 8'b0;
	cin = 1;
	#10;
	in1 = 8'b1111_1111;
	in2 = 8'b1;
	cin = 0;

    $finish;
end

endmodule

在这里插入图片描述
在vivado中被优化的不成样子,且vivado似乎不支持通过WIDTH的方式进行传参,但Modelsim支持的非常完美

4bit超前进位加法器

虽然超前进位加法器不支持任意位数,但是可以通过嵌套实现高位超前进位加法器
嵌套方法有串行超前进位加法器与超前超前进位加法器

// s = in1^in2^cin
// 	= (in1|in2)^(in1&in2)^cin
// cout = in1&in2 | cin(in1|in2)

module lookahead_carry_adder #(
	parameter WIDTH = 4
)(
	input [WIDTH-1:0] 	in1,
	input [WIDTH-1:0] 	in2,
	input 				cin,
	output	[WIDTH:0]	sum
);

wire [WIDTH-1:0] G;
wire [WIDTH-1:0] P;
wire [WIDTH:0] C;	// input carry

assign G = in1&in2;
assign P = in1|in2;


assign C[0] = cin;	// lsb carry equals to cin
assign C[1] = G[0] | (C[0]&P[0]);
// assign C[2] = G[1] | C[1]&P[1];
assign C[2] = G[1] | (G[0]&P[1]) | (C[0]&P[0]&P[1]);
assign C[3] = G[2] | (G[1]&P[2]) | (G[0]&P[1]&P[2]) | (C[0]&P[0]&P[1]&P[2]);
assign C[4] = G[3] | (G[2]&P[3]) | (G[1]&P[2]&P[3]) | (G[0]&P[1]&P[2]&P[3]) | (C[0]&P[0]&P[1]&P[2]&P[3]);

assign sum[3:0] = P^G^C;
assign sum[4] = C[4];
endmodule


在这里插入图片描述

Reference

https://blog.csdn.net/qq_45861449/article/details/109460294
https://wenku.baidu.com/view/3b1b326dcc84b9d528ea81c758f5f61fb736287b.html
https://www.jianshu.com/p/6ce9cad8b467

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值