--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.