! Stack chip generator

%include "inc:util.imp"
%include "ilap:ilap.inc"

%begin
   %integer bits, words
   %string (255) out file

   %routine STACK chip (%integer BITS, WORDS)
      %integer stx, sty, cox, coy, pucy, pocy, p1x, p2x, p3x, p4x
      %integerarray puy, poy (1:bits)
      %record (connf) %array ports (1:2*bits+8)
      %const %integer mwid = 4, dwid = 2   { metal & diffusion port widths }
      %const %integer swid = 8             { power supply width }
      %const %integer top ext = 8          { extension of top route from stack }
      %integer i
      stack("Stack", bits, words, cox, coy, pucy, pocy, p1x, p2x, p3x, p4x, puy, poy)
      ! Route all clock wires clear of other signal lines
      symbol ("Top route")
         layer (metal);   width (4)
         wirey (p1x, 0, top ext)
         wirey (p2x, 0, top ext)
         wirey (p3x, 0, top ext)
         wirey (p4x, 0, top ext)
         width (swid)
         wirey (SX("Stack")-swid, -coy, coy+top ext);
      end symbol
      ! Route 2 pads from each side to the bottom
      symbol ("Left route")
         layer (diffusion)
         wirex (0, puy(i), -6*i) %and ay (0) %for I = 1, 1, 4
         wirex (0, puy(i), -24) %for I = 5, 1, bits
         wirex (0, pucy, -24)
         wirex (0, pocy, -24)
      end symbol
      text ("Chip name", " A ".ItoS(bits,0)." x ".ItoS(words,0)." Stack",
                         SX("Stack")-cox-swid, coy+top ext) %if words > 4
      ! Add the componet symbols together.
      symbol ("Chip inards")
         draw ("Left route", 0, 0)
         draw ("Stack", 0, 0)
         draw ("Top route", 0, sy("Stack"))
         draw ("Chip name", cox, sy("Stack")-coy) %if words > 4
      end symbol
      ! Set up pad routing and complete the chip
      %for I = 1, 1, 4 %cycle
           fill port (ports(i), in pad, bottom, -6*i, dwid, diffusion)
           fill port (ports(i+bits), out pad, right, poy(i), dwid, diffusion)
      %repeat
      %for i = 5, 1, bits %cycle
           fill port (ports(i), in pad, left, puy(i), dwid, diffusion)
           fill port (ports(i+bits), out pad, right, poy(i), dwid, diffusion)
      %repeat
      fill port (ports(2*bits+1), in pad, left, pucy, dwid, diffusion)
      fill port (ports(2*bits+2), in pad, left, pocy, dwid, diffusion)
      fill port (ports(2*bits+3), in pad, top, p1x, mwid, metal)
      fill port (ports(2*bits+4), in pad, top, p2x, mwid, metal)
      fill port (ports(2*bits+5), in pad, top, p3x, mwid, metal)
      fill port (ports(2*bits+6), in pad, top, p4x, mwid, metal)
      fill port (ports(2*bits+7), vdd pad, bottom, SX("Stack")-swid, swid, metal)
      fill port (ports(2*bits+8), gnd pad, top, SX("Stack")-swid, swid, metal)
      place pads ("Stack chip", "Chip inards", ports, 2*bits+8)
   %end

   prompt ("Number of bits: ")
   read (bits)
   %if bits < 4 %start
       Prompt ("Number of bits must be >= 4, please re-enter: ")
       read (bits) %until bits>=4
   %finish
   prompt ("Number of words: ")
   read (words)
   %if words < 2 %start
       Prompt ("Number of words must be >= 2, please re-enter: ")
       read (words) %until words>=2
   %finish
   prompt ("File name for the chip: ")
   read (out file)
   initialise (out file)
   Stack chip (bits, words)
   finish
%end %of %program
