tf_lerp_csa.v 8.06 KB
////////////////////////////////////////////////////////////////////////
//
// Project Reality
//
// module:	tf_lerp_csa
// description:	Carry save adder tree for bilerp for texture filter unit.
//		23 partial products. 18 are from pseudo-booth encoder
//		for lerp subtract/multiply. 2 are correction from 1's comp
//		to 2's comp. 1 is the final lerp add. 2 are terms for
//		4 point average. Note that this is the triangular bilerp
//		(2 multiplies per component). Probably all the CSAs will
//		need to be high performance.
//
// designer:	Phil Gossett
// date:	6/18/94
//
////////////////////////////////////////////////////////////////////////

module tf_lerp_csa (a, b, p0p, p1p, p2p, p3p, p4p, p5p, p6p, p7p, p8p,
			  q0q, q1q, q2q, q3q, q4q, q5q, q6q, q7q, q8q,
			  c, t, o, mp);

input [8:0] a;		// 2's comp correction
input [8:0] b;		// 2's comp correction
input [9:0] p0p;	// pseudo-booth encoded partial products (*a)
input [9:0] p1p;
input [9:0] p2p;
input [9:0] p3p;
input [9:0] p4p;
input [9:0] p5p;
input [9:0] p6p;
input [9:0] p7p;
input [8:0] p8p;
input [9:0] q0q;	// pseudo-booth encoded partial products (*b)
input [9:0] q1q;
input [9:0] q2q;
input [9:0] q3q;
input [9:0] q4q;
input [9:0] q5q;
input [9:0] q6q;
input [9:0] q7q;
input [8:0] q8q;
input [8:0] c;		// final lerp add
input [8:0] t;		// for mid mode average (1's comp)
input [8:0] o;		// for mid mode average

wire [9:0]  sa;		// intermediate carry save adder sums and carrys
wire [9:0]  ca;
wire [10:0] sb;
wire [9:0]  cb;
wire [10:0] sc;
wire [10:0] cc;
wire [10:0] sd;
wire [9:0]  cd;
wire [10:0] se;
wire [10:0] ce;
wire [10:0] sf;
wire [8:0]  cf;
wire [8:0]  sg;
wire [7:0]  cg;
wire [11:0] sh;
wire [10:0] ch;
wire [11:0] si;
wire [12:0] ci;
wire [12:0] sj;
wire [11:0] cj;
wire [13:0] sk;
wire [12:0] ck;
wire [11:0] sl;
wire [9:0]  cl;
wire [11:0] sm;
wire [9:0]  cm;
wire [10:0] sn;
wire [9:0]  cn;
wire [10:0] so;
wire [9:0]  co;
wire [14:0] sp;
wire [14:0] cp;
wire [13:0] sq;
wire [13:0] cq;
wire [11:0] sr;
wire [8:0]  cr;
wire [11:0] ss;
wire [9:0]  cs;
wire [12:0] st;
wire [12:0] ct;
wire [11:0] su;
wire [11:0] cu;

output [8:0] mp;	// final carry-propagated sum

tf_lerp_csa_fa10 saf (	.ci({a[8],a[8:0]}),
			.b({b[8],b[8:0]}),
			.a(p0p[9:0]),
			.s(sa[9:0]),	.co(ca[9:0]));
					// no half adder bits here
					// no fall-thru bits here
tf_lerp_csa_fa10 sbf (	.ci({q0q[9],q0q[9:1]}),
			.b(p1p[9:0]),
			.a(q1q[9:0]),
			.s(sb[10:1]),	.co(cb[9:0]));
					// no half adder bits here
assign sb[0] = q0q[0];
tf_lerp_csa_fa10 scf (	.ci({p2p[9],p2p[9:1]}),
			.b({q2q[9],q2q[9:1]}),
			.a(p3p[9:0]),
			.s(sc[10:1]),	.co(cc[10:1]));
tf_lerp_csa_ha1  sch (	.a(p2p[0]),
			.b(q2q[0]),
			.s(sc[0]),	.co(cc[0]));
					// no fall-thru bits here
tf_lerp_csa_fa10 sdf (	.ci({q3q[9],q3q[9:1]}),
			.b(p4p[9:0]),
			.a(q4q[9:0]),
			.s(sd[10:1]),	.co(cd[9:0]));
					// no half adder bits here
assign sd[0] = q3q[0];
tf_lerp_csa_fa10 sef (	.ci({p5p[9],p5p[9:1]}),
			.b({q5q[9],q5q[9:1]}),
			.a(p6p[9:0]),
			.s(se[10:1]),	.co(ce[10:1]));
