Skip to content

Commit

Permalink
Added a 2nd use of the "device" property, which has long been needed,
Browse files Browse the repository at this point in the history
which instead of defining a device or subcircuit that exists inside
the cell, instead redefines the cell itself as a device or subcircuit
model that exists in the PDK.  This is used where a specific layout
subcell has its own associated device definition in the PDK.  Instead
of the "device" property value being the line that gets generated for
a device in the subcells .ext file, the property value should be the
word "primitive" optionally followed by any parameters that need to
be passed to the subcircuit call.
  • Loading branch information
RTimothyEdwards committed May 4, 2022
1 parent e00633b commit 468a8ae
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 15 deletions.
89 changes: 85 additions & 4 deletions doc/html/property.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ <H3>Summary:</H3>
<BLOCKQUOTE>
The <B>property</B> command implements a general-purpose method
of attaching information to a cell definition. Except for a
few properties known to the <B>lef</B> and <B>gds</B> commands
(q.v.), properties have no inherent meaning to magic but may be
used with other programs or scripts to add additional information
about a cell definition. <P>
few properties known to the <B>lef</B>, <B>extract</B>, and
<B>gds</B> commands (q.v.), properties have no inherent meaning
to magic but may be used with other programs or scripts to add
additional information about a cell definition. <P>

With no arguments, all properties of the current edit cell are
listed. With only the <I>key</I> argument, the value associated
Expand All @@ -48,6 +48,87 @@ <H3>Summary:</H3>
its original value will be overwritten.
</BLOCKQUOTE>

<BLOCKQUOTE>
Property names reserved by and used by magic:
<DL>
<DT> <B>GDS_FILE</B>
<DD> The value is the name of a GDS file which contains the mask
data for the cell. The cell is then effectively an abstract
view, because its contents are in the GDS file and do not
necessarily match what is displayed (although they might).
<DT> <B>GDS_START</B>
<DD> If a <B>GDS_FILE</B> is defined, then this value indicates the
byte position of the start of mask data for this cell definition
in the file. If set to value <B>0</B>, then the file will be
searched for the data bounds.
<DT> <B>GDS_END</B>
<DD> If a <B>GDS_FILE</B> is defined, then this value indicates the
byte position of the end of mask data for this cell definition
in the file. If <B>GDS_START</B> is set to <B>0</B>, then this
property may be omitted.
<DT> <B>LEFview</B>
<DD> If set to <B>TRUE</B>, this cell is an abstract view such as that
obtained from a LEF macro, and should not be used for extraction
or for writing mask data (unless <B>GDS_FILE</B> is defined).
<DT> <B>LEFproperties</B>
<DD> If the file was read from a LEF macro, then this property corresponds
to the LEF <B>PROPERTY</B> block values. All values from the block
are contatenated into the single property string.
<DT> <B>LEFsymmetry</B>
<DD> If the file was read from a LEF macro, then this property corresponds
to the macro's <B>SYMMETRY</B> value.
<DT> <B>LEFclass</B>
<DD> If the file was read from a LEF macro, then this property corresponds
to the macro's <B>CLASS</B> value.
<DT> <B>LEFsite</B>
<DD> If the file was read from a LEF macro, then this property corresponds
to the macro's <B>SITE</B> value.
<DT> <B>FIXED_BBOX</B>
<DD> This property value is a space-separated list of four integer values
corresponding to the abutment box of the cell, in magic's internal
units. The abutment box is automatically read from LEF files, but
may be defined for any file and can be used for placement alignment.
<DT> <B>device</B>
<DD> This property declares that the cell is a device or contains a
single device that is not a known extractable device defined in
the technology file. In the first case, the device to be extracted
is a subcircuit and the name of the device is the same as the name
of the cell. In this case, the property value should begin with
"<B>primitive</B>". This may be followed by any parameters
associated with the device that need to be output in the netlist;
e.g., "<B>primitive nf=4</B>. When the cell is recast as a
primitive device, it is necessary for the port order in the cell
to match the port order of the device as it must appear in the
output netlist. In the second case, the device to be extracted
is either a low-level component type (not a subcircuit), or is a
subcircuit with a different name than the cell. In that case, the
value string should be the text of the line as it should appear
in a "<B>device</B>" line in the output <TT>.ext</TT> file when the
cell is extracted. That includes the names of all ports and any
parameters to be output. As the output device is defined inside
the subcircuit of the cell in which it is defined, the ports may
be reordered between the subcircuit and the instantiation of the
device. The use of either form of the <B>device</B> property
precludes the generation of parasitics associated with the cell.
All parasitics are assumed to be included in the device model.
<DT> <B>parameter</B>
<DD> If, when an instance of the cell's subcircuit is generated in the
output netlist, the instance should be passed one or more
parameters, then those parameter <I>key</I><B>=</B><I>value</I>
pairs (as a single, space-separated string) should be defined as
the value to the <B>parameter</B> property.
<DT> <B>MASKHINTS_</B><I>type</I>
<DD> The value is a string of consecutive sets of four integer values,
each set representing the bounding box of a rectangle defining
the area of CIF type <I>type</I>, in magic's internal units.
This indicates that magic will
always generate mask layer <I>type</I> in the specified rectangle
area when writing GDS or CIF output. <I>type</I> may be a templayer,
such that <I>type</I> could be defined as the absence of a mask layer,
for example.
</DL>
</BLOCKQUOTE>

