<<>> <> <> <> <> <<>> DIRECTORY CD, CoreFlat, RefTab, SoftHdwBasics, SoftHdwAssembly, SoftHdwCompiler, TerminalIO; SoftHdwRouterOutput: CEDAR PROGRAM IMPORTS RefTab, SoftHdwAssembly, SoftHdwBasics EXPORTS SoftHdwCompiler = BEGIN OPEN SoftHdwCompiler; MarkedPlaceAndRoute: PUBLIC PROC [placement: Placement, route: RefTab.Ref, incompleteNetEnds: NetEndList, sizes: ArrayPosition] = { ColorPosition: PROC [node: Node] = TRUSTED { position: SoftHdwAssembly.ArrayPosition _ NEW[SoftHdwAssembly.ArrayPositionRec]; position^ _ node.position; positions _ CONS[[red, position], positions]; }; program: SoftHdwAssembly.Program _ ProgramFromPlaceAndRoute[placement, route, incompleteNetEnds]; design: CD.Design _ SoftHdwAssembly.PrintAndDraw[sizes, program]; positions: SoftHdwAssembly.ColoredArrayPositions _ NIL; FOR ine: NetEndList _ incompleteNetEnds, ine.rest UNTIL ine=NIL DO ColorPosition[ine.first.source]; FOR nl: Nodes _ ine.first.destinations, nl.rest UNTIL nl=NIL DO ColorPosition[nl.first]; ENDLOOP; ENDLOOP; SoftHdwAssembly.HighlightDesign[design, sizes, positions]; }; ProgramFromPlaceAndRoute: PUBLIC PROC [placement: Placement, route: RefTab.Ref, incompleteNetEnds: NetEndList] RETURNS [program: SoftHdwAssembly.Program] = { <<(... incompleteNetEnds is not yet used, but should be used to flag dangling wires. )>> ParsePlacement: RefTab.EachPairAction = { p: Primitive _ NARROW[key]; pa: PrimitiveAssignment _ NARROW[val]; grain: INT; position^ _ pa.position^; position.type _ InputEnabled; FOR index: CARDINAL IN [0..pa.size) DO grain _ pa[index]; SELECT position.orientation FROM Vertical => position.grain.y _ grain; Horizontal => position.grain.x _ grain; ENDCASE => ERROR; program.tiles _ CONS[CopyPosition[position], program.tiles]; ENDLOOP; IF p.flatClock#NIL THEN { flop: ArrayPosition _ CopyPosition[pa.position]; flop.type _ FlipFlop; program.tiles _ CONS[flop, program.tiles]; }; }; ParseRoute: RefTab.EachPairAction = { path: Path _ NARROW[val]; ParsePath[path] }; ParsePath: PROC [path: Path] = { pos, nextPos: ArrayPosition; FOR index: CARDINAL IN [0..path.size) DO pos _ path[index]; IF index> position^ _ from^; nextPosition^ _ to^; position.type _ SelectArcType[from, to]; <> position.minorArray.x _ MAX[from.minorArray.x, to.minorArray.x]; position.minorArray.y _ MAX[from.minorArray.y, to.minorArray.y]; IF position.type=InputEnabled THEN { <> position.orientation _ to.orientation; SELECT from.orientation FROM Vertical => { position.grain.x _ from.grain.x; position.grain.y _ to.grain.y }; Horizontal => { position.grain.y _ from.grain.y; position.grain.x _ to.grain.x }; ENDCASE => ERROR; }; program.tiles _ CONS[CopyPosition[position], program.tiles]; }; position: ArrayPosition _ NEW[ArrayPositionRec]; nextPosition: ArrayPosition _ NEW[ArrayPositionRec]; program _ SoftHdwAssembly.Create[NIL, NIL, MinorArray, NIL]; [] _ RefTab.Pairs[placement.positions, ParsePlacement]; [] _ RefTab.Pairs[route, ParseRoute]; FixUpPathInversions[placement, route, program]; }; IsPathSegmentInverting: PROC [from, to: ArrayPosition] RETURNS [invert: BOOL] ~{ <> invert _ SELECT from.type FROM Input => SELECT to.type FROM Output => TRUE, ENDCASE => ERROR, Interchip => ERROR, Long => SELECT to.type FROM Input => FALSE, ENDCASE => ERROR, Output => SELECT to.type FROM Input => FALSE, Long => FALSE, LeftDown => TRUE, RightUp => TRUE, ENDCASE => ERROR, LeftDown => SELECT to.type FROM Input => FALSE, LeftDown => TRUE, ENDCASE => ERROR, RightUp => SELECT to.type FROM Input => FALSE, RightUp => TRUE, ENDCASE => ERROR, ENDCASE => ERROR; }; SelectArcType: PROC [from, to: ArrayPosition] RETURNS [type: NodeType] ~{ <> type _ SELECT from.type FROM Input => SELECT to.type FROM Output => IF (from.orientation=to.orientation) THEN ParallelInput ELSE InputEnabled, ENDCASE => ERROR, Interchip => ERROR, Long => SELECT to.type FROM Input => LToI, ENDCASE => ERROR, Output => SELECT to.type FROM <> Input => IF ((from.minorArray.x=to.minorArray.x) AND from.orientation=Horizontal) OR ((from.minorArray.y=to.minorArray.y) AND from.orientation=Vertical) THEN ORUToI ELSE OLDToI, Long => ORUToL, LeftDown => ORUToLD, RightUp => OLDToRU, ENDCASE => ERROR, LeftDown => SELECT to.type FROM Input => LDToI, LeftDown => LDToLD, ENDCASE => ERROR, RightUp => SELECT to.type FROM Input => RUToI, RightUp => RUToRU, ENDCASE => ERROR, ENDCASE => ERROR; }; <> <<>> CopyPosition: PROC [pos: ArrayPosition] RETURNS [newpos: ArrayPosition] ~ { newpos _ NEW[ArrayPositionRec _ pos^]; }; FixUpPathInversions: PROC [placement: Placement, route: RefTab.Ref, program: SoftHdwAssembly.Program] ~ { <> flatCell: FlatCell _ placement.flatCell; EachWire: RefTab.EachPairAction ~ { <> wire: CoreFlat.FlatWire _ NARROW[key]; primitive: Primitive _ NARROW[val]; primitiveAssignment: PrimitiveAssignment _ NARROW[RefTab.Fetch[placement.positions, primitive].val]; primitivePosition: ArrayPosition _ primitiveAssignment.position; pathInverted, outputInverted, inputInverted, totalInversion, completed: BOOL; <> FOR index: CARDINAL IN [0..primitive.size) DO inputGrainIndex: CARDINAL _ primitiveAssignment[index]; polarizedInput: PolarizedInputRec _ primitive[index]; source: Primitive _ polarizedInput.source; path: Path; IF source#NIL THEN { path _ NARROW[RefTab.Fetch[route, source.flatOutput].val]; IF path=NIL THEN RETURN; inputPos^ _ primitivePosition^; SELECT primitivePosition.orientation FROM Horizontal => { inputPos.orientation _ Vertical; inputPos.grain.y _ 0; inputPos.grain.x _ inputGrainIndex}; Vertical => { inputPos.orientation _ Horizontal; inputPos.grain.x _ 0; inputPos.grain.y _ inputGrainIndex}; ENDCASE => ERROR; [completed, pathInverted] _ IsPathInverting[path, inputPos]; inputInverted _ polarizedInput.negate; outputInverted _ primitive.negateOutput; <> totalInversion _ pathInverted#(inputInverted#outputInverted); IF totalInversion THEN ProgramInverterForInput[inputPos, program]; }; ENDLOOP; }; inputPos: ArrayPosition _ NEW[ArrayPositionRec]; [] _ RefTab.Pairs[flatCell.wires, EachWire]; }; ProgramInverterForInput: PROC [inputPos: ArrayPosition, program: SoftHdwAssembly.Program] ~ { <> position: ArrayPosition _ CopyPosition[inputPos]; position.type _ Inverter; program.tiles _ CONS[position, program.tiles]; }; IsPathInverting: PROC [path: Path, inputPos: ArrayPosition] RETURNS [arrived: BOOL _ FALSE, invert: BOOL _ FALSE] ~ { <> TracePath: PROC [path: Path, dest: ArrayPosition, inversion: BOOL] RETURNS [BOOL, BOOL] ~ { FOR index: CARDINAL IN [0..path.size) DO position _ path[index]; IF SoftHdwBasics.ArrayPositionEqual[position, inputPos] THEN RETURN[TRUE, inversion]; IF index> IF path.subPaths = NIL THEN RETURN[FALSE, inversion] ELSE { FOR index: CARDINAL IN [0..path.subPaths.size) DO foundDest, subPathInverts: BOOL; [foundDest, subPathInverts] _ TracePath[path.subPaths[index], inputPos, FALSE]; position _ path[path.size-1]; nextPosition _ path.subPaths[index][0]; IF foundDest THEN RETURN[TRUE, inversion#(subPathInverts#IsPathSegmentInverting[position, nextPosition])]; ENDLOOP; }; <> <> RETURN[FALSE,FALSE]; }; position: ArrayPosition; nextPosition: ArrayPosition; [arrived, invert] _ TracePath[path, inputPos, FALSE]; }; NthPath: PUBLIC PROC [route: RefTab.Ref, nth: INT] RETURNS [path: Path _ NIL]~ { <> EachPath: RefTab.EachPairAction ~ { IF index = nth THEN path _ NARROW[val]; index _ index+1; }; index: INT _ 0; [] _ RefTab.Pairs[route, EachPath]; }; MakeColoredPositionPath: PUBLIC PROC [pathlist: ArrayPositions] RETURNS [SoftHdwAssembly.ColoredArrayPositions] ~ { <> cpathlist: SoftHdwAssembly.ColoredArrayPositions _ NIL; FOR poslist: ArrayPositions _ pathlist, poslist.rest WHILE poslist#NIL DO cpathlist _ CONS[[color: red, position: poslist.first], cpathlist]; ENDLOOP; RETURN[cpathlist]; }; ShowPath: PUBLIC PROC [design: CD.Design, sizes: ArrayPosition, route: RefTab.Ref, nthPath: INT] ~ { HighlightPath[design, sizes, NthPath[route, nthPath]]; }; HighlightPath: PUBLIC PROC [design: CD.Design, sizes: ArrayPosition, path: Path] ~ { <> pathList: ArrayPositions; posList: SoftHdwAssembly.ColoredArrayPositions; pathList _ FlattenPath[path]; posList _ MakeColoredPositionPath[pathList]; SoftHdwAssembly.HighlightDesign[design, sizes, NIL]; SoftHdwAssembly.HighlightDesign[design, sizes, posList, NIL, "Critical Path"]; }; FlattenPath: PUBLIC PROC [path: Path] RETURNS [pathlist: ArrayPositions _ NIL] ~ { <> position: ArrayPosition _ NEW[ArrayPositionRec]; nextPosition: ArrayPosition _ NEW[ArrayPositionRec]; TracePath: PROC [path: Path] = { pos, nextPos: ArrayPosition; FOR index: CARDINAL IN [0..path.size) DO pos _ path[index]; pathlist _ CONS[CopyPosition[pos], pathlist]; IF index> position^ _ from^; nextPosition^ _ to^; position.type _ SelectArcType[from, to]; <> position.minorArray.x _ MAX[from.minorArray.x, to.minorArray.x]; position.minorArray.y _ MAX[from.minorArray.y, to.minorArray.y]; IF position.type=InputEnabled THEN { <> position.orientation _ to.orientation; SELECT from.orientation FROM Vertical => { position.grain.x _ from.grain.x; position.grain.y _ to.grain.y }; Horizontal => { position.grain.y _ from.grain.y; position.grain.x _ to.grain.x }; ENDCASE => ERROR; }; pathlist _ CONS[CopyPosition[position], pathlist]; }; TracePath[path]; }; END.