dp_adder16.v 5.64 KB
////////////////////////////////////////////////////////////////////////
//
// Project Reality
//
// module:	dp_adder16
// description:	16 bit carry-propagating adder for use in replacing 
//		datapath adder with standard cells.  Requires carry 
//		in and carry out.
//
//		Ripple adder with high performance ad01d1h cells.
//		
//
// designer:	Brian Ferguson
// date:	3/8/95
//
////////////////////////////////////////////////////////////////////////

module dp_adder16 (
			input1,
			input2,
			carryin,
			sumout,
			carryout14,
			carryout
		  ) ;

input [15:0] input1;
input [15:0] input2;
input carryin;

output [15:0] sumout;
output carryout14;	// carry out for bit 14 used to generate overflow
output carryout;	// carry out for bit 15


/*
*  This adder is optimised for area therefore is a 16 bit
*  ripple carry adder.
*/

/*
* Carry in does not go to carryin of least significant bit 
* data is timing critical not carryin.
*/

wire [7:0] carry;	// carry out for each bit

ad01d1h addb0	(	.a(carryin), .b(input2[0]), .ci(input1[0]),
			.s(sumout[0]), .co(carry[0])
		);

ad01d1h addb1	(	.a(input1[1]), .b(input2[1]), .ci(carry[0]),
			.s(sumout[1]), .co(carry[1])
		);

ad01d1h addb2	(	.a(input1[2]), .b(input2[2]), .ci(carry[1]),
			.s(sumout[2]), .co(carry[2])
		);

ad01d1h addb3	(	.a(input1[3]), .b(input2[3]), .ci(carry[2]),
			.s(sumout[3]), .co(carry[3])
		);

ad01d1h addb4	(	.a(input1[4]), .b(input2[4]), .ci(carry[3]),
			.s(sumout[4]), .co(carry[4])
		);

ad01d1h addb5	(	.a(input1[5]), .b(input2[5]), .ci(carry[4]),
			.s(sumout[5]), .co(carry[5])
		);

ad01d1h addb6	(	.a(input1[6]), .b(input2[6]), .ci(carry[5]),
			.s(sumout[6]), .co(carry[6])
		);

ad01d1h addb7	(	.a(input1[7]), .b(input2[7]), .ci(carry[6]),
			.s(sumout[7]), .co(carry[7])
		);

/*
* ad01d1h addb8	(	.a(input1[8]), .b(input2[8]), .ci(carry[7]),
*			.s(sumout[8]), .co(carry[8])
*		);
*/

/*
*  Carry select is applied to upper 8 bits of 16 bit add.
*  These are built out of low performance add cells to save area.
*  First group assumes carry in 0.
*/

wire [7:0] sumoutc0;	// sum out for upper 7 bits of adder assuming carry in 0
wire [7:0] carryc0;	// carry out for upper 7 bits of adder assuming carry in 0

/*
*ad01d2 addb8c0	(	.a(1'b0), .b(input2[8]), .ci(input1[8]),
*			.s(sumoutc0[0]), .co(carryc0[0])
*		);
*/

xo02d1 addb8s0  (	.a1(input2[8]), .a2(input1[8]),
			.z(sumoutc0[0])
		);

an02d1h addb8c0  (	.a1(input2[8]), .a2(input1[8]),
			.z(carryc0[0])
		);

ad01d1h addb9c0	(	.a(input1[9]), .b(input2[9]), .ci(carryc0[0]),
			.s(sumoutc0[1]), .co(carryc0[1])
		);

ad01d1h addb10c0 (	.a(input1[10]), .b(input2[10]), .ci(carryc0[1]),
			.s(sumoutc0[2]), .co(carryc0[2])
		);

ad01d1h addb11c0 (	.a(input1[11]), .b(input2[11]), .ci(carryc0[2]),
			.s(sumoutc0[3]), .co(carryc0[3])
		);

ad01d2 addb12c0 (	.a(input1[12]), .b(input2[12]), .ci(carryc0[3]),
			.s(sumoutc0[4]), .co(carryc0[4])
		);

ad01d2 addb13c0 (	.a(input1[13]), .b(input2[13]), .ci(carryc0[4]),
			.s(sumoutc0[5]), .co(carryc0[5])
		);

ad01d2 addb14c0 (	.a(input1[14]), .b(input2[14]), .ci(carryc0[5]),
			.s(sumoutc0[6]), .co(carryc0[6])
		);