<H3>Implementation Notes:</H3>
<BLOCKQUOTE>
<B>property</B> is implemented as a built-in command in <B>magic</B>.
Expand Down
6 changes: 5 additions & 1 deletion ext2spice/ext2hier.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,8 @@ subcktHierVisit(use, hierName, is_top)
/* Same considerations as at line 1831 for determining if the cell */
/* has been folded into the parent and should not be output. */

isStub = ((def->def_flags & DEF_ABSTRACT) && esDoBlackBox) ? TRUE : FALSE;
isStub = ((def->def_flags & (DEF_ABSTRACT | DEF_PRIMITIVE)) && esDoBlackBox) ?
TRUE : FALSE;
if ((!is_top) && (def->def_flags & DEF_NODEVICES) && (!isStub))
return 0;

Expand Down Expand Up @@ -1922,6 +1923,9 @@ esHierVisit(hc, cdata)
topdef = dfd->def;
flags = dfd->flags;

/* Cells which are marked as "primitive" get no output at all */
if (def->def_flags & DEF_PRIMITIVE) return 0;

/* Cells without any contents (devices or subcircuits) will */
/* be absorbed into their parents. Use this opportunity to */
/* remove all ports. */
Expand Down
3 changes: 3 additions & 0 deletions ext2spice/ext2spice.c
Original file line number Diff line number Diff line change
Expand Up @@ -1779,6 +1779,9 @@ topVisit(def, doStub)
char **sorted_ports;
linkedNodeName *lnn = NULL;

/* Primitive devices are not output at all */
if (def->def_flags & DEF_PRIMITIVE) return;

HashInit(&portNameTable, 32, HT_STRINGKEYS);

/* SPICE subcircuit names must begin with A-Z. This will also be */
Expand Down
6 changes: 3 additions & 3 deletions extflat/EFflat.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,11 +407,11 @@ efFlatNodesDeviceless(hc, cdata)

/* If this definition has no devices but has ports, then it is treated */
/* as a black-box device, so don't decrement the use count of the */
/* parent. Alternately, devices flagged "abstract" are automatically */
/* treated as black-box devices. */
/* parent. Alternately, devices flagged "abstract" or "primitive" are */
/* automatically treated as black-box devices. */

