TriDriver:
PROC [
design: CD.Design,
enable: PW.ROPE,
disable: PW.ROPE,
top: List,
in: List,
out: List,
bot: List ]
RETURNS [PW.ObjName] = {
topTail: INT = 4;
botTail: INT = 2;
pitch: Size = [mPitch, pBigPitch];
cell: CD.ObPtr ← CDCells.CreateEmptyCell[];
rangeX: INT ← nofVWires;
inN: PW.ROPE ← IF in=NIL THEN NIL ELSE in.first;
outN: PW.ROPE ← IF out=NIL THEN NIL ELSE out.first;
Metal wires
FOR i:
INT
IN [0..rangeX)
DO
Add:
PROC[bindex, tindex, toptail, bottail:
INT] = {
loc.y ← bindex*pitch.y - bottail;
size.y ← (tindex-bindex)*pitch.y + toptail + bottail;
IF size.y>0 THEN AddRet[cell:cell, size:size, loc:loc, level: CMos.met]};
size: Size ← [6, 0];
loc: Location ← [i*pitch.x, 0];
tIO: PW.ROPE ← ListIndexItem[top, i];
bIO: PW.ROPE ← ListIndexItem[bot, i];
IF tIO#
NIL
THEN
SELECT
TRUE
FROM
Rope.Equal[tIO, bIO] => {Add[0, 4, 4+topTail, botTail]};
Rope.Equal[tIO, outN] => {Add[1, 4, 4+topTail, 0]};
Rope.Equal[tIO, inN] => {Add[3, 4, 4+topTail, 0]}
ENDCASE => ERROR; -- top not connected anywhere ABORT;
IF bIO#
NIL
THEN
SELECT
TRUE
FROM
Rope.Equal[bIO, tIO] => LOOP;
Rope.Equal[bIO, inN] => {Add[0, 3, 0, botTail]};
Rope.Equal[bIO, outN] => {Add[0, 1, 0, botTail]};
ENDCASE => ERROR; -- bottom not connected anywhere ABORT
ENDLOOP;
Insert Metal Pins
FOR i:
INT
IN [0..rangeX)
DO
tName: PW.ROPE ← ListIndexItem[top, i];
bName: PW.ROPE ← ListIndexItem[bot, i];
size: Size ← [6, 6];
loc: Location ← [i*pitch.x, 4*pitch.y+4+topTail-size.y];
IF tName #NIL THEN PutPin [cell, size, loc, CMos.met, tName];
IF bName #NIL THEN PutPin [cell, size, [loc.x, -botTail], CMos.met, bName];
ENDLOOP;
Enables and power Wires
AddRet[cell:cell, size:[cellWidth, 4], loc:[-leftTail, 64], level: CMos.pol];
AddRet[cell:cell, size:[cellWidth,16], loc:[-leftTail, 48], level: CMos.met2];
AddRet[cell:cell, size:[cellWidth,16], loc:[-leftTail, 12], level: CMos.met2];
AddRet[cell:cell, size:[cellWidth, 4], loc:[-leftTail, 0], level: CMos.pol];
Insert Enable and power Pins
PutPin [cell, [4, 4], [-leftTail, 64], CMos.pol, enable];
PutPin [cell, [4, 4], [cellWidth-leftTail-4, 64], CMos.pol, enable];
PutPin [cell, [4,16], [-leftTail, 48], CMos.met2, "VDD"];
PutPin [cell, [4,16], [cellWidth-leftTail-4, 48], CMos.met2, "VDD"];
PutPin [cell, [4,16], [-leftTail, 12], CMos.met2, "GND"];
PutPin [cell, [4,16], [cellWidth-leftTail-4, 12], CMos.met2, "GND"];
PutPin [cell, [4, 4], [-leftTail, 0], CMos.pol, disable];
PutPin [cell, [4, 4], [cellWidth-leftTail-4, 0], CMos.pol, disable];
Poly connections
FOR i:
INT
IN [0..rangeX)
DO
AddPCnt:
PROC = {[] ← PWBasics.IncludeApplication
[cell, CMosContacts.CreatePolyCon[l: 8], [loc.x, loc.y-2]]};
loc: Location ← [i * pitch.x, 0];
size: Size ← [(rangeX-i) * pitch.x, 4];
ioT: PW.ROPE ← ListIndexItem[top, i];
ioB: PW.ROPE ← ListIndexItem[bot, i];
loc.y ← 3*pitch.y;
IF inN#
NIL
THEN
IF Rope.Equal[inN, ioT]
OR Rope.Equal[inN, ioB]
THEN {AddPCnt[]; AddRet[cell:cell, size:size, loc:loc, level:CMos.pol]};
loc.y ← 1*pitch.y;
IF outN
#NIL THEN IF Rope.Equal[outN, ioT]
OR Rope.Equal[outN, ioB]
THEN {AddPCnt[]; AddRet[cell:cell, size:size, loc:loc, level:CMos.pol]};
ENDLOOP;
Cell
IF
NOT inN=NIL
THEN [] ← PWBasics.IncludeApplication[
cell: cell,
subcell: PWBasics.ObjFromName[design, "GVTriStateDriver"],
location: [rangeX*pitch.x, 0]];
PWBasics.RepositionCell[design, cell];
RETURN[PWBasics.NameFromObj[cell]]};
Gate:
PROC [
design: CD.Design,
top: List,
type: List,
in1: List,
in2: List,
out: List,
bot: List ]
RETURNS [PW.ObjName] = {
topTail: INT = 4;
botTail: INT = 2;
pitch: Size = [mPitch, pBigPitch];
cell: CD.ObPtr ← CDCells.CreateEmptyCell[];
rangeX: INT ← MAX[ListLength[top], ListLength[bot]];
in1N: PW.ROPE ← IF in1=NIL THEN NIL ELSE in1.first;
in2N: PW.ROPE ← IF in2=NIL THEN NIL ELSE in2.first;
outN: PW.ROPE ← IF out=NIL THEN NIL ELSE out.first;
Metal wires
FOR i:
INT
IN [0..rangeX)
DO
Add:
PROC[bindex, tindex, toptail, bottail:
INT] = {
loc.y ← bindex*pitch.y - bottail;
size.y ← (tindex-bindex)*pitch.y + toptail + bottail;
IF size.y>0 THEN AddRet[cell:cell, size:size, loc:loc, level: CMos.met]};
size: Size ← [6, 0];
loc: Location ← [i*pitch.x, 0];
tIO: PW.ROPE ← ListIndexItem[top, i];
bIO: PW.ROPE ← ListIndexItem[bot, i];
IF tIO#
NIL
THEN
SELECT
TRUE
FROM
Rope.Equal[tIO, bIO] => {Add[0, 2, 4+topTail, botTail]};
Rope.Equal[in2N, tIO] => {Add[0, 2, 4+topTail, 0]};
Rope.Equal[outN, tIO] => {Add[1, 2, 4+topTail, 0]};
Rope.Equal[in1N, tIO] => {Add[2, 2, 4+topTail, 0]};
ENDCASE => ERROR; -- top not connected anywhere ABORT;
IF bIO#
NIL
THEN
SELECT
TRUE
FROM
Rope.Equal[bIO, tIO] => LOOP;
Rope.Equal[in1N, bIO] => {Add[0, 2, 0, botTail]};
Rope.Equal[outN, bIO] => {Add[0, 1, 0, botTail]};
Rope.Equal[in2N, bIO] => {Add[0, 0, 0, botTail]};
ENDCASE => ERROR; -- bottom not connected anywhere ABORT
ENDLOOP;
Insert Metal Pins
FOR i:
INT
IN [0..rangeX)
DO
tName: PW.ROPE ← ListIndexItem[top, i];
bName: PW.ROPE ← ListIndexItem[bot, i];
size: Size ← [6, 6];
loc: Location ← [i*pitch.x, 2*pitch.y+4+topTail-size.y];
IF tName #NIL THEN PutPin [cell, size, loc, CMos.met, tName];
IF bName #NIL THEN PutPin [cell, size, [loc.x, -botTail], CMos.met, bName];
ENDLOOP;
Enables and power Wires
AddRet[cell:cell, size:[cellWidth,18], loc:[-leftTail, 22], level: CMos.met2];
AddRet[cell:cell, size:[cellWidth,18], loc:[-leftTail, -4], level: CMos.met2];
Insert Enable and power Pins
PutPin [cell, [4,18], [-leftTail, 22], CMos.met2, "VDD"];
PutPin [cell, [4,18], [cellWidth-leftTail-4, 22], CMos.met2, "VDD"];
PutPin [cell, [4,18], [-leftTail, -4], CMos.met2, "GND"];
PutPin [cell, [4,18], [cellWidth-leftTail-4, -4], CMos.met2, "GND"];
Poly connections
FOR i:
INT
IN [0..rangeX)
DO
AddPCnt:
PROC = {[] ← PWBasics.IncludeApplication
[cell, CMosContacts.CreatePolyCon[l: 8], [loc.x, loc.y-2]]};
loc: Location ← [ i * pitch.x, 0];
size: Size ← [(rangeX-i) * pitch.x, 4];
ioT: PW.ROPE ← ListIndexItem[top, i];
ioB: PW.ROPE ← ListIndexItem[bot, i];
loc.y ← 2*pitch.y;
IF in1N#
NIL
THEN
IF Rope.Equal[in1N, ioT]
OR Rope.Equal[in1N, ioB]
THEN {AddPCnt[]; AddRet[cell:cell, size:size, loc:loc, level:CMos.pol]};
loc.y ← 1*pitch.y;
IF outN#
NIL
THEN
IF Rope.Equal[outN, ioT]
OR Rope.Equal[outN, ioB]
THEN {AddPCnt[]; AddRet[cell:cell, size:size, loc:loc, level:CMos.pol]};
loc.y ← 0*pitch.y;
IF in2N#
NIL
THEN
IF Rope.Equal[in2N, ioT]
OR Rope.Equal[in2N, ioB]
THEN {AddPCnt[]; AddRet[cell:cell, size:size, loc:loc, level:CMos.pol]};
ENDLOOP;
Cell
IF type#
NIL
THEN {
inv: BOOL ← Rope.Find[s1: type.first, s2: "INV", case: FALSE]#-1;
nor: BOOL ← Rope.Find[s1: type.first, s2: "NOR", case: FALSE]#-1;
nand: BOOL ← Rope.Find[s1: type.first, s2: "NAND", case: FALSE]#-1;
[] ← PWBasics.IncludeApplication[
cell: cell,
subcell: PWBasics.ObjFromName[design, (
SELECT
TRUE
FROM
nor => "BasicNOR", nand => "BasicNAND", ENDCASE => "BasicINV")],
location: [rangeX*pitch.x, -4]] };
PWBasics.RepositionCell[design, cell];
RETURN[PWBasics.NameFromObj[cell]]};