tf_lerp_csa_ha1  seh (	.a(p5p[0]),
			.b(q5q[0]),
			.s(se[0]),	.co(ce[0]));
					// no fall-thru bits here
tf_lerp_csa_faso sfg (	.ci(q6q[9]),	// sum only full adder
			.b(p7p[9]),
			.a(q7q[9]),
			.s(sf[10]));
tf_lerp_csa_fa9  sff (	.ci(q6q[9:1]),
			.b(p7p[8:0]),
			.a(q7q[8:0]),
			.s(sf[9:1]),	.co(cf[8:0]));
					// no half adder bits here
assign sf[0] = q6q[0];
tf_lerp_csa_faso sgg (	.ci(p8p[8]),	// sum only full adder
			.b(q8q[8]),
			.a(c[8]),
			.s(sg[8]));
tf_lerp_csa_fa8  sgf (	.ci(p8p[7:0]),
			.b(q8q[7:0]),
			.a(c[7:0]),
			.s(sg[7:0]),	.co(cg[7:0]));
					// no half adder bits here
tf_lerp_csa_fa10 shf (	.ci({sa[9],sa[9],sa[9:2]}),
			.b({ca[9],ca[9:1]}),
			.a(cb[9:0]),
			.s(sh[11:2]),	.co(ch[10:1]));
tf_lerp_csa_ha1  shh (	.a(sa[1]),
			.b(ca[0]),
			.s(sh[1]),	.co(ch[0]));
assign sh[0] = sa[0];
tf_lerp_csa_fa11 sif (	.ci({sh[11],sh[11:2]}),
			.b(ch[10:0]),
			.a({sb[10],sb[10],sb[10:2]}),
			.s(si[11:1]),	.co(ci[12:2]));
tf_lerp_csa_ha1  sih (	.a(sh[1]),
			.b(sb[1]),
			.s(si[0]),	.co(ci[1]));
tf_lerp_csa_haco cih (	.a(sh[0]),	// carry only half adder
			.b(sb[0]),	.co(ci[0]));
					// no fall-thru bits here
tf_lerp_csa_fa10 sjf (	.ci({sc[10],sc[10],sc[10:3]}),
			.b({cc[10],cc[10:2]}),
			.a(cd[9:0]),
			.s(sj[12:3]),	.co(cj[11:2]));
tf_lerp_csa_ha2  sjh (	.a(sc[2:1]),
			.b(cc[1:0]),
			.s(sj[2:1]),	.co(cj[1:0]));
assign sj[0] = sc[0];
tf_lerp_csa_fa12 skf (	.ci({sj[12],sj[12:2]}),
			.b(cj[11:0]),
			.a({sd[10],sd[10],sd[10:1]}),
			.s(sk[13:2]),	.co(ck[12:1]));
tf_lerp_csa_ha1  skh (	.a(sj[1]),
			.b(sd[0]),
			.s(sk[1]),	.co(ck[0]));
assign sk[0] = sj[0];
tf_lerp_csa_faso slg (	.ci(se[10]),	// sum only full adder
			.b(ce[10]),
			.a(cf[8]),
			.s(sl[11]));
