--routeCells.mesa DIRECTORY RouteDefs; RouteCells:PROGRAM IMPORTS RouteDefs EXPORTS RouteDefs=BEGIN OPEN RouteDefs; Error:SIGNAL=CODE; CreateCells:PUBLIC CtlProc=BEGIN GetInput[]; EnumerateAllSignals[MakeCells]; IF problem.chipSize.x<=0 OR problem.chipSize.y<=0 THEN Error; EnumerateCells[CheckCells]; EnumerateAllSignals[CheckSignals]; CheckNets[]; ShowLabel["CELLS"]; ShowPoint["chip = ",problem.chipSize.x,problem.chipSize.y]; Return[]; EnumerateCells[ShowCells]; ShowNets; RETURN[-1]; END; MakeCells:PROCEDURE[c:CellPtr,s:SignalPtr]=BEGIN FOR nl:NetListPtr←problem.wirelist,nl.t UNTIL nl=NIL DO n:NetPtr=nl.h; IF SameString[s.name,n.name] THEN {s.circuit←n.number; s.net←n; EXIT}; ENDLOOP; END; CheckCells:PROCEDURE[c:CellPtr]=BEGIN Overlap:PROCEDURE[c2:CellPtr]=BEGIN IF c=c2 THEN RETURN; IF c.pos.x<c2.pos.x+c2.sizeL.x AND c2.pos.x<c.pos.x+c.sizeL.x AND c.pos.y<c2.pos.y+c2.sizeL.y AND c2.pos.y<c.pos.y+c.sizeL.y THEN Error; END; IF c.sizeL.x<=0 OR c.sizeL.y<=0 THEN Error; IF c.pos.x<0 OR c.pos.y<0 THEN Error; IF c.pos.x+c.sizeL.x>problem.chipSize.x THEN Error; IF c.pos.y+c.sizeL.y>problem.chipSize.y THEN Error; EnumerateCells[Overlap]; END; CheckSignals:PROCEDURE[c:CellPtr,s:SignalPtr]=BEGIN good:BOOLEAN←FALSE; SELECT s.side FROM n,s=>IF s.offset NOT IN [0..c.sizeL.x) THEN Error; e,w=>IF s.offset NOT IN [0..c.sizeL.y) THEN Error; ENDCASE=>Error; FOR nl:NetListPtr←problem.wirelist,nl.t UNTIL nl=NIL OR good DO n:NetPtr=nl.h; good←SameString[n.name,s.name]; ENDLOOP; IF ~good THEN Error; END; CheckNets:PROCEDURE=BEGIN FOR nl:NetListPtr←problem.wirelist,nl.t UNTIL nl=NIL DO n:NetPtr=nl.h; good:BOOLEAN←FALSE; Match:PROCEDURE[c:CellPtr,s:SignalPtr]= {good←good OR SameString[n.name,s.name]}; FOR nl2:NetListPtr←problem.wirelist,nl2.t UNTIL nl2=NIL DO n2:NetPtr=nl2.h; IF n.number=n2.number THEN EXIT; REPEAT FINISHED=>Error; --only one end ENDLOOP; EnumerateAllSignals[Match]; IF ~good THEN Error; --wirelist name not in cells ENDLOOP; END; ShowCells:PROCEDURE[c:CellPtr]=BEGIN Return[]; ShowPoint["size = ",c.sizeL.x,c.sizeL.y]; ShowPoint[" pos = ",c.pos.x,c.pos.y]; FOR sl:SignalListPtr←c.signals,sl.t UNTIL sl=NIL DO s:SignalPtr=sl.h; Return[]; ShowString[" "]; ShowString[s.name]; ShowString[SELECT s.side FROM n=>" n ", s=>" s ", e=>" e ", w=>" w ", ENDCASE=>" x "]; ShowDecimal[s.offset," pos = "]; ENDLOOP; END; ShowNets:PROCEDURE=BEGIN FOR i:INTEGER IN [1..1000) DO seen:BOOLEAN←FALSE; FOR nl:NetListPtr←problem.wirelist,nl.t UNTIL nl=NIL DO n:NetPtr=nl.h; IF n.number#i THEN LOOP; IF ~seen THEN {Return[]; ShowChar[ShowCircuit[i]]}; seen←TRUE; ShowString[" "]; ShowString[n.name]; ENDLOOP; ENDLOOP; END; END.