diff options
Diffstat (limited to 'Master/texmf-dist/doc/latex/circuit-macros/examples/CanLogic.m4')
-rw-r--r-- | Master/texmf-dist/doc/latex/circuit-macros/examples/CanLogic.m4 | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/circuit-macros/examples/CanLogic.m4 b/Master/texmf-dist/doc/latex/circuit-macros/examples/CanLogic.m4 new file mode 100644 index 00000000000..88e26469282 --- /dev/null +++ b/Master/texmf-dist/doc/latex/circuit-macros/examples/CanLogic.m4 @@ -0,0 +1,158 @@ +.PS +# CanLogic +log_init +divert(-1) +########################################################################### + Macros for automatically drawing 2-layer + Boolean functions + + Style parameters +define(`dotrad_',(0.01*scale)) +define(`gatelineth',1) +define(`lineth',0.5) +define(`inputsep',`2*jog') +define(`jog',`(AND_ht/2)*L_unit') + + `CanLogic(layer gate type,[N], + output gate type,[N], + term,term,...) + This is the driver macro. Terms are + strings of variables or of variables + preceded by the ~ character. Each + variable is one letter e.g. + CanLogic(NAND,,OR,N,abcd,a~b,c,~ad)' +define(`CanLogic', + `define(`terms',`shift(shift(shift(shift($@))))') +# Determine required input variables and negated +# variables + Loopover_(`t_',`varloop(`v_',`define(X`'v_)',`define(XN`'v_)',t_)',terms) +# Draw the inputs with NOT gates as necessary + PrevInput: Here-(inputsep,0) + Loopover_(`t_',`varloop(`v_', + `ifdef(D`'v_,,`ifdef(XN`'v_,`DrawInNotIn(v_)',`DrawIn(v_)')')', + `ifdef(D`'v_,,`ifdef(X`'v_,`DrawInNotIn(v_)',`DrawNotIn(v_)')')', t_)', + terms) +# Draw 2nd-layer gates + right_ + LastGateSE: PrevInput+(5*jog,-(AND_wd*L_unit*1.5)) dnl + Loopover_(`t_', + `define(`termcount',m4Lx)DrawLayerGate(G`'termcount,$1,$2,t_)', + terms) +# Draw output gate + linethick = gatelineth + OP: m4xpand(`$3'_gate(termcount,$4)) with .Out at \ + 0.5<G1.Out,G`'termcount.Out> + (jog/2*(termcount+3)+AND_wd*L_unit,0) + Out: Here + linethick = lineth +# Connect 2nd-layer gates to the output gate + VectorConnect(G,termcount,OP) +# Connect the inputs and negated inputs to +# 2nd-layer gates + Loopover_(`t_',`ConnectInputs(G`'m4Lx,t_)',terms) +# Clean up + Loopover_(`t_',`DeleteLogDefs(t_)',terms) + ') + `VectorConnect(number of 2nd layer gates, + common 2nd layer gate name, + output gate name) + Connect the 2nd-layer gate outputs to the + output gate inputs' +define(`VectorConnect', + `for_(1,`$2',1, + `line from `$1'm4x.Out right `$3'.In1.x-`$1'm4x.Out.x \ + - jog/2*(`$2'+1-abs(2*m4x-`$2'-1)) \ + then down `$1'm4x.Out.y - `$3'.In`'m4x.y then to `$3'.In`'m4x ')') + + Draw and label a non-inverted input +define(`DrawIn', + `PrevInput: PrevInput+(inputsep,0) + In`'$1: PrevInput + "$$1$" ljust at PrevInput # Maybe labels should be done externally + Int`'$1: PrevInput + define(D`'$1)') + + Draw and label an inverted input +define(`DrawNotIn', + `PrevInput: PrevInput+(inputsep,0) + In`'$1: PrevInput + "$$1$" ljust at PrevInput # Maybe labels should be done externally + line down_ 2*jog from PrevInput + linethick = gatelineth + NOT_gate + InNt`'$1: Here + linethick = lineth + define(D`'$1)') + Draw and label an input that is required both + inverted and uninverted. +define(`DrawInNotIn', + `PrevInput: PrevInput+(inputsep,0) + In`'$1: PrevInput + "$$1$" ljust at PrevInput # Maybe labels should be done externally + line from PrevInput down jog + Int`'$1: dot + PrevInput: PrevInput+(inputsep,0) + line to (PrevInput,Here) then down_ jog + linethick = gatelineth + NOT_gate + linethick = lineth + InNt`'$1: Here + define(D`'$1)') + `varloop(`var',ifnotnegated,ifnegated,term) + Loop over term variables performing actions' +define(`varloop',`ifelse(`$4',,,substr(`$4',0,1),~, + `define(`$1',substr($4,1,1)) $3 + varloop(`$1',`$2',`$3',substr($4,2))', + `define(`$1',substr($4,0,1)) $2 + varloop(`$1',`$2',`$3',substr($4,1))')')') + + Count gate inputs and mark last appearance +define(`Countinputs',`varloop(`v_', + `define(`incount',incr(incount)) define(Last`'v_,`$1')', + `define(`incount',incr(incount)) define(LastN`'v_,`$1')',$2)') + + Draw a 2nd layer gate +define(`DrawLayerGate', + `define(`incount',0) dnl + Countinputs($1,$4) dnl + ifelse(incount,1, + `LastGateSE: LastGateSE-(0,jog) + $1: [ In1:Here; line right AND_wd*L_unit; Out: Here] \ + with .Out at LastGateSE', + `LastGateSE: LastGateSE-(0,jog+AND_ht*L_unit) + linethick = gatelineth + $1: m4xpand(`$2'_gate(incount,$3)) with .se at LastGateSE + linethick = lineth ')') + + Connect this gate to its input lines +define(`ConnectInputs',`define(`innum',0) varloop(`v_', + `define(`innum',incr(innum)) + line from `$1'.In`'innum to (In`'v_,`$1'.In`'innum)dnl + ifelse(`$1',m4xpand(Last`'v_),`then to In`'v_',`; dot')', + `define(`innum',incr(innum)) + line from `$1'.In`'innum to (InNt`'v_,`$1'.In`'innum)dnl + ifelse(`$1',m4xpand(LastN`'v_), `then to InNt`'v_', `; dot')',$2)') + + Delete definitions to allow more than one + circuit per diagram +define(`DeleteLogDefs',`varloop(`v_', + `undefine(Last`'v_) undefine(D`'v_) undefine(X`'v_)', + `undefine(LastN`'v_) undefine(D`'v_) undefine(XN`'v_)',$1)') + + Thanks to Alexander Ray for suggesting the + need for something like these macros +########################################################################### +divert(0)dnl + + linethick = lineth + +[ CanLogic(AND,,OR,,abcd,~ba,c,d~a) #; line right jog from Out "$f$" above + ] +{`"\tt CanLogic(AND,,OR,,abcd,\char126{}ba,c,d\char126{}a)"' \ + at last [].s -(0,11bp__)} + +[ CanLogic(OR,N,NAND,,ab~c,a~bc,ac,~d) #; line right jog from Out "$f$" above + ] with .sw at last [].se+(0.5,0) +{`"\tt CanLogic(OR,N,NAND,,ab\char126{}c,a\char126{}bc,ac,\char126{}d)"' \ + at last [].s - (0,11bp__)} + +.PE |