if (!(hc->hc_use->use_def->def_flags & DEF_SUBCIRCUIT))
if (!(hc->hc_use->use_def->def_flags & DEF_ABSTRACT))
if (!(hc->hc_use->use_def->def_flags & (DEF_ABSTRACT | DEF_PRIMITIVE)))
(*usecount)--;
}
return (0);
Expand Down
1 change: 1 addition & 0 deletions extflat/EFint.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ typedef struct def
#define DEF_NODEVICES 0x08 /* This def contains no devices */
#define DEF_SUBSNODES 0x10 /* This def contains implicit substrate nodes */
#define DEF_ABSTRACT 0x20 /* This def is an abstract view (e.g., LEF) */
#define DEF_PRIMITIVE 0x40 /* This def is a primitive device */

/*
* Every Def has a NULL-terminated list of uses that correspond
Expand Down
10 changes: 8 additions & 2 deletions extflat/EFread.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ char *extDevTable[] = {"fet", "mosfet", "asymmetric", "bjt", "devres",
typedef enum
{
ABSTRACT, ADJUST, ATTR, CAP, DEVICE, DIST, EQUIV, FET, KILLNODE, MERGE,
NODE, PARAMETERS, PORT, RESISTOR, RESISTCLASS, RNODE, SCALE, SUBCAP,
SUBSTRATE, TECH, TIMESTAMP, USE, VERSION, EXT_STYLE
NODE, PARAMETERS, PORT, PRIMITIVE, RESISTOR, RESISTCLASS, RNODE, SCALE,
SUBCAP, SUBSTRATE, TECH, TIMESTAMP, USE, VERSION, EXT_STYLE
} Key;

static struct
Expand All @@ -80,6 +80,7 @@ keyTable[] =
"node", NODE, 7,
"parameters", PARAMETERS, 3,
"port", PORT, 8,
"primitive", PRIMITIVE, 0, /* defines a primitive device */
"resist", RESISTOR, 4,
"resistclasses", RESISTCLASS, 1,
"rnode", RNODE, 5,
Expand Down Expand Up @@ -595,6 +596,11 @@ efReadDef(def, dosubckt, resist, noscale, toplevel)
def->def_flags |= DEF_ABSTRACT;
break;

/* primitive (no arguments) */
case PRIMITIVE:
def->def_flags |= DEF_PRIMITIVE;
break;

/* To-do: compare timestamp against the cell */
case TIMESTAMP:
break;
Expand Down
28 changes: 23 additions & 5 deletions extract/ExtBasic.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,6 @@ extBasic(def, outFile)
extRelocateSubstrateCoupling(&extCoupleHash, glob_subsnode);
}

/* Output device parameters for any subcircuit devices */
if (!SigInterruptPending)
extOutputParameters(def, transList, outFile);

/* Check for "device", as it modifies handling of parasitics */
propptr = (char *)DBPropGet(def, "device", &propfound);
if (propfound)
Expand All @@ -318,6 +314,19 @@ extBasic(def, outFile)
tnode->nreg_cap = (CapValue)0.0;
tnode->nreg_resist = (ResValue)0;
}

/* If the device name is "primitive", then parameters */
/* are output here. */

if (!strncmp(propptr, "primitive ", 10))
fprintf(outFile, "parameters :%s %s\n", def->cd_name, propptr + 10);
}

else
{
/* Output device parameters for any subcircuit devices */
if (!SigInterruptPending)
extOutputParameters(def, transList, outFile);
}

if (isabstract) fprintf(outFile, "abstract\n");
Expand All @@ -342,12 +351,21 @@ extBasic(def, outFile)
subsnode = NULL;
propvalue = NULL;

if (propfound)
/* Special case of device "primitive": The subcircuit has the */
/* name of a primitive device model and should be extracted as */
/* the same. The property string may contain parameters to */
/* pass to the subcircuit. */

if (propfound && (!strncmp(propptr, "primitive", 9)))
fprintf(outFile, "primitive\n");

else if (propfound)
{
/* Sanity checking on syntax of property line, plus */
/* conversion of values to internal units. */
propvalue = StrDup((char **)NULL, propptr);
token = strtok(propvalue, " ");

devidx = Lookup(token, extDevTable);
if (devidx < 0)
{
Expand Down

0 comments on commit 468a8ae

Please sign in to comment.