ad01d2 addb15c0 (	.a(input1[15]), .b(input2[15]), .ci(carryc0[6]),
			.s(sumoutc0[7]), .co(carryc0[7])
		);


/*
*  Second group assumes carryout 1
*/

wire [7:0] sumoutc1;	// sum out for upper 7 bits of adder assuming carry in 1
wire [7:0] carryc1;	// carry out for upper 7 bits of adder assuming carry in 1

/*
*ad01d2 addb8c1	(	.a(1'b1), .b(input2[8]), .ci(input1[8]),
*			.s(sumoutc1[0]), .co(carryc1[0])
*		);
*/

xn02d1 addb8s1  (	.a1(input2[8]), .a2(input1[8]),
			.zn(sumoutc1[0])
		);

or02d2 addb8c1  (	.a1(input2[8]), .a2(input1[8]),
			.z(carryc1[0])
		);

ad01d1h addb9c1 (	.a(input1[9]), .b(input2[9]), .ci(carryc1[0]),
			.s(sumoutc1[1]), .co(carryc1[1])
		);

ad01d1h addb10c1 (	.a(input1[10]), .b(input2[10]), .ci(carryc1[1]),
			.s(sumoutc1[2]), .co(carryc1[2])
		);

ad01d1h addb11c1 (	.a(input1[11]), .b(input2[11]), .ci(carryc1[2]),
			.s(sumoutc1[3]), .co(carryc1[3])
		);

ad01d2 addb12c1 (	.a(input1[12]), .b(input2[12]), .ci(carryc1[3]),
			.s(sumoutc1[4]), .co(carryc1[4])
		);

ad01d2 addb13c1 (	.a(input1[13]), .b(input2[13]), .ci(carryc1[4]),
			.s(sumoutc1[5]), .co(carryc1[5])
		);

ad01d2 addb14c1 (	.a(input1[14]), .b(input2[14]), .ci(carryc1[5]),
			.s(sumoutc1[6]), .co(carryc1[6])
		);

ad01d2 addb15c1 (	.a(input1[15]), .b(input2[15]), .ci(carryc1[6]),
			.s(sumoutc1[7]), .co(carryc1[7])
		);


/*
*	Mux for carry selecting between upper 8 bits of data
*/

wire buf_carry;		// buffer carry out

ni01d7	buf_carry7 (	.z		(buf_carry),
			.i		(carry[7])
		   ) ;


mx21d1	dpcselmx8 (	.z		(sumout[8]),
			.i0		(sumoutc0[0]),
			.i1		(sumoutc1[0]),
			.s		(buf_carry)
		   ) ;

mx21d1	dpcselmx9 (	.z		(sumout[9]),
			.i0		(sumoutc0[1]),
			.i1		(sumoutc1[1]),
			.s		(buf_carry)
		   ) ;


mx21d1	dpcselmx10 (	.z		(sumout[10]),
			.i0		(sumoutc0[2]),
			.i1		(sumoutc1[2]),
			.s		(buf_carry)
		   ) ;


mx21d1	dpcselmx11 (	.z		(sumout[11]),
			.i0		(sumoutc0[3]),
			.i1		(sumoutc1[3]),
			.s		(buf_carry)
		   ) ;


mx21d1	dpcselmx12 (	.z		(sumout[12]),
			.i0		(sumoutc0[4]),
			.i1		(sumoutc1[4]),
			.s		(buf_carry)
		   ) ;


mx21d1	dpcselmx13 (	.z		(sumout[13]),
			.i0		(sumoutc0[5]),
			.i1		(sumoutc1[5]),
			.s		(buf_carry)
		   ) ;


mx21d1h	dpcselmx14 (	.z		(sumout[14]),
			.i0		(sumoutc0[6]),
			.i1		(sumoutc1[6]),
			.s		(buf_carry)
		   ) ;


mx21d1h	dpcselmx15 (	.z		(sumout[15]),
			.i0		(sumoutc0[7]),
			.i1		(sumoutc1[7]),
			.s		(carry[7])
		   ) ;



mx21d1h	coutb14	(	.z		(carryout14),
			.i0		(carryc0[6]),
			.i1		(carryc1[6]),
			.s		(buf_carry)
		) ;


mx21d1h	coutb15	(	.z		(carryout),
			.i0		(carryc0[7]),
			.i1		(carryc1[7]),
			.s		(carry[7])
		) ;


endmodule // dp_adder16