pg4bt_lt32 i_pg_15_12 ( .gs_3_0(g15_12),
.ps_2_n1(p14_11),
.g_in(gi[15:12]),
.p_in(pi[14:12]),
.pn_3(pi[11]));
pg4bt_lt32 i_pg_11_8 ( .gs_3_0(g11_8),
.ps_2_n1(p10_7),
.g_in(gi[11:8]),
.p_in(pi[10:8]),
.pn_3(pi[7]));
pg4bt_lt32 i_pg_7_4 ( .gs_3_0(g7_4),
.ps_2_n1(p6_3),
.g_in(gi[7:4]),
.p_in(pi[6:4]),
.pn_3(pi[3]));
pg4bt_lt32 i_pgs_3_0 ( .gs_3_0(g3_0),
.ps_2_n1(p2_0),
.g_in(gi[3:0]),
.p_in({pi[2:0]}),
.pn_3(1'b1));
pg2nd_lt32 i_pg_31_16 ( .G_3_0(g31_16),
.P_3_0(p30_15),
.g_in({g31_28,g27_24,g23_20,g19_16}),
.p_in({p30_27,p26_23,p22_19,p18_15}));
pg2nd_lt32 i_pg_15_0 ( .G_3_0(g15_0),
.P_3_0(NC), // .ps_2_n1(p14_0), no connec.
.g_in({g15_12,g11_8,g7_4,g3_0}),
.p_in({p14_11,p10_7,p6_3,p2_0}));
assign a_ltn_b = ~(pi[31] & (g31_16 | p30_15&g15_0)) ; // pg_last to Carry_out
endmodule
![[Up: cmp32_ks_lt i_pg_31_28]](v2html-up.gif)
![[Up: cmp32_ks_lt i_pg_27_24]](v2html-up.gif)
![[Up: cmp32_ks_lt i_pg_23_20]](v2html-up.gif)
![[Up: cmp32_ks_lt i_pg_19_16]](v2html-up.gif)
![[Up: cmp32_ks_lt i_pg_15_12]](v2html-up.gif)
![[Up: cmp32_ks_lt i_pg_11_8]](v2html-up.gif)
![[Up: cmp32_ks_lt i_pg_7_4]](v2html-up.gif)
module pg4bt_lt32
(gs_3_0, ps_2_n1, g_in, p_in, pn_3);
output gs_3_0
; // carry_generated.
output ps_2_n1
; // carry_propgated. lower 1-bit
input [3:0] g_in
; // generate inputs.
input [2:0] p_in
; // propgate inputs. lower 1-bit
input pn_3
; // next lower bit prop input.
/* or use this Brent-Kung stage, Ling's mods to save gates:*/
assign gs_3_0 = g_in[3] // Pseudo Generate
| g_in[2]
| p_in[2] & g_in[1]
| p_in[2] & p_in[1] & g_in[0] ;
assign ps_2_n1 = p_in[2] & p_in[1] & p_in[0] & pn_3 ; // Pseudo Prop.
/* conventional approach uses much more gates
assign G_3_0 = gi[3] // conventional g.
| pi[3] & gi[2]
| pi[3] & pi[2] & gi[1]
| pi[3] & pi[2] & pi[1] & gi[0] ;
assign P_3_0 = pi[3] & pi[2] & pi[1] & pi[0] ; // all prop.
*/
endmodule
![[Up: cmp32_ks_lt i_pg_31_16]](v2html-up.gif)
module pg2nd_lt32
(G_3_0, P_3_0, g_in, p_in);
output G_3_0
; // carry_generated.
output P_3_0
; // carry_propgated. lower 1-bit
input [3:0] g_in
; // generate inputs.
input [3:0] p_in
; // propgate inputs. lower 1-bit
/* conventional approach must be used at second level */
assign G_3_0 = g_in[3] // conventional g.
| p_in[3] & g_in[2]
| p_in[3] & p_in[2] & g_in[1]
| p_in[3] & p_in[2] & p_in[1] & g_in[0] ;
assign P_3_0 = p_in[3] & p_in[2] & p_in[1] & p_in[0] ; // all prop.
endmodule
/*******************************************************************************
*
* 16) Module: cmp_legs_32
*
* This module contains the 32-bit comparator that can handle both signed
* and unsigned comparisons.
*
******************************************************************************/
module cmp_legs_32
(gt,
eq,
lt,
in1,
in2,
sign);
input [31:0] in1
; // Operand on the LHS to be compared
input [31:0] in2
; // Operand on the RHS to be compared
input sign
; // 0: unsigned comparison, 1: signed comparison
output gt
; // in1 > in2
output eq
; // in1 == in2
output lt
; // in1 < in2
wire msel
, lt1
, eq1
, gt1
;
/*
reg cmp_gt; // Intermediate result, in1 > in2
reg cmp_eq; // Intermediate result, in1 == in2
reg cmp_lt; // Intermediate result, in1 < in2
reg [31:0] tmp1; // 2's complement of in1
reg [31:0] tmp2; // 2's complement of in2
always @(in1 or in2 or sign)
begin
if (sign == 0)
begin
cmp_gt = (in1 > in2);
cmp_eq = (in1 == in2);
cmp_lt = (in1 < in2);
end // if (sign == 0)
else
begin
case ({in1[31], in2[31]})
2'b00:
begin
cmp_gt = (in1 > in2);
cmp_eq = (in1 == in2);
cmp_lt = (in1 < in2);
end // case: 2'b00
2'b01:
begin
cmp_gt = 1;
cmp_eq = 0;
cmp_lt = 0;
end // case: 2'b01
2'b10:
begin
cmp_gt = 0;
cmp_eq = 0;
cmp_lt = 1;
end // case: 2'b10
2'b11:
begin
tmp1 = (~in1) + 1;
tmp2 = (~in2) + 1;
cmp_gt = (tmp1 < tmp2);
cmp_eq = (in1 == in2);
cmp_lt = (tmp1 > tmp2);
end // case: 2'b11
endcase // case({in1[31], in2[31]})
end // else: !if(sign == 0)
end // always @ (in1 or in2 or sign)
assign gt = cmp_gt;
assign eq = cmp_eq;
assign lt = cmp_lt;
*/
assign msel = ( ~sign | ~(in1[31] ^ in2[31]) );
cmp3s_32_leg comp_32_leg (.ai(in1), .bi(in2), .a_ltn_b(lt1), .a_eql_b(eq1), .a_gtn_b(gt1)
);
mj_h_mux2_3 res_mux ( .mx_out({lt,eq,gt}),
.in0({in1[31],1'b0,in2[31]}),
.in1({lt1,eq1,gt1}),
.sel(msel),
.sel_l(~msel)
);
endmodule // cmp_32
/*******************************************************************************
*
* 17) Module: shift_64
*
* This module contains the 64-bit shifter that handles:
* 1. Left shift
* 2. Right logical shift
* 3. Right arithmetic shift
*
******************************************************************************/
module shift_64
(msw_in,
lsw_in,
count,
dir,
arith,
word_sel,
out);
input [31:0] msw_in
; // MSW of the operand, or [63:32]
input [31:0] lsw_in
; // LSW of the operand, or [31:0]
input [5:0] count
; // 6-bit shift count
input dir
; // 0: shift left, 1: shift right
input arith
; // 0: logical, 1: arithmetic
input word_sel
; // 0: LSW, 1: MSW
output [31:0] out
; // 32-bit result
wire sgn
;
wire[5:0] mux_sel
;
/*
reg [127:0] src_bus; // 128-bit source bus
reg [127:0] dst_bus; // 128-bit destination bus
reg [63:0] result; // 64-bit output of the shifter
// This is just a behavioral implementation.
always @(msw_in or lsw_in or count or dir or arith or word_sel)
begin
if (dir == 0)
begin
src_bus = {msw_in, lsw_in, 64'h0};
dst_bus = src_bus << count;
result = dst_bus[127:64];
end // if (dir == 0)
else
begin
if (arith == 1)
src_bus[127:64] = {64{msw_in[31]}};
else
src_bus[127:64] = 64'h0;
src_bus[63:0] = {msw_in, lsw_in};
dst_bus = src_bus >> count;
result = dst_bus[63:0];
end // else: !if(dir == 0)
end // always @ (msw_in or lsw_in or count or dir or arith or word_sel)
*/
wire [63:0] lev_0
; // level_0 32-bit 2:1 mux output
wire [63:0] lev_1
; // level_1 32-bit 2:1 mux output
wire [63:0] lev_2
; // level_2 32-bit 2:1 mux output
wire [63:0] lev_3
; // level_3 32-bit 2:1 mux output
wire [63:0] lev_4
; // level_4 32-bit 2:1 mux output
wire [63:0] lev_5
; // level_5 32-bit 2:1 mux output
wire [63:0] lev_6
;
wire [63:0] result
; // level_5 32-bit 2:1 mux output
wire [63:0] sft_in
,rev_sft_in
,rev_lev_6
;
assign sgn = dir & arith & msw_in[31];
assign sft_in = {msw_in,lsw_in};
assign mux_sel = ~count;
mx21_64_l mx_0(.mx_out(lev_0), .sel(~dir), .in0(sft_in[63:0]),
.in1(rev_sft_in[63:0]) );
assign rev_sft_in = {
sft_in[0],sft_in[1],sft_in[2],sft_in[3],sft_in[4],sft_in[5],sft_in[6],sft_in[7],
sft_in[8],sft_in[9],sft_in[10],sft_in[11],sft_in[12],sft_in[13],sft_in[14],sft_in[15],
sft_in[16], sft_in[17], sft_in[18], sft_in[19], sft_in[20], sft_in[21], sft_in[22], sft_in[23], sft_in[24], sft_in[25], sft_in[26],sft_in[27], sft_in[28], sft_in[29],
sft_in[30], sft_in[31], sft_in[32] , sft_in[33], sft_in[34] , sft_in[35], sft_in[36], sft_in[37], sft_in[38], sft_in[39],sft_in[40], sft_in[41], sft_in[42], sft_in[43],
sft_in[44], sft_in[45], sft_in[46], sft_in[47], sft_in[48], sft_in[49],
sft_in[50], sft_in[51], sft_in[52], sft_in[53], sft_in[54], sft_in[55], sft_in[56], sft_in[57], sft_in[58], sft_in[59],sft_in[60], sft_in[61], sft_in[62], sft_in[63] } ;
mx21_64_l mx_1 (.mx_out(lev_1), .sel(mux_sel[5]), .in0({{32{~sgn}},lev_0[63:32]}),
.in1(lev_0[63:0]) );
mx21_64_l mx_2 (.mx_out(lev_2), .sel(mux_sel[4]), .in0({{16{sgn}},lev_1[63:16]}),
.in1(lev_1[63:0]) );
mx21_64_l mx_3(.mx_out(lev_3), .sel(mux_sel[3]), .in0({{ 8{~sgn}},lev_2[63: 8]}),
.in1(lev_2[63:0]) );
mx21_64_l mx_4(.mx_out(lev_4), .sel(mux_sel[2]), .in0({{ 4{sgn}},lev_3[63: 4]}),
.in1(lev_3[63:0]) );
mx21_64_l mx_5(.mx_out(lev_5), .sel(mux_sel[1]), .in0({{2{~sgn}},lev_4[63:2]}),
.in1(lev_4[63:0]) );
mx21_64_l mx_6(.mx_out(lev_6), .sel(mux_sel[0]), .in0({{1{sgn}},lev_5[63:1]}),
.in1(lev_5[63:0]) );
mx21_64_l mx_7(.mx_out(result), .sel(~dir), .in0(lev_6[63:0]),
.in1(rev_lev_6[63:0]) );
assign rev_lev_6 = { lev_6[0],lev_6[1],lev_6[2],lev_6[3],lev_6[4],lev_6[5],lev_6[6],lev_6[7],
lev_6[8],lev_6[9],lev_6[10],lev_6[11],lev_6[12],lev_6[13],lev_6[14],lev_6[15],
lev_6[16],lev_6[17],lev_6[18],lev_6[19],lev_6[20],lev_6[21],lev_6[22],lev_6[23],
lev_6[24],lev_6[25],lev_6[26],lev_6[27],lev_6[28],lev_6[29],lev_6[30],lev_6[31],
lev_6[32],lev_6[33],lev_6[34],lev_6[35],lev_6[36],lev_6[37],lev_6[38],lev_6[39],
lev_6[40],lev_6[41],lev_6[42],lev_6[43],lev_6[44],lev_6[45],lev_6[46],lev_6[47],
lev_6[48],lev_6[49],lev_6[50],lev_6[51],lev_6[52],lev_6[53],lev_6[54],lev_6[55],
lev_6[56],lev_6[57],lev_6[58],lev_6[59],lev_6[60],lev_6[61],lev_6[62],lev_6[63] };
assign out = (word_sel == 1'b0) ? result[31:0] : result[63:32];
endmodule // shift_64
![[Up: shift_64 mx_0]](v2html-up.gif)
![[Up: shift_64 mx_1]](v2html-up.gif)
![[Up: shift_64 mx_2]](v2html-up.gif)
![[Up: shift_64 mx_3]](v2html-up.gif)
![[Up: shift_64 mx_4]](v2html-up.gif)
![[Up: shift_64 mx_5]](v2html-up.gif)
![[Up: shift_64 mx_6]](v2html-up.gif)
module mx21_64_l
(mx_out, sel, in0, in1);
output [63:0] mx_out
;
input sel
;
input [63:0] in0
, in1
;
wire [63:0] sel_not
, mux_sel
;
assign sel_not = {64{~sel}};
assign mux_sel = {64{ sel}};
assign mx_out = ~(mux_sel & in1 | sel_not & in0) ;
endmodule
// ------------------- 18) 8-bit adder --------------------------
module fa8
(a, b, c, sum, cout);
input [7:0] a
;
input [7:0] b
;
output [7:0] sum
;
input c
; // carry in
output cout
; // carry out
// -------------------- carry tree level 1 ----------------------------
// produce the generate for the least significant bit (sch: glsbs)
wire g0_l
= !(((a[0] | b[0]) & c) | (a[0] &b[0]));
// produce the propagates and generates for the other bits
wire gen0_l
, p0_l
, g1_l
, p1_l
, g2_l
, p2_l
, g3_l
, p3_l
, g4_l
, p4_l
,
g5_l
, p5_l
, g6_l
, p6_l
, g7_l
, p7_l
;
pgnx_fa8 pgnx0 (a[0], b[0], gen0_l, p0_l); // gen0_l is used only for sum[0] calc.
pgnx_fa8 pgnx1 (a[1], b[1], g1_l, p1_l);
pgnx_fa8 pgnx2 (a[2], b[2], g2_l, p2_l);
pgnx_fa8 pgnx3 (a[3], b[3], g3_l, p3_l);
pgnx_fa8 pgnx4 (a[4], b[4], g4_l, p4_l);
pgnx_fa8 pgnx5 (a[5], b[5], g5_l, p5_l);
pgnx_fa8 pgnx6 (a[6], b[6], g6_l, p6_l);
pgnx_fa8 pgnx7 (a[7], b[7], g7_l, p7_l);
// -------------------- carry tree level 2 ----------------------------
// produce group propagates/generates for sets of 2 bits (sch: pg2l)
// this stage contains the ling modification, which simplifies
// this stage, but the outputs are Pseudo-generates, which
// later need to be recovered by anding.
wire g0to1
, g1to2
, g2to3
, g4to5
, g6to7
, p0to1
, p1to2
, p3to4
, p5to6
;
pg2lg_fa8 pg2lg ( .gd_l(g0_l),
.gu_l(g1_l),
.g(g0to1)); //assign g0to1 = !(g0_l & g1_l);
pg2l_fa8 p2gl0 ( .gd_l(g1_l),
.gu_l(g2_l),
.pd_l(p0_l),
.pu_l(p1_l),
.g(g1to2), //assign g1to2 = !(g1_l & g2_l);
.p(p0to1)); //assign p0to1 = !(p0_l | p1_l);
pg2l_fa8 p2gl1 ( .gd_l(g2_l),
.gu_l(g3_l),
.pd_l(p1_l),
.pu_l(p2_l),
.g(g2to3), //assign g2to3 = !(g2_l & g3_l);
.p(p1to2)); //assign p1to2 = !(p1_l | p2_l);
pg2l_fa8 p2gl2 ( .gd_l(g4_l),
.gu_l(g5_l),
.pd_l(p3_l),
.pu_l(p4_l),
.g(g4to5), //assign g4to5 = !(g4_l & g5_l);
.p(p3to4)); //assign p3to4 = !(p3_l | p4_l);
pg2l_fa8 p2gl3 ( .gd_l(g6_l),
.gu_l(g7_l),
.pd_l(p5_l),
.pu_l(p6_l),
.g(g6to7),
.p(p5to6));
// -------------------- carry tree level 3 ----------------------------
// use aoi to make group generates
wire g0to2_l
, g0to3_l
, g2to5_l
, g4to7_l
, p1to4_l
, p3to6_l
;
aoig_fa8 aoig0 ( .gd(~g0_l),
.gu(g1to2),
.pu(p0to1),
.g_l(g0to2_l)); //assign g0to2_l = !((!g0_l & p0to1) | g1to2);
aoig_fa8 aoig1 ( .gd(g0to1),
.gu(g2to3),
.pu(p1to2),
.g_l(g0to3_l)); //assign g0to3_l = !((g0to1 & p1to2) | g2to3);
baoi_fa8 baoi0 ( .gd(g2to3),
.gu(g4to5),
.pd(p1to2),
.pu(p3to4),
.g_l(g2to5_l), //assign g2to5_l = !((g2to3 & p3to4) | g4to5);
.p_l(p1to4_l)); //assign p1to4_l = !(p1to2 & p3to4);
baoi_fa8 baoi1 ( .gd(g4to5),
.gu(g6to7),
.pd(p3to4),
.pu(p5to6),
.g_l(g4to7_l),
.p_l(p3to6_l));
// -------------------- carry tree level 4 ----------------------------
// use oai's since the inputs are active-low.
wire g0to5
, g0to7
;
oaig_fa8 oaig0 ( .gd_l(~g0to1),
.gu_l(g2to5_l),
.pu_l(p1to4_l),
.g(g0to5)); //assign g0to5 = !((!g0to1 | p1to4_l) & g2to5_l);
oaig_fa8 oaig1 ( .gd_l(g0to3_l),
.gu_l(g4to7_l),
.pu_l(p3to6_l),
.g(g0to7));
// -------------------- sum, and cout ----------------------------
assign cout = g0to7 & !p7_l; // recover cout by anding p7 with the pseudo-generate
wire [7:0] suma
, sumb
; // local sums before carry select mux
sum2_fa8 sum0to1 (.g1(~gen0_l), .g2(~g1_l),
.p0(1'b1), .p1(~p0_l), .p2(~p1_l),
.sum1a(suma[0]), .sum2a(suma[1]),
.sum1b(sumb[0]), .sum2b(sumb[1]));
sum2_fa8 sum2to3 (.g1(~g2_l), .g2(~g3_l),
.p0(~p1_l), .p1(~p2_l), .p2(~p3_l),
.sum1a(suma[2]), .sum2a(suma[3]),
.sum1b(sumb[2]), .sum2b(sumb[3]));
sum2_fa8 sum4to5 (.g1(~g4_l), .g2(~g5_l),
.p0(~p3_l), .p1(~p4_l), .p2(~p5_l),
.sum1a(suma[4]), .sum2a(suma[5]),
.sum1b(sumb[4]), .sum2b(sumb[5]));
sum2_fa8 sum6to7 (.g1(~g6_l), .g2(~g7_l),
.p0(~p5_l), .p1(~p6_l), .p2(~p7_l),
.sum1a(suma[6]), .sum2a(suma[7]),
.sum1b(sumb[6]), .sum2b(sumb[7]));
/********** mux to select sum using G* signals from carry tree *****/
selsum2_fa8 selsum0to1 ( .sum1a(suma[0]), .sum2a(suma[1]),
.sum1b(sumb[0]), .sum2b(sumb[1]),
.sel(c),
.sum1(sum[0]), .sum2(sum[1]));
selsum2_fa8 selsum2to3 ( .sum1a(suma[2]), .sum2a(suma[3]),
.sum1b(sumb[2]), .sum2b(sumb[3]),
.sel(g0to1),
.sum1(sum[2]), .sum2(sum[3]));
selsum2_fa8 selsum4to5 ( .sum1a(suma[4]), .sum2a(suma[5]),
.sum1b(sumb[4]), .sum2b(sumb[5]),
.sel(~g0to3_l),
.sum1(sum[4]), .sum2(sum[5]));
selsum2_fa8 selsum6to7 ( .sum1a(suma[6]), .sum2a(suma[7]),
.sum1b(sumb[6]), .sum2b(sumb[7]),
.sel(g0to5),
.sum1(sum[6]), .sum2(sum[7]));
endmodule
// -------------------- selsum2 -----------------------
// new module just to make synopsys synthesize with a mux at end
![[Up: fa8 selsum0to1]](v2html-up.gif)
![[Up: fa8 selsum2to3]](v2html-up.gif)
![[Up: fa8 selsum4to5]](v2html-up.gif)
module selsum2_fa8
(sel, sum1, sum2,
sum1a, sum2a,
sum1b, sum2b);
input sum1a
, sum2a
,
sum1b
, sum2b
, sel
;
output sum1
, sum2
;
wire sum1, sum2;
assign sum1 = sel ? sum1a : sum1b;
assign sum2 = sel ? sum2a : sum2b;
endmodule
// -------------------- sum ----------------------------
// we need to recover the real gernerates
// after the ling modification used in level 2.
// we also are replacing the a,b with p,g to reduce loading
// of the a,b inputs. (a ^ b = p & !g)
// send out two sets of sums to be selected with mux at last stage
![[Up: fa8 sum0to1]](v2html-up.gif)
![[Up: fa8 sum2to3]](v2html-up.gif)
![[Up: fa8 sum4to5]](v2html-up.gif)
module sum2_fa8
(g1, g2, p0, p1, p2,
sum1a, sum2a,
sum1b, sum2b);
output sum1a
, sum2a
,
sum1b
, sum2b
; // sum outputs.
input g1
, g2
; // individual generate inputs.
input p0
, p1
, p2
; // individual propagate inputs.
//input G; // global carry input. (pseudo-generate)
wire sum1a, sum2a,
sum1b, sum2b;
assign sum1a = (p1 & (~g1)) ^ p0;
assign sum2a = (p2 & (~g2)) ^ (g1 | (p1 & p0));
assign sum1b = p1 & (~g1);
assign sum2b = (p2 & (~g2)) ^ g1;
endmodule
// -------------------- pgnx ----------------------------
![[Up: fa8 pgnx0]](v2html-up.gif)
![[Up: fa8 pgnx1]](v2html-up.gif)
![[Up: fa8 pgnx2]](v2html-up.gif)
![[Up: fa8 pgnx3]](v2html-up.gif)
![[Up: fa8 pgnx4]](v2html-up.gif)
![[Up: fa8 pgnx5]](v2html-up.gif)
![[Up: fa8 pgnx6]](v2html-up.gif)
module pgnx_fa8
(a, b, g_l, p_l); // level 1 propagate and generate signals
input a
, b
;
output g_l
, p_l
;
assign g_l = !(a & b); //nand to make initial generate
assign p_l = !(a | b); //nor to make initial propagate
endmodule
// -------------------- pg2lg ----------------------------
// ling modification stage, generate only
module pg2lg_fa8
(gd_l, gu_l, g);
input gd_l
, gu_l
;
output g
;
assign g = !(gd_l & gu_l); //nand to make pseudo generate
endmodule
// -------------------- pg2l ----------------------------
// ling modification stage, psuedo group generate and propagate
![[Up: fa8 p2gl0]](v2html-up.gif)
![[Up: fa8 p2gl1]](v2html-up.gif)
![[Up: fa8 p2gl2]](v2html-up.gif)
module pg2l_fa8
(gd_l, gu_l, pd_l, pu_l, g, p);
input gd_l
, gu_l
, pd_l
, pu_l
;
output g
, p
;
assign g = !(gd_l & gu_l); //nand to make pseudo generate
assign p = !(pd_l | pu_l); //nor to make pseudo generate
endmodule
// -------------------- aoig ----------------------------
// aoi for carry tree generates
![[Up: fa8 aoig0]](v2html-up.gif)
module aoig_fa8
(gd, gu, pu, g_l);
input gd
, gu
, pu
;
output g_l
;
assign g_l = ~((gd & pu) | gu); //aoi to make group generate
endmodule
// -------------------- oaig ----------------------------
// aoi for carry tree generates
![[Up: fa8 oaig0]](v2html-up.gif)
module oaig_fa8
(gd_l, gu_l, pu_l, g);
input gd_l
, gu_l
, pu_l
;
output g
;
assign g = ~((gd_l | pu_l) & gu_l); //aoi to make group generate
endmodule
// -------------------- baoi ----------------------------
// aoi for carry tree generates + logic for propagate
![[Up: fa8 baoi0]](v2html-up.gif)
module baoi_fa8
(gd, gu, pd, pu, g_l, p_l);
input gd
, gu
, pd
, pu
;
output g_l
, p_l
;
assign g_l = ~((gd & pu) | gu); //aoi to make group generate
assign p_l = ~(pd & pu); // nand to make group prop
endmodule
// ------------------- 19) 10-bit adder --------------------------
module fa10
(a, b, c, sum, cout);
input [9:0] a
;
input [9:0] b
;
output [9:0] sum
;
input c
; // carry in
output cout
; // carry out
// -------------------- carry tree level 1 ----------------------------
// produce the generate for the least significant bit (sch: glsbs)
wire g0_l
= !(((a[0] | b[0]) & c) | (a[0] &b[0]));
// produce the propagates and generates for the other bits
wire gen0_l
, p0_l
, g1_l
, p1_l
, g2_l
, p2_l
, g3_l
, p3_l
, g4_l
, p4_l
,
g5_l
, p5_l
, g6_l
, p6_l
, g7_l
, p7_l
, g8_l
, p8_l
, g9_l
, p9_l
;
pgnx_fa10 pgnx0 (a[0], b[0], gen0_l, p0_l); // gen0_l is used only for sum[0] calc.
pgnx_fa10 pgnx1 (a[1], b[1], g1_l, p1_l);
pgnx_fa10 pgnx2 (a[2], b[2], g2_l, p2_l);
pgnx_fa10 pgnx3 (a[3], b[3], g3_l, p3_l);
pgnx_fa10 pgnx4 (a[4], b[4], g4_l, p4_l);
pgnx_fa10 pgnx5 (a[5], b[5], g5_l, p5_l);
pgnx_fa10 pgnx6 (a[6], b[6], g6_l, p6_l);
pgnx_fa10 pgnx7 (a[7], b[7], g7_l, p7_l);
pgnx_fa10 pgnx8 (a[8], b[8], g8_l, p8_l);
pgnx_fa10 pgnx9 (a[9], b[9], g9_l, p9_l);
// -------------------- carry tree level 2 ----------------------------
// produce group propagates/generates for sets of 2 bits (sch: pg2l)
// this stage contains the ling modification, which simplifies
// this stage, but the outputs are Pseudo-generates, which
// later need to be recovered by anding.
wire g0to1
, g1to2
, g2to3
, g4to5
, g6to7
, g8to9
, p0to1
, p1to2
, p3to4
,
p5to6
, p7to8
;
pg2lg_fa10 pg2lg ( .gd_l(g0_l),
.gu_l(g1_l),
.g(g0to1)); //assign g0to1 = !(g0_l & g1_l);
pg2l_fa10 p2gl0 ( .gd_l(g1_l),
.gu_l(g2_l),
.pd_l(p0_l),
.pu_l(p1_l),
.g(g1to2), //assign g1to2 = !(g1_l & g2_l);
.p(p0to1)); //assign p0to1 = !(p0_l | p1_l);
pg2l_fa10 p2gl1 ( .gd_l(g2_l),
.gu_l(g3_l),
.pd_l(p1_l),
.pu_l(p2_l),
.g(g2to3), //assign g2to3 = !(g2_l & g3_l);
.p(p1to2)); //assign p1to2 = !(p1_l | p2_l);
pg2l_fa10 p2gl2 ( .gd_l(g4_l),
.gu_l(g5_l),
.pd_l(p3_l),
.pu_l(p4_l),
.g(g4to5), //assign g4to5 = !(g4_l & g5_l);
.p(p3to4)); //assign p3to4 = !(p3_l | p4_l);
pg2l_fa10 p2gl3 ( .gd_l(g6_l),
.gu_l(g7_l),
.pd_l(p5_l),
.pu_l(p6_l),
.g(g6to7),
.p(p5to6));
pg2l_fa10 p2gl4 ( .gd_l(g8_l),
.gu_l(g9_l),
.pd_l(p7_l),
.pu_l(p8_l),
.g(g8to9),
.p(p7to8));
// -------------------- carry tree level 3 ----------------------------
// use aoi to make group generates
wire g0to3_l
, g2to5_l
, g4to7_l
, g6to9_l
, p1to4_l
, p3to6_l
, p5to8_l
;
aoig_fa10 aoig1 ( .gd(g0to1),
.gu(g2to3),
.pu(p1to2),
.g_l(g0to3_l)); //assign g0to3_l = !((g0to1 & p1to2) | g2to3);
baoi_fa10 baoi0 ( .gd(g2to3),
.gu(g4to5),
.pd(p1to2),
.pu(p3to4),
.g_l(g2to5_l), //assign g2to5_l = !((g2to3 & p3to4) | g4to5);
.p_l(p1to4_l)); //assign p1to4_l = !(p1to2 & p3to4);
baoi_fa10 baoi1 ( .gd(g4to5),
.gu(g6to7),
.pd(p3to4),
.pu(p5to6),
.g_l(g4to7_l),
.p_l(p3to6_l));
baoi_fa10 baoi2 ( .gd(g6to7),
.gu(g8to9),
.pd(p5to6),
.pu(p7to8),
.g_l(g6to9_l),
.p_l(p5to8_l));
// -------------------- carry tree level 4 ----------------------------
// use oai's since the inputs are active-low.
wire g0to5
, g0to7
, g2to9
, p1to8
;
oaig_fa10 oaig0 ( .gd_l(~g0to1),
.gu_l(g2to5_l),
.pu_l(p1to4_l),
.g(g0to5)); //assign g0to5 = !((!g0to1 | p1to4_l) & g2to5_l);
oaig_fa10 oaig1 ( .gd_l(g0to3_l),
.gu_l(g4to7_l),
.pu_l(p3to6_l),
.g(g0to7));
boai_fa10 boai0 ( .gd_l(g2to5_l),
.gu_l(g6to9_l),
.pd_l(p1to4_l),
.pu_l(p5to8_l),
.g(g2to9),
.p(p1to8));
// -------------------- carry tree level 5 ----------------------------
// use aoi's to make group generates
wire g0to9_l
;
aoig_fa10 aoiglev5 ( .gd(g0to1),
.gu(g2to9),
.pu(p1to8),
.g_l(g0to9_l));
// -------------------- sum, and cout ----------------------------
assign cout = !g0to9_l & !p9_l; // recover cout by anding p9 with the pseudo-generate
wire [9:0] suma
, sumb
; // local sums before carry select mux
sum2_fa10 sum0to1 (.g1(~gen0_l), .g2(~g1_l),
.p0(1'b1), .p1(~p0_l), .p2(~p1_l),
.sum1a(suma[0]), .sum2a(suma[1]),
.sum1b(sumb[0]), .sum2b(sumb[1]));
sum2_fa10 sum2to3 (.g1(~g2_l), .g2(~g3_l),
.p0(~p1_l), .p1(~p2_l), .p2(~p3_l),
.sum1a(suma[2]), .sum2a(suma[3]),
.sum1b(sumb[2]), .sum2b(sumb[3]));
sum2_fa10 sum4to5 (.g1(~g4_l), .g2(~g5_l),
.p0(~p3_l), .p1(~p4_l), .p2(~p5_l),
.sum1a(suma[4]), .sum2a(suma[5]),
.sum1b(sumb[4]), .sum2b(sumb[5]));
sum2_fa10 sum6to7 (.g1(~g6_l), .g2(~g7_l),
.p0(~p5_l), .p1(~p6_l), .p2(~p7_l),
.sum1a(suma[6]), .sum2a(suma[7]),
.sum1b(sumb[6]), .sum2b(sumb[7]));
sum2_fa10 sum8to9 (.g1(~g8_l), .g2(~g9_l),
.p0(~p7_l), .p1(~p8_l), .p2(~p9_l),
.sum1a(suma[8]), .sum2a(suma[9]),
.sum1b(sumb[8]), .sum2b(sumb[9]));
/********** mux to select sum using G* signals from carry tree *****/
selsum2_fa10 selsum0to1 ( .sum1a(suma[0]), .sum2a(suma[1]),
.sum1b(sumb[0]), .sum2b(sumb[1]),
.sel(c),
.sum1(sum[0]), .sum2(sum[1]));
selsum2_fa10 selsum2to3 ( .sum1a(suma[2]), .sum2a(suma[3]),
.sum1b(sumb[2]), .sum2b(sumb[3]),
.sel(g0to1),
.sum1(sum[2]), .sum2(sum[3]));
selsum2_fa10 selsum4to5 ( .sum1a(suma[4]), .sum2a(suma[5]),
.sum1b(sumb[4]), .sum2b(sumb[5]),
.sel(~g0to3_l),
.sum1(sum[4]), .sum2(sum[5]));
selsum2_fa10 selsum6to7 ( .sum1a(suma[6]), .sum2a(suma[7]),
.sum1b(sumb[6]), .sum2b(sumb[7]),
.sel(g0to5),
.sum1(sum[6]), .sum2(sum[7]));
selsum2_fa10 selsum8to9 ( .sum1a(suma[8]), .sum2a(suma[9]),
.sum1b(sumb[8]), .sum2b(sumb[9]),
.sel(g0to7),
.sum1(sum[8]), .sum2(sum[9]));
endmodule
// -------------------- selsum2 -----------------------
// new module just to make synopsys synthesize with a mux at end
![[Up: fa10 selsum0to1]](v2html-up.gif)
![[Up: fa10 selsum2to3]](v2html-up.gif)
![[Up: fa10 selsum4to5]](v2html-up.gif)
![[Up: fa10 selsum6to7]](v2html-up.gif)
module selsum2_fa10
(sel, sum1, sum2,
sum1a, sum2a,
sum1b, sum2b);
input sum1a
, sum2a
,
sum1b
, sum2b
, sel
;
output sum1
, sum2
;
wire sum1, sum2;
assign sum1 = sel ? sum1a : sum1b;
assign sum2 = sel ? sum2a : sum2b;
endmodule
// -------------------- sum ----------------------------
// we need to recover the real gernerates
// after the ling modification used in level 2.
// we also are replacing the a,b with p,g to reduce loading
// of the a,b inputs. (a ^ b = p & !g)
// send out two sets of sums to be selected with mux at last stage
![[Up: fa10 sum0to1]](v2html-up.gif)
![[Up: fa10 sum2to3]](v2html-up.gif)
![[Up: fa10 sum4to5]](v2html-up.gif)
![[Up: fa10 sum6to7]](v2html-up.gif)
module sum2_fa10
(g1, g2, p0, p1, p2,
sum1a, sum2a,
sum1b, sum2b);
output sum1a
, sum2a
,
sum1b
, sum2b
; // sum outputs.
input g1
, g2
; // individual generate inputs.
input p0
, p1
, p2
; // individual propagate inputs.
//input G; // global carry input. (pseudo-generate)
wire sum1a, sum2a,
sum1b, sum2b;
assign sum1a = (p1 & (~g1)) ^ p0;
assign sum2a = (p2 & (~g2)) ^ (g1 | (p1 & p0));
assign sum1b = p1 & (~g1);
assign sum2b = (p2 & (~g2)) ^ g1;
endmodule
// -------------------- pgnx ----------------------------
![[Up: fa10 pgnx0]](v2html-up.gif)
![[Up: fa10 pgnx1]](v2html-up.gif)
![[Up: fa10 pgnx2]](v2html-up.gif)
![[Up: fa10 pgnx3]](v2html-up.gif)
![[Up: fa10 pgnx4]](v2html-up.gif)
![[Up: fa10 pgnx5]](v2html-up.gif)
![[Up: fa10 pgnx6]](v2html-up.gif)
![[Up: fa10 pgnx7]](v2html-up.gif)
![[Up: fa10 pgnx8]](v2html-up.gif)
module pgnx_fa10
(a, b, g_l, p_l); // level 1 propagate and generate signals
input a
, b
;
output g_l
, p_l
;
assign g_l = !(a & b); //nand to make initial generate
assign p_l = !(a | b); //nor to make initial propagate
endmodule
// -------------------- pg2lg ----------------------------
// ling modification stage, generate only
module pg2lg_fa10
(gd_l, gu_l, g);
input gd_l
, gu_l
;
output g
;
assign g = !(gd_l & gu_l); //nand to make pseudo generate
endmodule
// -------------------- pg2l ----------------------------
// ling modification stage, psuedo group generate and propagate
![[Up: fa10 p2gl0]](v2html-up.gif)
![[Up: fa10 p2gl1]](v2html-up.gif)
![[Up: fa10 p2gl2]](v2html-up.gif)
![[Up: fa10 p2gl3]](v2html-up.gif)
module pg2l_fa10
(gd_l, gu_l, pd_l, pu_l, g, p);
input gd_l
, gu_l
, pd_l
, pu_l
;
output g
, p
;
assign g = !(gd_l & gu_l); //nand to make pseudo generate
assign p = !(pd_l | pu_l); //nor to make pseudo generate
endmodule
// -------------------- aoig ----------------------------
// aoi for carry tree generates
![[Up: fa10 aoig1]](v2html-up.gif)
module aoig_fa10
(gd, gu, pu, g_l);
input gd
, gu
, pu
;
output g_l
;
assign g_l = ~((gd & pu) | gu); //aoi to make group generate
endmodule
// -------------------- oaig ----------------------------
// aoi for carry tree generates
![[Up: fa10 oaig0]](v2html-up.gif)
module oaig_fa10
(gd_l, gu_l, pu_l, g);
input gd_l
, gu_l
, pu_l
;
output g
;
assign g = ~((gd_l | pu_l) & gu_l); //aoi to make group generate
endmodule
// -------------------- baoi ----------------------------
// aoi for carry tree generates + logic for propagate
![[Up: fa10 baoi0]](v2html-up.gif)
![[Up: fa10 baoi1]](v2html-up.gif)
module baoi_fa10
(gd, gu, pd, pu, g_l, p_l);
input gd
, gu
, pd
, pu
;
output g_l
, p_l
;
assign g_l = ~((gd & pu) | gu); //aoi to make group generate
assign p_l = ~(pd & pu); // nand to make group prop
endmodule
// -------------------- boai ----------------------------
// aoi for carry tree generates
module boai_fa10
(gd_l, gu_l, pd_l, pu_l, g, p);
input gd_l
, gu_l
, pu_l
, pd_l
;
output g
, p
;
assign g = ~((gd_l | pu_l) & gu_l); //aoi to make group generate
assign p = ~(pu_l | pd_l); // nor to make group prop
endmodule
// -------------------20) 6-bit decrementer --------------------------
module dec6
(data, sum);
input [5:0] data
;
output [5:0] sum
;
wire p0
, p0to1
, p0to2
, p0to3
, p0to4
;
assign p0 = data[0];
assign p0to1 = data[0] | data[1];
assign p0to2 = data[0] | data[1] | data[2];
assign p0to3 = data[0] | data[1] | data[2] | data[3];
assign p0to4 = data[0] | data[1] | data[2] | data[3] | data[4];
assign sum[0] = ~data[0];
assign sum[1] = ~p0 ? ~data[1] : data[1];
assign sum[2] = ~p0to1 ? ~data[2] : data[2];
assign sum[3] = ~p0to2 ? ~data[3] : data[3];
assign sum[4] = ~p0to3 ? ~data[4] : data[4];
assign sum[5] = ~p0to4 ? ~data[5] : data[5];
endmodule
// ------------------- 21) mj_s_dcd8to256 --------------------------
![[Up: ex_decode decode8to256_1]](v2html-up.gif)
module mj_s_dcd8to256
(data, decodeout);
input [7:0] data
;
output [255:0] decodeout
;
wire [15:0] sel
, bottom
;
wire [255:0] decodeout_l
;
// decode top order bits
wire [7:0] data_l
= ~data;
mj_s_dcd4to16 decodeupper( .data(data[7:4]),
.data_l(data_l[7:4]),
.decodeout_l(sel[15:0]));
// decode lower order bits
mj_s_dcd4to16 decodelower( .data(data[3:0]),
.data_l(data_l[3:0]),
.decodeout_l(bottom[15:0]));
// now use the top order bits to select the proper lower order bits
finalsel finalsel15( .sel(~sel[15]),
.sel2(~sel[15]),
.data(~bottom[15:0]),
.out(decodeout_l[255:240]));
finalsel finalsel14( .sel(~sel[14]),
This page: |
Created: | Wed Mar 24 09:43:39 1999 |
| From: |
/import/jet-pj2-sim/rahim/picoJava-II/design/rtl/custom_cells_behv.v
|