tf_lerp_csa_fa9  slf (	.ci(se[10:2]),
			.b(ce[9:1]),
			.a({cf[7:0],1'b1}),
			.s(sl[10:2]),	.co(cl[9:1]));
tf_lerp_csa_ha1  slh (	.a(se[1]),
			.b(ce[0]),
			.s(sl[1]),	.co(cl[0]));
assign sl[0] = se[0];
tf_lerp_csa_faso smg (	.ci(sl[11]),	// sum only full adder
			.b(cl[9]),
			.a(sf[10]),
			.s(sm[11]));
tf_lerp_csa_fa9  smf (	.ci(sl[10:2]),
			.b(cl[8:0]),
			.a(sf[9:1]),
			.s(sm[10:2]),	.co(cm[9:1]));
tf_lerp_csa_ha1  smh (	.a(sl[1]),
			.b(sf[0]),
			.s(sm[1]),	.co(cm[0]));
assign sm[0] = sl[0];
tf_lerp_csa_faso sng (	.ci(sg[8]),	// sum only full adder
			.b(cg[7]),
			.a(t[8]),
			.s(sn[10]));
tf_lerp_csa_fa8  snf (	.ci(sg[7:0]),
			.b({cg[6:0],1'b1}),
			.a({t[8],t[8:2]}),
			.s(sn[9:2]),	.co(cn[9:2]));
assign cn[1] =  1'b1;			// half add with two 1's
assign sn[1] =  t[1];			// half add with two 1's
assign cn[0] =  t[0];			// half add with 1
assign sn[0] = ~t[0];			// half add with 1
					// no fall-thru bits here
tf_lerp_csa_faso sog (	.ci(sn[10]),	// sum only full adder
			.b(cn[9]),
			.a(o[8]),
			.s(so[10]));
tf_lerp_csa_fa9  sof (	.ci(sn[9:1]),
			.b(cn[8:0]),
			.a({o[8],o[8:1]}),
			.s(so[9:1]),	.co(co[9:1]));
tf_lerp_csa_ha1  soh (	.a(sn[0]),
			.b(o[0]),
			.s(so[0]),	.co(co[0]));
					// no fall-thru bits here
tf_lerp_csa_faso spg (	.ci(si[11]),	// sum only full adder
			.b(ci[12]),
			.a(ck[12]),
			.s(sp[14]));
tf_lerp_csa_fa12 spf (	.ci({{3{si[11]}},si[11:3]}),
			.b({ci[12],ci[12],ci[12:3]}),
			.a(ck[11:0]),
			.s(sp[13:2]),	.co(cp[14:3]));
tf_lerp_csa_ha2  sph (	.a(si[2:1]),
			.b(ci[2:1]),
			.s(sp[1:0]),	.co(cp[2:1]));
tf_lerp_csa_haco cph (	.a(si[0]),	// carry only half adder
			.b(ci[0]),	.co(cp[0]));
					// no fall-thru bits here
tf_lerp_csa_faso sqg (	.ci(sp[14]),	// sum only full adder
			.b(cp[14]),
			.a(sk[13]),
			.s(sq[13]));
tf_lerp_csa_fa13 sqf (	.ci(sp[13:1]),
			.b(cp[13:1]),
			.a(sk[13:1]),
			.s(sq[12:0]),	.co(cq[13:1]));
tf_lerp_csa_faco cqf (	.ci(sp[0]),	// carry only full adder
			.b(cp[0]),
			.a(sk[0]),	.co(cq[0]));
					// no half adder bits here
					// no fall-thru bits here
tf_lerp_csa_faso srg (	.ci(sm[11]),	// sum only full adder
			.b(cm[9]),
			.a(co[9]),
			.s(sr[11]));
tf_lerp_csa_fa9  srf (	.ci(sm[10:2]),
			.b(cm[8:0]),
			.a(co[8:0]),
			.s(sr[10:2]),	.co(cr[8:0]));
					// no half adder bits here
assign sr[1:0] = sm[1:0];
tf_lerp_csa_faso ssg (	.ci(sr[11]),	// sum only full adder
			.b(cr[8]),
			.a(so[10]),
			.s(ss[11]));
tf_lerp_csa_fa8  ssf (	.ci(sr[10:3]),
			.b(cr[7:0]),
			.a(so[9:2]),
			.s(ss[10:3]),	.co(cs[9:2]));
tf_lerp_csa_ha2  ssh (	.a(sr[2:1]),
			.b(so[1:0]),
			.s(ss[2:1]),	.co(cs[1:0]));
assign ss[0] = sr[0];
tf_lerp_csa_faso stg (	.ci(sq[13]),	// sum only full adder
			.b(cq[13]),
			.a(cs[9]),
			.s(st[12]));
tf_lerp_csa_fa9  stf (	.ci(sq[12:4]),
			.b(cq[12:4]),
			.a(cs[8:0]),
			.s(st[11:3]),	.co(ct[12:4]));
tf_lerp_csa_ha3  sth (	.a(sq[3:1]),
			.b(cq[3:1]),
			.s(st[2:0]),	.co(ct[3:1]));
tf_lerp_csa_haco cth (	.a(sq[0]),	// carry only half adder
			.b(cq[0]),	.co(ct[0]));
					// no fall-thru bits here
tf_lerp_csa_faso sug (	.ci(st[12]),	// sum only full adder
			.b(ct[12]),
			.a(ss[11]),
			.s(su[11]));
tf_lerp_csa_fa11 suf (	.ci(st[11:1]),
			.b(ct[11:1]),
			.a(ss[10:0]),
			.s(su[10:0]),	.co(cu[11:1]));
tf_lerp_csa_haco cuh (	.a(st[0]),	// carry only half adder
			.b(ct[0]),	.co(cu[0]));
					// no fall-thru bits here
tf_lerp_csa_add12 mpa (	.b(su[11:0]),	// final carry-propagating adder
			.a(cu[11:0]),
			.s(mp[8:0]));

endmodule // tf_lerp_csa