Add a "sel" point for the selector to the multiplexers.
[matthijs/master-project/report.git] / Utils / Metapost.tex
1 % Some setup for metapost
2 \startMPinclusions 
3
4 % Use metaobj for drawing objects
5 input metaobj; 
6
7 % Set some defaults for pretty pictures
8 setObjectDefaultOption("Box")("framewidth")(.75mm);
9 setObjectDefaultOption("Circle")("framewidth")(.75mm);
10 setObjectDefaultOption("Circle")("circmargin")(3mm);
11 setObjectDefaultOption("Mux")("framewidth")(.75mm);
12 %ahlength := 1.5mm;
13 ahangle := 60;
14
15 setCurveDefaultOption("linewidth",.75mm);
16 % Add a nodesep that's equal to the linewidth, since the linewidth isn't
17 % included in the bounding box for line cutoff.
18 setCurveDefaultOption("nodesep",curve_linewidth_default);
19
20
21 % Define a register.
22 % |v| is either a picture, a string or an object given by its number which
23 % will be contained inside the register. Supports the same options as Box,
24 % plus:
25 %   reflect    Reflect the register vertically, so input is right and output
26 %              is left. (default: false)
27 %   labels     Show labels for the input and output ports. (default: false)
28 vardef newReg@#(expr v) text options=
29   ExecuteOptions(@#)(options);
30   assignObj(@#,"Reg");
31   StandardInterface;
32   
33   % We contain a box (that contains the passed object in turn)
34   SubObject(box,obj(newobjstring_));
35   newBox.obj(@#box)(v) options;
36  
37   % Some points for ports
38   ObjPoint ck,d,out;
39
40   ObjCode StandardEquations,
41     % Align our bounding box with the enclosed box
42     "obj(@#box).c = @#c",
43     "obj(@#box).se = @#se",
44     "obj(@#box).nw = @#nw",
45     % Put the clock, data and output ports at the right spots
46     if OptionValue@#("reflect"):
47       "xpart @#out = xpart @#w",
48       "xpart @#d = xpart @#ck = xpart @#e",
49     else:
50       "xpart @#out = xpart @#e",
51       "xpart @#d = xpart @#ck = xpart @#w",
52     fi
53     "ypart @#d = ypart @#out = ypart (@#sw * .25 + @#nw * .75)",
54     "ypart @#ck = ypart (@#sw * .75 + @#nw * .25)";
55
56   StandardTies;
57 enddef;
58
59 % Draw a register
60 def drawReg(suffix reg)=
61   save clkwh, refl;
62   % Draw the box
63   drawObj(obj(reg.box));
64
65   % Fill refl with 1 or -1, to invert coordinates when reflected.
66   if OptionValue.reg("reflect"):
67     refl = -1;
68   else:
69     refl = 1;
70   fi;
71
72   % Calculate (half of) the height and width of the triangle
73   clkwh = ypart((reg.n - reg.s)) * .1;
74   % Draw the "clock" triangle
75   draw ((0, clkwh) -- (refl * clkwh, 0) -- (0, -clkwh)) shifted reg.ck;
76
77   % Draw input and output labels
78   if OptionValue.reg("labels"):
79     if OptionValue.reg("reflect"):
80       label.lft(\sometxt{D}, reg.d);
81       label.rt(\sometxt{O}, reg.out);
82     else:
83       label.rt(\sometxt{D}, reg.d);
84       label.lft(\sometxt{O}, reg.out);
85     fi;
86   fi
87 enddef;
88
89 % Bounding path for a register
90 def BpathReg(suffix n)=BpathObj(obj(n.box)) enddef;
91
92 % Define options
93 define_global_boolean_option("reflect");
94 define_global_boolean_option("labels");
95 setObjectDefaultOption("Reg")("reflect")(false);
96 setObjectDefaultOption("Reg")("labels")(false);
97
98 % Define a Multiplexer.
99 vardef newMux@# text options=
100   ExecuteOptions(@#)(options);
101   assignObj(@#,"Mux");
102   StandardInterface;
103   % Add ports
104   ObjPoint inpa, inpb, out, sel;
105  
106   ObjCode MinimumStandardEquations,
107     % Make it a parallel trapezium
108     "xpart(@#ne - @#nw) = xpart(@#se - @#sw)",
109     "ypart(@#ne - @#nw) = -1 * ypart(@#se - @#sw)",
110     % Use a 22.5 degree angle for the sides
111     "ypart(@#nw) - ypart(@#ne) = xpart(@#ne-@#nw) / 2",
112     % With a specific width and height
113     "@#e-@#w = (" & decimal OptionValue@#("width") & ", 0mm)",
114     "@#n-@#s = (0mm, " & decimal OptionValue@#("height") & ")",
115     % And space the input ports evenly
116     "@#inpa = midpoint(@#nw, @#w)",
117     "@#inpb = midpoint(@#w, @#sw)",
118     "@#out = @#e", 
119     "@#sel = @#n"; 
120
121   StandardTies;
122 enddef;
123
124 % Draw a multiplexer
125 def drawMux(suffix mux)=
126   draw mux.n -- mux.s;
127   % Use our bounding path to draw
128   drawFramedOrFilledObject_(mux);
129 enddef;
130
131 % Bounding path for a multiplexer
132 def BpathMux(suffix n)=StandardBpath(n) enddef;
133
134 % Define options
135 define_local_numeric_option("width");
136 define_local_numeric_option("height");
137 setObjectDefaultOption("Mux")("width")(5mm);
138 setObjectDefaultOption("Mux")("height")(15mm);
139 setObjectDefaultOption("Mux")("framed")(true);
140 % Overidden above
141 %setObjectDefaultOption("Mux")("framewidth")(.5bp);
142 setObjectDefaultOption("Mux")("framecolor")(black);
143 setObjectDefaultOption("Mux")("framestyle")("");
144 setObjectDefaultOption("Mux")("shadow")(false);
145 setObjectDefaultOption("Mux")("shadowcolor")(black);
146 setObjectDefaultOption("Mux")("filled")(false);
147 setObjectDefaultOption("Mux")("fillcolor")(black);
148
149
150 def midpoint(expr a, b) = ((a + b) / 2) enddef;
151
152 \stopMPinclusions
153
154 % Make \overrightarrow "unexpanded", to make it work within metapost.
155 % http://www.ntg.nl/pipermail/ntg-context/2009/043620.html. Will be fixed in
156 % context.
157 \let\normaloverrightarrow\overrightarrow                                                                                                                     
158 \unexpanded\def\overrightarrow{\normaloverrightarrow}