CoreXformImpl.mesa
Created by Don Curry, February 1, 1986 2:43:22 pm PST
Edited by Don Curry, March 25, 1986 4:24:02 pm PST
CoreXformImpl:
CEDAR
PROGRAM
IMPORTS CoreOps, CoreProperties, IO
EXPORTS CoreXform =
BEGIN OPEN CoreXform;
Signal: SIGNAL = CODE;
xformProp:
ATOM ← CoreProperties.RegisterProperty[
$CoreXformProp, CoreProperties.Props[
[CoreProperties.propPrint, NEW[CoreProperties.PropPrintProc ← Print ]] ] ];
Print: CoreProperties.PropPrintProc = {
xfm: Xform ← NARROW[val];
CoreOps.PrintIndent[indent, to];
to.PutRope["Xform: "];
FOR i:
INT
IN [0..xfm.size)
DO
to.PutF[" %g %g %g %g %g",
IO.int[xfm[i].size], IO.int[xfm[i].toLev], IO.int[xfm[i].fmLev],
IO.int[xfm[i].fmSubSize], IO.int[xfm[i].toSubSize]]
ENDLOOP};
LinkXform:
PROC [xform: Xform] = {
FOR index:
INT
IN [0..xform.size)
DO
temp: INT ← xform[xform[index].toLev].fmLev;
IF temp#index
THEN
IF temp#-1
THEN Signal[]
ELSE xform[xform[index].toLev].fmLev ← index ENDLOOP;
xform[xform.size-1].toSubSize ← 1;
FOR seq:
INT
DECREASING
IN [0..xform.size-1)
DO
size: INT ← xform[xform[seq+1].fmLev].size;
xform[seq].toSubSize ← size*xform[seq+1].toSubSize;
ENDLOOP;
xform[xform.size-1].fmSubSize ← 1;
FOR seq:
INT
DECREASING
IN [0..xform.size-1)
DO
xform[seq].fmSubSize ← xform[seq+1].size*xform[seq+1].fmSubSize;
ENDLOOP};
GenXform:
PUBLIC
PROC[xforms: Xforms]
RETURNS[xform: Xform ← NIL] = {
size: INT ← 0;
index: INT ← 0;
IF xforms=NIL THEN RETURN[NIL];
FOR list: Xforms ← xforms, list.rest
WHILE list#
NIL
DO size ← size+1 ENDLOOP;
xform ← NEW[XformSeq[size]];
FOR list: Xforms ← xforms, list.rest
WHILE list#
NIL
DO
xform[index] ← list.first; index ← index+1 ENDLOOP;
LinkXform[xform]};
GenXforms:
PUBLIC
PROC[xform: Xform]
RETURNS[xforms: Xforms ← NIL] = {
IF xform#
NIL
THEN
FOR index:
INT
DECREASING
IN [0..xform.size)
DO
xforms ← CONS[xform[index], xforms] ENDLOOP};
SetXforms:
PUBLIC
PROC[on:
REF, xforms: Xforms] =
{SetXform[on, GenXform[xforms]]};
SetXform:
PUBLIC
PROC[on:
REF, xform: Xform] = {
WITH on
SELECT
FROM
wire: Core.Wire => CoreProperties.PutWireProp [wire, xformProp, xform];
cell: Core.CellType => CoreProperties.PutCellTypeProp [cell, xformProp, xform];
ENDCASE => Signal[]};
GetXforms:
PUBLIC
PROC[from:
REF]
RETURNS[xforms: Xforms ←
NIL] =
{xforms ← GenXforms[GetXform[from]]};
GetXform:
PUBLIC
PROC[from:
REF]
RETURNS[ xform: Xform ←
NIL] =
{
IF from#
NIL
THEN
WITH from
SELECT
FROM
wire: Core.Wire =>
xform ← NARROW[CoreProperties.GetWireProp[wire, xformProp].value];
cell: Core.CellType =>
xform ← NARROW[CoreProperties.GetCellTypeProp[cell, xformProp].value];
ENDCASE => Signal[]};
XformSize:
PUBLIC
PROC[from:
REF]
RETURNS[ domain:
INT𡤀] =
{xform: Xform ← GetXform[from];
IF xform=NIL OR xform.size=0 THEN RETURN[0];
RETURN[xform[0].size*xform[0].fmSubSize]};
SourceSizeTempIdx:
PROC[xform: Xform, dir: Dir, seq:
INT]
RETURNS[index:
INT] =
{index ← IF dir = ll OR dir = lr THEN seq ELSE xform[seq].fmLev};
SourceSubSize:
PROC[xform: Xform, dir: Dir, seq:
INT]
RETURNS[index:
INT] =
{index ← IF dir = ll OR dir = lr THEN xform[seq].fmSubSize ELSE xform[seq].toSubSize};
DestSizeTempIdx:
PROC[xform: Xform, dir: Dir, seq:
INT]
RETURNS[index:
INT] =
{index ← IF dir = lr OR dir = rr THEN xform[seq].fmLev ELSE seq};
DestSubSize:
PROC[xform: Xform, dir: Dir, seq:
INT]
RETURNS[index:
INT] =
{index ← IF dir = lr OR dir = rr THEN xform[seq].toSubSize ELSE xform[seq].fmSubSize};
XformAddr:
PUBLIC
PROC[xform: Xform, dir: Dir, addr: Addr]
RETURNS[i:
INT, a: Addr] = {
index: INT ← 0;
size: INT ← 1;
FOR seq:
INT
IN [0..xform.size)
DO
index: INT ← SourceSizeTempIdx[xform, dir, seq];
xform[index].temp ← addr.first;
addr ← addr.rest;
REPEAT FINISHED => IF addr#NIL THEN ERROR ENDLOOP;
[i, a] ← ReadOut[xform, dir]};
XformIndex:
PUBLIC
PROC[xform: Xform, dir: Dir, index:
INT]
RETURNS[i:
INT, a: Addr] = {
IF xform=NIL THEN Signal[];
FOR seq:
INT
IN [0..xform.size)
DO
idx: INT ← SourceSizeTempIdx[xform, dir, seq];
subSize: INT ← SourceSubSize[xform, dir, seq];
xform[idx].temp ← index / subSize;
index ← index MOD subSize; ENDLOOP;
[i, a] ← ReadOut[xform, dir]};
ReadOut:
PROC[xform: Xform, dir: Dir]
RETURNS[i:
INT𡤀, a: Addr←NIL] = {
FOR seq:
INT
DECREASING
IN [0..xform.size)
DO
index: INT ← DestSizeTempIdx[xform, dir, seq];
subSize: INT ← DestSubSize[xform, dir, seq];
i ← i + xform[index].temp*subSize;
a ← CONS[xform[index].temp, a] ENDLOOP};
FlatTreeIndex:
PUBLIC
PROC[size, index:
INT]
RETURNS[coord: Coord] = {
val: INT ← 0;
level: INT ← 0;
levels: INT ← 0;
FOR val ← size, val/2 WHILE val#0 DO levels ← levels +1 ENDLOOP;
FOR val ← index, val/2 WHILE (val MOD 2) = 1 DO level ← level +1 ENDLOOP;
coord.index ← val/2;
coord.degrees ← levels;
coord.degree ← levels - level - 1};
END.