%----------------------------------------------------------------------------
% Magic tutorial number S-2
%----------------------------------------------------------------------------

\NeedsTeXFormat{LaTeX2e}[1994/12/01]
\documentclass[letterpaper,twoside,12pt]{article}
\usepackage{epsfig,times}

\setlength{\textwidth}{8.5in}
\addtolength{\textwidth}{-2.0in}
\setlength{\textheight}{11.0in}
\addtolength{\textheight}{-2.0in}
\setlength{\oddsidemargin}{0in}
\setlength{\evensidemargin}{0pt}
\setlength{\topmargin}{-0.5in}
\setlength{\headheight}{0.2in}
\setlength{\headsep}{0.3in}
\setlength{\topskip}{0pt}

\def\hinch{\hspace*{0.5in}}
\def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\=\hinch\=\kill}
\def\endi{\end{tabbing}\end{center}}
\def\ii{\>\>\>}
\def\q{\special{ps:(") show}\hspace*{0.6em}}
\def\mytitle{Magic Tutorial \#S-2: Boxes and labels}

%----------------------------------------------------------------------------

\begin{document}

\makeatletter
\newcommand{\ps@magic}{%
	\renewcommand{\@oddhead}{\mytitle\hfil\today}%
	\renewcommand{\@evenhead}{\today\hfil\mytitle}%
	\renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}%
	\renewcommand{\@oddfoot}{\@evenfoot}}
\newcommand{\ps@mplain}{%
	\renewcommand{\@oddhead}{}%
	\renewcommand{\@evenhead}{}%
	\renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}%
	\renewcommand{\@oddfoot}{\@evenfoot}}
\makeatother
\pagestyle{magic}
\thispagestyle{mplain}


\begin{center}
  {\bfseries \Large \mytitle} \\
  \vspace*{0.5in}
  {\itshape Rajit Manohar} \\
  \vspace*{0.5in}
   Department of Computer Science \\
   California Institute of Technology \\
   Pasadena, CA  91125 \\
  \vspace*{0.25in}
  This tutorial corresponds to Magic version 7. \\
\end{center}
\vspace*{0.5in}

{\noindent\bfseries\large Tutorials to read first:}
\starti
   \> Magic Tutorial \#S-1: The scheme command-line interpreter
\endi

{\noindent\bfseries\large Commands introduced in this tutorial:}
\starti
   \> :getbox, :box.push, :box.pop, :box.move, :label.vert, :label.horiz, \\
   \> :label.rename, :label.search, :label.find-next
\endi

{\noindent\bfseries\large Macros introduced in this tutorial:}

\starti
   \> {\itshape (None)}
\endi

\vspace*{0.25in}
\section{The current box}

The fundamental way scheme programs interact with magic layout is by
using magic's {\bfseries box} command. For instance,

\starti
   \ii {\bfseries (box 1 1 2 2)}
\endi

changes the current box to the rectangle defined by the coordinates
(1,1) and (2,2) in the current edit cell. This is the standard magic
{\bfseries :box} command. After moving the box to a particular position in
the layout, the area can be painted, erased, selected, etc.


The scheme function {\bfseries getbox} returns the current box as a list of
four integers. For instance,

\starti
   \ii {\bfseries (box 1 1 2 2)} \\
   \ii {\bfseries (define x (getbox))}
\endi


will bind the list {\bfseries (1 1 2 2)} to variable {\bfseries x}.

\section{Saving and restoring the box}

If a scheme function moves the current box around, it is good practice
to restore the box back to its original position. This is especially
useful when writing a function that the user is likely to type on the
command line.

{\bfseries box.push} can be used to push a box onto the current stack of
boxes. {\bfseries box.pop} restores the box to the one on the top of the box
stack. The sequence

\starti
   \ii {\bfseries (box.push (getbox))} \\
   \ii {\bfseries (box 1 1 5 4)} \\
   \ii {\bfseries (paint poly)} \\
   \ii {\bfseries (box.pop)}
\endi

will paint a rectangle of polysilicon from (1,1) to (5,4), restoring
the original position of the box.

\section{Moving the box}

Magic's built-in {\bfseries move} command is not entirely
reliable. Sometimes move commands are ignored, with disastrous
effects. (Think about what might happen if a move command was ignored
in the middle of drawing a stack of twenty transistors . . .) The
scheme function {\bfseries box.move} moves the box relative to the current
position.

\starti
   \ii {\bfseries (box.move 5 3)}
\endi

will move the box right 5 lambda and up 3 lambda.

\section{Labelling vertical and horizontal wires}

Datapaths are usually designed by designing cells for a single bit of
the datapath, and then arraying those cells to obtain the complete
datapath. When simulating such designs, it is usually desirable to
label wires in the datapath with names like ``name0'', ``name1'', up to
``nameN.''

There are two functions that can be used to perform such a task. The
function {\bfseries label.vert} returns a function that can be used as a
labeller for vertically arrayed nodes. {\bfseries label.horiz} returns a
function that can be used as a labeller for horizontally arrayed
nodes.

\starti
   \ii {\bfseries (define lbl (label.vert {\q}name{\q} 6)}
\endi

The command above defines a new function {\bfseries lbl} that can be used to
generate labels beginning with {\q}name0{\q} for nodes that are vertically
spaced by 6 lambda. The simplest way to use this function is to bind
it to a macro as follows:

\starti
   \ii {\bfseries (macro 1 {\q}lbl{\q})}
\endi

Place the box over the lowest node. Every time key ``1'' is pressed, a
new label ``nameM'' is created and the box is moved up by 6
lambda. {\bfseries label.horiz} can be used in a similar fashion for
labelling nodes that are horizontally arrayed.

\section{Finding and renaming existing labels}

The label macros provide functionality to search for all labels
that match a particular string. Place the box over the region of
interest. Type:

\starti
   \ii {\bfseries (label.search {\q}label{\q})}
\endi

To place the box over the first occurrence of the label you searched
for, type:

\starti
   \ii {\bfseries (label.find-next)}
\endi

Repeatedly executing this function causes the box to move to all the
labels that match the search pattern. Typically, one would bind 
{\bfseries label.find-next} to a macro.

The command {\bfseries label.rename} can be used to rename all labels with a
particular name. To use this command, place the box over the region of
interest. Then type

\starti
   \ii {\bfseries (label.rename {\q}label1{\q} {\q}label2{\q})}
\endi


All occurrences of label ``label1'' in the current box will be
renamed to ``label2''.

\section{Writing these functions}

The functions discussed in this tutorial are not built-in. They are
user-defined functions in the default scheme file loaded in when magic
starts.

As you begin to use magic with the scheme command-line interpreter,
you will observe that commands for drawing paint on the screen are
extremely slow. This time interval is not normally noticeable because
editing is interactive. However, when one can write a scheme program
to draw twenty transistors on the screen, this delay becomes
noticeable. It is worthwhile to minimize the number of magic commands
executed, even if this involves writing more scheme code. The
{\bfseries box-pop} command has been tuned a little to not execute the
{\bfseries box} command if the box would not move as a result.

\bfseries
\starti
\> (define box.list ()) \\ \\

\> (define box.move \\
\>\>   (lambda (dx dy) \\
\ii     (let* ((x (getbox)) \\
\ii\> 	      (nllx (+ dx (car x))) \\
\ii\> 	      (nlly (+ dy (cadr x))) \\
\ii\> 	      (nurx (+ dx (caddr x))) \\
\ii\> 	      (nury (+ dy (cadddr x)))) \\
\ii     (box nllx nlly nurx nury) \\
\ii    ) \\
\>\>  ) \\
\>   ) \\ \\

\>   (define box.=? \\
\>\>   (lambda (b1 b2) \\
\ii      (and (and (=? (car b1) (car b2)) (=? (cadr b1) (cadr b2))) \\
\ii\>	      (and (=? (caddr b1) (caddr b2)) (=? (caddr b1) (caddr b2))) \\
\ii	 ) \\
\>\>   ) \\
\>   ) \\ \\

\> (define box.push \\
\>\>   (lambda (pos) \\
\ii	(set! box.list (cons pos box.list)) \\
\>\>  ) \\
\> )
\endi


\starti
\> (define box.pop \\
\>\>  (lambda () \\
\ii      (if (null? box.list) \\
\ii\>	    (echo {\q}Box list is empty{\q}) \\
\ii\>	    (let ((x (car box.list))) \\
\ii\>\>	       (begin  \\
\ii\>\>        (set! box.list (cdr box.list)) \\
\ii\>\>        (if (box.=? x (getbox)) \#t (eval (cons 'box x))) \\
\ii\>\>	    ) \\
\ii\>	 ) \\
\ii    ) \\
\>\> ) \\
\> )
\endi

\end{document}
