load "Int"; exception notdone; datatype hexp_t = x_num of int | x_true | x_false | x_net of string ; fun sfold f nil = "" | sfold f [item] = f item | sfold f (h::t) = (f h) ^ ", " ^ (sfold f t) ; fun xToStr (x_num n) = Int.toString n | xToStr (x_true) = "true" | xToStr (x_false) = "false" | xToStr (x_net s) = s | xToStr (_) = "??" ; fun printgate (id, contacts) = print(" " ^ id ^ "(" ^ sfold xToStr contacts ^ ");\n"); val k = ref 0; val gates = ref nil; fun loggate g = (printgate g; gates := g :: !gates); fun funique id = id ^ Int.toString(!k) before k := !k + 1; fun newnet() = x_net(funique "n"); fun gen_gate(id, contacts) = let val r = x_net(funique "g") val _ = loggate(id, r :: contacts) in r end ; fun gen_buffer(a, b) = loggate("BUF", [a, b]); fun gen_and2(x_false, b) = x_false | gen_and2(x_true, b) = b | gen_and2(a, x_false) = x_false | gen_and2(a, x_true) = a | gen_and2(a, b) = gen_gate("AND2", [a, b]); ; fun gen_not(x_true) = x_false | gen_not(x_false) = x_true | gen_not(a) = gen_gate("INV", [a]) ; fun gen_or2(x_false, b) = b | gen_or2(x_true, b) = x_true | gen_or2(a, x_false) = a | gen_or2(a, x_true) = x_true | gen_or2(a, b) = gen_gate("OR2", [a, b]); ; fun gen_mux2(x_true, l, r) = l | gen_mux2(x_false, l, r) = r | gen_mux2(g, l, r) = if l=r then l else gen_gate("MUX2", [g, l, r]) ; fun gen_dff(a) = gen_gate("DFF", [a, x_net "clk"]); (* Build converts an expression into logic gates. * It should perhaps check for sub-expressions already made ! *) fun build (Num n) = if n=0 then x_false else x_true | build (Net s) = x_net s | build (Inv v) = gen_not(build v) | build (Diadic(D_and, a, b)) = gen_and2(build a, build b) | build (Diadic(D_or, a, b)) = gen_or2(build a, build b) | build (Diadic(D_xor, a, b)) = gen_xor2(build a, build b) | build (Query(g, a, b)) = gen_mux2(build g, build a, build b) ; (* end of gatebuilder *)