It is possible to move all DEVICE statement calculations to a DMACRO that is called by a CMACRO, which is part of a DEVICE statement, replacing the traditional DEVICE statement calculations. In this fashion, you can have several DEVICE operations share a common calculation section.

This is done by adding the CMACRO statement to the end of the DEVICE statement(s), as follows:

DEVICE MP pgate pgate (G) psd (S) psd (D) bulk (B) <sd_rs> CMACRO m_props sd_rs

DEVICE MN ngate ngate (G) nsd (S) nsd (D) bulk (B) <sd_rs> CMACRO m_props sd_rs

Note 3 things about this DEVICE statement:

- The traditional "[...]" section is missing, replaced by a CMACRO. The calculation will be added later as part of a DMACRO.
- The CMACRO has a name "m_props" and one layer argument : sd_rs.
- The DEVICE statement has an auxillary layer called <sd_rs> which is also an argument to the CMACRO. (this aux layer is required for NRD and NRS calculations.)

For each DEVICE statement that you wish to share the MACRO, you will have to hand edit the DEVICE statement in a similar fashion as the one above. You can then use m_props MACRO for all those devices.

Following is an example of a rulesfile section that uses a DMACRO to calculate all the parameters W, L, AD, AS, PD, PS, NRD & NRS.

// Put the following statements anywhere, but it is probably best to

// place them near the DMACRO below

sd_rs1 = sd not CONTACT

sd_rs2 = sd_rs1 coincident edge gate

sd_rs3 = sd_rs1 coincident edge CONTACT

sd_rs = int sd_rs2 sd_rs3 < 100 parallel opposite region

// the sd_rs layer created above is necessary for the NRD and NRS

// calculations in M devices.

// Note, instead of 100, the above command should use the

// actual largest distance a source/drain contact would ever

// be from the edge of a gate in your process.

// Following is the DMACRO that does the actual calculation.

DMACRO m_props sd_rs

{

[ property W, L, AS, AD, PS, PD, NRS, NRD

weffect = 0

// CALCULATE W & L

W = (perim_coincide(S, G)+ perim_coincide(D, G)) /2

L = area(G) / W

if ( ( bends(G) != 0 ) && ( weffect != 0 ) )

{

if ( W > L )

W = W - weffect * bends(G) * L

else

L = L - weffect * bends(G) * W

}

//CALCULATE AS, AD, PS, PD

AS = area(S)

AD = area(D)

PS = perim(S)

PD = perim(D)

// The next section was built by copying the example in the

// Calibre Verification User's Manual, Device Recognition,

// Property Computation section. Please refer

// to that document for details on these calculations.

// CALCULATE NRS and NRD.

SUM_S_LENGTH = perimeter_inside(sd_rs, S) - perimeter_coincide(sd_rs, S)

COUNT_S = trunc((count(sd_rs) * perimeter_coincide(sd_rs, S) /

perimeter_coincide(sd_rs, G)) + 0.5)

IF (COUNT_S != 0)

{

NRS = SUM_S_LENGTH / COUNT_S / W / 2 }

ELSE {

NRS = AS / (W * W)

}

SUM_D_LENGTH = perimeter_inside(sd_rs, D) - perimeter_coincide(sd_rs, D)

COUNT_D = count(sd_rs) - COUNT_S

IF (COUNT_D != 0)

{

NRD = SUM_D_LENGTH / COUNT_D / W / 2 }

ELSE {

NRD = AD / (W * W)

}

]

}