defpackage firrtl/ir-utils : import core import verse import firrtl/ir2 import bigint2 ;============== DEBUG STUFF ============================= public defmulti print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field|Module|Circuit) -> False public defmethod print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field|Module|Circuit) -> False : false public defmulti turn-off-debug (x:False) -> False ;public defmethod turn-off-debug (x:False) : false public defmulti turn-on-debug (x:False) ;public defmethod turn-on-debug (x:False) : false ;============== GENSYM STUFF ====================== defn generated? (s:String) -> False|Int : for i in 1 to length(s) - 1 find : val sub = substring(s,i + 1) s[i] == '_' and digits?(sub) and s[i - 1] != '_' defn digits? (s:String) -> True|False : val digits = "0123456789" var yes = true for c in s do : if not contains?(digits,c) : yes = false yes val gen-names = HashTable(symbol-hash) public defn firrtl-gensym (s:Symbol) -> Symbol : firrtl-gensym(s,HashTable(symbol-hash)) public defn firrtl-gensym (sym-hash:HashTable) -> Symbol : firrtl-gensym(`gen,sym-hash) public defn firrtl-gensym (s:Symbol,sym-hash:HashTable) -> Symbol : defn get-name (s:Symbol) -> Symbol : if key?(sym-hash,s) : val num = sym-hash[s] + 1 sym-hash[s] = num symbol-join([s delin num]) else : sym-hash[s] = 0 symbol-join([s delin 0]) val s* = to-string(s) val i* = generated?(s*) val nex = match(i*) : (i:False) : get-name(s) (i:Int) : get-name(to-symbol(substring(s*,0,i))) nex public defn get-sym-hash (m:InModule) -> HashTable : get-sym-hash(m,list()) public defn get-sym-hash (m:InModule,keywords:Streamable) -> HashTable : val sym-hash = HashTable(symbol-hash) for k in keywords do : sym-hash[k] = 0 defn add-name (s:Symbol) -> Symbol : val s* = to-string(s) val i* = generated?(s*) match(i*) : (i:False) : if key?(sym-hash,s) : val num = sym-hash[s] sym-hash[s] = max(num,0) else : sym-hash[s] = 0 (i:Int) : val name = to-symbol(substring(s*,0,i)) val digit = to-int(substring(s*,i + 1)) if key?(sym-hash,name) : val num = sym-hash[name] sym-hash[name] = max(num,digit) else : sym-hash[name] = digit s defn to-port (p:Port) : add-name(name(p)) defn to-stmt (s:Stmt) -> Stmt : map{to-stmt,_} $ map(add-name,s) to-stmt(body(m)) map(to-port,ports(m)) sym-hash ; ======== Expression Computation Library =========== public defn BoolType () : UIntType(IntWidth(1)) public val zero = UIntValue(BigIntLit(0),IntWidth(1)) public val one = UIntValue(BigIntLit(1),IntWidth(1)) public defn uint (i:Int) -> UIntValue : val num-bits = req-num-bits(i) val w = IntWidth(max(1,num-bits - 1)) UIntValue(BigIntLit(i),w) public defn sint (i:Int) -> SIntValue : val num-bits = req-num-bits(i) val w = IntWidth(max(1,num-bits)) SIntValue(BigIntLit(i),w) public defn AND (e1:Expression,e2:Expression) -> Expression : if e1 == e2 : e1 else if e1 == zero or e2 == zero : zero else if e1 == one : e2 else if e2 == one : e1 else : DoPrim(BIT-AND-OP,list(e1,e2),list(),UIntType(IntWidth(1))) public defn OR (e1:Expression,e2:Expression) -> Expression : if e1 == e2 : e1 else if e1 == one or e2 == one : one else if e1 == zero : e2 else if e2 == zero : e1 else : DoPrim(BIT-OR-OP,list(e1,e2),list(),UIntType(IntWidth(1))) public defn EQV (e1:Expression,e2:Expression) -> Expression : DoPrim(EQUIV-OP,list(e1,e2),list(),type(e1)) public defn MUX (p:Expression,e1:Expression,e2:Expression) -> Expression : Mux(p,e1,e2,mux-type(type(e1),type(e2))) public defn mux-type (e1:Expression,e2:Expression) -> Type : mux-type(type(e1),type(e2)) public defn mux-type (t1:Type,t2:Type) -> Type : if t1 == t2 : match(t1,t2) : (t1:UIntType,t2:UIntType) : UIntType(UnknownWidth()) (t1:SIntType,t2:SIntType) : SIntType(UnknownWidth()) (t1:VectorType,t2:VectorType) : VectorType(mux-type(type(t1),type(t2)),size(t1)) (t1:BundleType,t2:BundleType) : BundleType $ for (f1 in fields(t1),f2 in fields(t2)) map : Field(name(f1),flip(f1),mux-type(type(f1),type(f2))) else : UnknownType() public defn CAT (e1:Expression,e2:Expression) -> Expression : DoPrim(CONCAT-OP,list(e1,e2),list(),type(e1)) public defn NOT (e1:Expression) -> Expression : if e1 == one : zero else if e1 == zero : one else : DoPrim(EQUIV-OP,list(e1,zero),list(),UIntType(IntWidth(1))) public defn children (e:Expression) -> List : val es = Vector() defn f (e:Expression) : add(es,e) e map(f,e) to-list(es) public var mname : Symbol = `blah public defn exp-hash (e:Expression) -> Int : turn-off-debug(false) val i = symbol-hash(to-symbol(string-join(map(to-string,list(mname `.... e))))) ;val i = symbol-hash(to-symbol(to-string(e))) turn-on-debug(false) i public defn type-hash (t:Type) -> Int : symbol-hash(to-symbol(to-string(t))) public defn list-hash (l:List) -> Int : turn-off-debug(false) val i = symbol-hash(to-symbol(string-join(map(to-string,l)))) turn-on-debug(false) i ;===== Type Expansion Algorithms ========= public defn times (f1:Flip,f2:Flip) -> Flip : switch {_ == f2} : DEFAULT : f1 REVERSE : swap(f1) public defn swap (f:Flip) -> Flip : switch {_ == f} : DEFAULT : REVERSE REVERSE : DEFAULT public defmulti get-type (s:Stmt) -> Type public defmethod get-type (s:Stmt) -> Type : match(s) : (s:DefWire|DefPoison|DefRegister) : type(s) (s:DefNode) : type(value(s)) (s:DefMemory) : val depth = depth(s) ; Fields val addr = Field(`addr,DEFAULT,UIntType(IntWidth(ceil-log2(depth)))) val en = Field(`en,DEFAULT,BoolType()) val clk = Field(`clk,DEFAULT,ClockType()) val def-data = Field(`data,DEFAULT,data-type(s)) val rev-data = Field(`data,REVERSE,data-type(s)) val mask = Field(`mask,DEFAULT,create-mask(data-type(s))) val rmode = Field(`rmode,DEFAULT,UIntType(IntWidth(1))) val rdata = Field(`rdata,REVERSE,data-type(s)) val read-type = BundleType(to-list([rev-data,addr,en,clk])) val write-type = BundleType(to-list([def-data,mask,addr,en,clk])) val readwrite-type = BundleType(to-list([rmode,rdata,def-data,mask,addr,en,clk])) val mem-fields = Vector() for x in readers(s) do : add(mem-fields,Field(x,REVERSE,read-type)) for x in writers(s) do : add(mem-fields,Field(x,REVERSE,write-type)) for x in readwriters(s) do : add(mem-fields,Field(x,REVERSE,readwrite-type)) BundleType(to-list(mem-fields)) (s:DefInstance) : UnknownType() (s:Begin|Connect|BulkConnect|Stop|Print|Empty|IsInvalid) : UnknownType() public defn get-size (t:Type) -> Int : val x = match(t) : (t:BundleType) : var sum = 0 for f in fields(t) do : sum = sum + get-size(type(f)) sum (t:VectorType) : size(t) * get-size(type(t)) (t) : 1 x public defn get-valid-points (t1:Type,t2:Type,flip1:Flip,flip2:Flip) -> List<[Int,Int]> : ;println-all(["Inside with t1:" t1 ",t2:" t2 ",f1:" flip1 ",f2:" flip2]) match(t1,t2) : (t1:UIntType,t2:UIntType) : if flip1 == flip2 : list([0, 0]) else: list() (t1:SIntType,t2:SIntType) : if flip1 == flip2 : list([0, 0]) else: list() (t1:BundleType,t2:BundleType) : val points = Vector<[Int,Int]>() var ilen = 0 var jlen = 0 for i in 0 to length(fields(t1)) do : for j in 0 to length(fields(t2)) do : ;println(i) ;println(j) ;println(ilen) ;println(jlen) val f1 = fields(t1)[i] val f2 = fields(t2)[j] if name(f1) == name(f2) : val ls = get-valid-points(type(f1),type(f2),flip1 * flip(f1), flip2 * flip(f2)) for x in ls do : add(points,[x[0] + ilen, x[1] + jlen]) ;println(points) jlen = jlen + get-size(type(fields(t2)[j])) ilen = ilen + get-size(type(fields(t1)[i])) jlen = 0 to-list(points) (t1:VectorType,t2:VectorType) : val points = Vector<[Int,Int]>() var ilen = 0 var jlen = 0 for i in 0 to min(size(t1),size(t2)) do : val ls = get-valid-points(type(t1),type(t2),flip1,flip2) for x in ls do : add(points,[x[0] + ilen, x[1] + jlen]) ilen = ilen + get-size(type(t1)) jlen = jlen + get-size(type(t2)) to-list(points) ;============= Useful functions ============== public defn create-mask (dt:Type) -> Type : match(dt) : (t:VectorType) : VectorType(create-mask(type(t)),size(t)) (t:BundleType) : val fields* = for f in fields(t) map : Field(name(f),flip(f),create-mask(type(f))) BundleType(fields*) (t:UIntType|SIntType) : BoolType() ;============== Exceptions ===================== public definterface PassException <: Exception public defn PassException (s:String) : new PassException : defmethod print (o:OutputStream, this) : print(o, s) public defn PassExceptions (xs:Streamable) : PassException(string-join(xs, "\n")) ;============== Pass/Compiler Structs ============ public definterface Compiler public defmulti passes (c:Compiler) -> List public defmulti backend (c:Compiler) -> List defmethod passes (c:Compiler) : List() public defmulti with-output (c:Compiler) -> ((() -> False) -> False) defmethod with-output (c:Compiler) : 1 as ? public definterface Pass public defmulti pass (p:Pass) -> (Circuit -> Circuit) public defmethod pass (p:Pass) : fn (c:Circuit) : c public defmulti name (p:Pass) -> String public defmethod name (p:Pass) -> String : "--" public defmulti short-name (p:Pass) -> String public defmethod short-name (p:Pass) -> String : "--" public defmethod print (o:OutputStream, p:Pass) : print(o,name(p)) ;============== Various Useful Functions ============== public defn add-all (v1:Vector,v2:Vector) -> False : for x in v2 do : add(v1,x) public defn ceil-log2 (i:Long) -> Long : defn* loop (n:Long, l:Long) : if n < i : if l == 30 : to-long(31) else : loop(n * to-long(2), l + to-long(1)) else : l error("Log of negative number!") when i < to-long(0) loop(to-long $ 1, to-long $ 0) public defn abs (x:Long) -> Long : if x < to-long(0) : to-long(0) - x else : x public defn max (x:Long,y:Long) -> Long : if x < y : y else : x defn escape (s:String) -> String : val s* = Vector() add(s*,"\"");" for c in s do : if c == '\n' : add(s*,"\\n") else : add(s*,to-string(c)) add(s*,"\"");" string-join(s*) ;" ;============== PRINTERS =================================== defmethod print (o:OutputStream, d:Flip) : print{o, _} $ switch {d == _} : DEFAULT : "" REVERSE: "flip" defmethod print (o:OutputStream, d:Direction) : print{o, _} $ switch {d == _} : INPUT : "input" OUTPUT: "output" defmethod print (o:OutputStream, w:Width) : print{o, _} $ match(w) : (w:UnknownWidth) : "?" (w:IntWidth) : width(w) defmethod print (o:OutputStream, op:PrimOp) : print{o, _} $ switch {op == _} : ADD-OP : "add" SUB-OP : "sub" MUL-OP : "mul" DIV-OP : "div" MOD-OP : "mod" QUO-OP : "quo" REM-OP : "rem" ADD-WRAP-OP : "addw" SUB-WRAP-OP : "subw" LESS-OP : "lt" LESS-EQ-OP : "leq" GREATER-OP : "gt" GREATER-EQ-OP : "geq" EQUIV-OP : "eqv" NEQUIV-OP : "neqv" EQUAL-OP : "eq" NEQUAL-OP : "neq" ;MUX-OP : "mux" PAD-OP : "pad" AS-UINT-OP : "asUInt" AS-SINT-OP : "asSInt" DYN-SHIFT-LEFT-OP : "dshl" DYN-SHIFT-RIGHT-OP : "dshr" SHIFT-LEFT-OP : "shl" SHIFT-RIGHT-OP : "shr" CONVERT-OP : "cvt" NEG-OP : "neg" BIT-NOT-OP : "not" BIT-AND-OP : "and" BIT-OR-OP : "or" BIT-XOR-OP : "xor" BIT-AND-REDUCE-OP : "andr" BIT-OR-REDUCE-OP : "orr" BIT-XOR-REDUCE-OP : "xorr" CONCAT-OP : "cat" BIT-SELECT-OP : "bit" BITS-SELECT-OP : "bits" defmethod print (o:OutputStream, e:Expression) : match(e) : (e:Ref) : print(o, name(e)) (e:SubField) : print-all(o, [exp(e) "." name(e)]) (e:SubIndex) : print-all(o, [exp(e) "[" value(e) "]"]) (e:SubAccess) : print-all(o, [exp(e) "[" index(e) "]"]) (e:UIntValue) : print-all(o, ["UInt(" value(e) ")"]) (e:SIntValue) : print-all(o, ["SInt(" value(e) ")"]) (e:DoPrim) : print-all(o, [op(e) "("]) print-all(o, join(concat(args(e), consts(e)), ", ")) print(o, ")") (e:Mux) : print-all(o, ["mux(" cond(e) ", " tval(e) ", " fval(e) ")"]) (e:ValidIf) : print-all(o, ["validif(" cond(e) ", " value(e) ")"]) print-debug(o,e) defmethod print (o:OutputStream, c:Stmt) : val io = IndentedStream(o, 3) match(c) : (c:DefPoison) : print-all(o,["poison " name(c) " : " type(c)]) (c:DefWire) : print-all(o,["wire " name(c) " : " type(c)]) (c:DefRegister) : print-all(o,["reg " name(c) " : " type(c) ", " clock(c) ", " reset(c) ", " init(c)]) (c:DefMemory) : print-all(o,["mem " name(c) " : "]) print-debug(o,c) print-all(io,["\ndata-type: " data-type(c)]) print-all(io,["\ndepth: " depth(c)]) print-all(io,["\nwrite-latency: " write-latency(c)]) print-all(io,["\nread-latency: " read-latency(c)]) for r in readers(c) do : print-all(io,["\nreader: " r]) for w in writers(c) do : print-all(io,["\nwriter: " w]) for rw in readwriters(c) do : print-all(io,["\nread-writer: " rw]) (c:DefInstance) : print-all(o,["inst " name(c) " of " module(c)]) (c:DefNode) : print-all(o,["node " name(c) " = " value(c)]) (c:Conditionally) : if conseq(c) typeof Begin : print-all(o, ["when " pred(c) " :"]) print-debug(o,c) print(o,"\n") print(io,conseq(c)) else : print-all(o, ["when " pred(c) " : " conseq(c)]) print-debug(o,c) if alt(c) not-typeof Empty: print(o, "\nelse :") print(io, "\n") print(io,alt(c)) (c:Begin) : do(print{o,_}, join(body(c), "\n")) (c:Connect) : print-all(o, [loc(c) " <= " exp(c)]) (c:IsInvalid) : print-all(o, [exp(c) " is invalid"]) (c:BulkConnect) : print-all(o, [loc(c) " <- " exp(c)]) (c:Empty) : print(o, "skip") (c:Stop) : print-all(o, ["stop(" clk(c) ", " en(c) ", " ret(c) ")"]) (c:Print) : print-all(o, ["printf(" clk(c) ", " en(c) ", "]) ;" print-all(o, join(List(escape(string(c)),args(c)), ", ")) print(o, ")") if not c typeof Conditionally|Begin|Empty: print-debug(o,c) defmethod print (o:OutputStream, t:Type) : match(t) : (t:UnknownType) : print(o, "?") (t:ClockType) : print(o, "Clock") (t:UIntType) : match(width(t)) : (w:IntWidth) : print-all(o, ["UInt<" width(t) ">"]) (w) : print-all(o, ["UInt"]) (t:SIntType) : match(width(t)) : (w:IntWidth) : print-all(o, ["SInt<" width(t) ">"]) (w) : print-all(o, ["SInt"]) (t:BundleType) : print(o, "{") print-all(o, join(fields(t), ", ")) print(o, "}") (t:VectorType) : print-all(o, [type(t) "[" size(t) "]"]) print-debug(o,t) defmethod print (o:OutputStream, f:Field) : print-all(o, [flip(f) " " name(f) " : " type(f)]) print-debug(o,f) defmethod print (o:OutputStream, p:Port) : print-all(o, [direction(p) " " name(p) " : " type(p)]) print-debug(o,p) defmethod print (o:OutputStream, m:InModule) : print-all(o, ["module " name(m) " :"]) print-debug(o,m) print(o,"\n") val io = IndentedStream(o, 3) for p in ports(m) do : println(io,p) print(io,body(m)) defmethod print (o:OutputStream, m:ExModule) : print-all(o, ["extmodule " name(m) " :"]) print-debug(o,m) print(o,"\n") val io = IndentedStream(o, 3) for p in ports(m) do : println(io,p) defmethod print (o:OutputStream, c:Circuit) : print-all(o, ["circuit " main(c) " :"]) print-debug(o,c) print(o,"\n") val io = IndentedStream(o, 3) for m in modules(c) do : println(io, m) ;=================== MAPPERS =============================== public defn map (f: Type -> Type, t:?T&Type) -> T : val type = match(t) : (t:T&BundleType) : BundleType $ for p in fields(t) map : Field(name(p), flip(p), f(type(p))) (t:T&VectorType) : VectorType(f(type(t)), size(t)) (t) : t type as T&Type public defmulti map (f: Expression -> Expression, e:?T&Expression) -> T defmethod map (f: Expression -> Expression, e:Expression) -> Expression : match(e) : (e:SubField) : SubField(f(exp(e)), name(e), type(e)) (e:SubIndex) : SubIndex(f(exp(e)), value(e), type(e)) (e:SubAccess) : SubAccess(f(exp(e)), f(index(e)), type(e)) (e:DoPrim) : DoPrim(op(e), map(f, args(e)), consts(e), type(e)) (e:Mux) : Mux(f(cond(e)),f(tval(e)),f(fval(e)),type(e)) (e:ValidIf) : ValidIf(f(cond(e)),f(value(e)),type(e)) (e) : e public defmulti map (f: Symbol -> Symbol, c:?T&Stmt) -> T defmethod map (f: Symbol -> Symbol, c:Stmt) -> Stmt : match(c) : (c:DefWire) : DefWire(info(c),f(name(c)),type(c)) (c:DefPoison) : DefPoison(info(c),f(name(c)),type(c)) (c:DefRegister) : DefRegister(info(c),f(name(c)), type(c), clock(c), reset(c), init(c)) (c:DefMemory) : DefMemory(info(c),f(name(c)), data-type(c), depth(c), write-latency(c), read-latency(c), readers(c), writers(c), readwriters(c)) (c:DefNode) : DefNode(info(c),f(name(c)),value(c)) (c:DefInstance) : DefInstance(info(c),f(name(c)), module(c)) (c) : c public defmulti map (f: Expression -> Expression, c:?T&Stmt) -> T defmethod map (f: Expression -> Expression, c:Stmt) -> Stmt : match(c) : (c:DefRegister) : DefRegister(info(c),name(c), type(c), f(clock(c)), f(reset(c)), f(init(c))) (c:DefNode) : DefNode(info(c),name(c), f(value(c))) ;(c:DefInstance) : DefInstance(info(c),name(c), f(module(c))) (c:Conditionally) : Conditionally(info(c),f(pred(c)), conseq(c), alt(c)) (c:Connect) : Connect(info(c),f(loc(c)), f(exp(c))) (c:BulkConnect) : BulkConnect(info(c),f(loc(c)), f(exp(c))) (c:IsInvalid) : IsInvalid(info(c),f(exp(c))) (c:Stop) : Stop(info(c),ret(c),f(clk(c)),f(en(c))) (c:Print) : Print(info(c),string(c),map(f,args(c)),f(clk(c)),f(en(c))) (c) : c public defmulti map (f: Stmt -> Stmt, c:?T&Stmt) -> T defmethod map (f: Stmt -> Stmt, c:Stmt) -> Stmt : match(c) : (c:Conditionally) : Conditionally(info(c),pred(c), f(conseq(c)), f(alt(c))) (c:Begin) : Begin(map(f, body(c))) (c) : c public defmulti map (f: Width -> Width, c:?T&Expression) -> T defmethod map (f: Width -> Width, c:Expression) -> Expression : match(c) : (c:UIntValue) : UIntValue(value(c),f(width(c))) (c:SIntValue) : SIntValue(value(c),f(width(c))) (c) : c public defmulti map (f: Width -> Width, c:?T&Type) -> T defmethod map (f: Width -> Width, c:Type) -> Type : match(c) : (c:UIntType) : UIntType(f(width(c))) (c:SIntType) : SIntType(f(width(c))) (c) : c public defmulti map (f: Type -> Type, c:?T&Expression) -> T defmethod map (f: Type -> Type, c:Expression) -> Expression : match(c) : (c:Ref) : Ref(name(c),f(type(c))) (c:SubField) : SubField(exp(c),name(c),f(type(c))) (c:SubIndex) : SubIndex(exp(c),value(c),f(type(c))) (c:SubAccess) : SubAccess(exp(c),index(c),f(type(c))) (c:DoPrim) : DoPrim(op(c),args(c),consts(c),f(type(c))) (c:Mux) : Mux(cond(c),tval(c),fval(c),f(type(c))) (c:ValidIf) : ValidIf(cond(c),value(c),f(type(c))) (c) : c public defmulti map (f: Type -> Type, c:?T&Stmt) -> T defmethod map (f: Type -> Type, c:Stmt) -> Stmt : match(c) : (c:DefPoison) : DefPoison(info(c),name(c),f(type(c))) (c:DefWire) : DefWire(info(c),name(c),f(type(c))) (c:DefRegister) : DefRegister(info(c),name(c),f(type(c)),clock(c),reset(c),init(c)) (c:DefMemory) : DefMemory(info(c),name(c), f(data-type(c)), depth(c), write-latency(c), read-latency(c), readers(c), writers(c), readwriters(c)) (c) : c public defmulti mapr (f: Width -> Width, t:?T&Type) -> T defmethod mapr (f: Width -> Width, t:Type) -> Type : defn apply-t (t:Type) -> Type : map{f,_} $ map(apply-t,t) apply-t(t) public defmulti mapr (f: Width -> Width, s:?T&Stmt) -> T defmethod mapr (f: Width -> Width, s:Stmt) -> Stmt : defn apply-t (t:Type) -> Type : mapr(f,t) defn apply-e (e:Expression) -> Expression : map{f,_} $ map{apply-t,_} $ map(apply-e,e) defn apply-s (s:Stmt) -> Stmt : map{apply-t,_} $ map{apply-e,_} $ map(apply-s,s) apply-s(s) ;================= HELPER FUNCTIONS USING MAP =================== public defmulti do (f:Expression -> ?, e:Expression) -> False defmethod do (f:Expression -> ?, e:Expression) -> False : defn f* (x:Expression) : f(x) x map(f*,e) false public defmulti do (f:Expression -> ?, s:Stmt) -> False defmethod do (f:Expression -> ?, s:Stmt) -> False : defn f* (x:Expression) : f(x) x map(f*,s) false public defmulti do (f:Stmt -> ?, s:Stmt) -> False defmethod do (f:Stmt -> ?, s:Stmt) -> False : defn f* (x:Stmt) : f(x) x map(f*,s) false ; Not well defined - usually use dor on fields of a recursive type ;public defmulti dor (f:Expression -> ?, e:Expression) -> False ;defmethod dor (f:Expression -> ?, e:Expression) -> False : ; f(e) ; for x in e map : ; dor(f,x) ; x ; false ; ;public defmulti dor (f:Expression -> ?, s:Stmt) -> False ;defmethod dor (f:Expression -> ?, s:Stmt) -> False : ; defn f* (x:Expression) : ; dor(f,x) ; x ; map(f*,s) ; false ; ;public defmulti dor (f:Stmt -> ?, s:Stmt) -> False ;defmethod dor (f:Stmt -> ?, s:Stmt) -> False : ; f(s) ; defn f* (x:Stmt) : ; dor(f,x) ; x ; map(f*,s) ; false ; ;public defmulti sub-exps (s:Expression|Stmt) -> List ;defmethod sub-exps (e:Expression) -> List : ; val l = Vector() ; defn f (x:Expression) : add(l,x) ; do(f,e) ; to-list(l) ;defmethod sub-exps (e:Stmt) -> List : ; val l = Vector() ; defn f (x:Expression) : add(l,x) ; do(f,e) ; to-list(l) ; ;public defmulti sub-stmts (s:Stmt) -> List ;defmethod sub-stmts (s:Stmt) : ; val l = Vector() ; defn f (x:Stmt) : add(l,x) ; do(f,s) ; to-list(l) ;=================== ADAM OPS =============================== public defn split (s:String,c:Char) -> List : if not contains(to-list(s),c) : list(s) else : val index = label ret : var i = 0 for c* in to-list(s) do : if c* == c : ret(i) else : i = i + 1 ret(0) val h = substring(s,0,index) val t = substring(s,index + 1,length(s)) List(h,split(t,c)) public defn contains (l:List, c:Char) : label myret : for x in l do : if x == c : myret(true) false public defn merge! (a:HashTable, b:HashTable) : for e in b do : a[key(e)] = value(e) ;=================== VERILOG KEYWORDS ======================= public val v-keywords = HashTable(symbol-hash) v-keywords[`alias] = true v-keywords[`always] = true v-keywords[`always_comb] = true v-keywords[`always_ff] = true v-keywords[`always_latch] = true v-keywords[`and] = true v-keywords[`assert] = true v-keywords[`assign] = true v-keywords[`assume] = true v-keywords[`attribute] = true v-keywords[`automatic] = true v-keywords[`before] = true v-keywords[`begin] = true v-keywords[`bind] = true v-keywords[`bins] = true v-keywords[`binsof] = true v-keywords[`bit] = true v-keywords[`break] = true v-keywords[`buf] = true v-keywords[`bufif0] = true v-keywords[`bufif1] = true v-keywords[`byte] = true v-keywords[`case] = true v-keywords[`casex] = true v-keywords[`casez] = true v-keywords[`cell] = true v-keywords[`chandle] = true v-keywords[`class] = true v-keywords[`clocking] = true v-keywords[`cmos] = true v-keywords[`config] = true v-keywords[`const] = true v-keywords[`constraint] = true v-keywords[`context] = true v-keywords[`continue] = true v-keywords[`cover] = true v-keywords[`covergroup] = true v-keywords[`coverpoint] = true v-keywords[`cross] = true v-keywords[`deassign] = true v-keywords[`default] = true v-keywords[`defparam] = true v-keywords[`design] = true v-keywords[`disable] = true v-keywords[`dist] = true v-keywords[`do] = true v-keywords[`edge] = true v-keywords[`else] = true v-keywords[`end] = true v-keywords[`endattribute] = true v-keywords[`endcase] = true v-keywords[`endclass] = true v-keywords[`endclocking] = true v-keywords[`endconfig] = true v-keywords[`endfunction] = true v-keywords[`endgenerate] = true v-keywords[`endgroup] = true v-keywords[`endinterface] = true v-keywords[`endmodule] = true v-keywords[`endpackage] = true v-keywords[`endprimitive] = true v-keywords[`endprogram] = true v-keywords[`endproperty] = true v-keywords[`endspecify] = true v-keywords[`endsequence] = true v-keywords[`endtable] = true v-keywords[`endtask] = true v-keywords[`enum] = true v-keywords[`event] = true v-keywords[`expect] = true v-keywords[`export] = true v-keywords[`extends] = true v-keywords[`extern] = true v-keywords[`final] = true v-keywords[`first_match] = true v-keywords[`for] = true v-keywords[`force] = true v-keywords[`foreach] = true v-keywords[`forever] = true v-keywords[`fork] = true v-keywords[`forkjoin] = true v-keywords[`function] = true v-keywords[`generate] = true v-keywords[`genvar] = true v-keywords[`highz0] = true v-keywords[`highz1] = true v-keywords[`if] = true v-keywords[`iff] = true v-keywords[`ifnone] = true v-keywords[`ignore_bins] = true v-keywords[`illegal_bins] = true v-keywords[`import] = true v-keywords[`incdir] = true v-keywords[`include] = true v-keywords[`initial] = true v-keywords[`initvar] = true v-keywords[`inout] = true v-keywords[`input] = true v-keywords[`inside] = true v-keywords[`instance] = true v-keywords[`int] = true v-keywords[`integer] = true v-keywords[`interconnect] = true v-keywords[`interface] = true v-keywords[`intersect] = true v-keywords[`join] = true v-keywords[`join_any] = true v-keywords[`join_none] = true v-keywords[`large] = true v-keywords[`liblist] = true v-keywords[`library] = true v-keywords[`local] = true v-keywords[`localparam] = true v-keywords[`logic] = true v-keywords[`longint] = true v-keywords[`macromodule] = true v-keywords[`matches] = true v-keywords[`medium] = true v-keywords[`modport] = true v-keywords[`module] = true v-keywords[`nand] = true v-keywords[`negedge] = true v-keywords[`new] = true v-keywords[`nmos] = true v-keywords[`nor] = true v-keywords[`noshowcancelled] = true v-keywords[`not] = true v-keywords[`notif0] = true v-keywords[`notif1] = true v-keywords[`null] = true v-keywords[`or] = true v-keywords[`output] = true v-keywords[`package] = true v-keywords[`packed] = true v-keywords[`parameter] = true v-keywords[`pmos] = true v-keywords[`posedge] = true v-keywords[`primitive] = true v-keywords[`priority] = true v-keywords[`program] = true v-keywords[`property] = true v-keywords[`protected] = true v-keywords[`pull0] = true v-keywords[`pull1] = true v-keywords[`pulldown] = true v-keywords[`pullup] = true v-keywords[`pulsestyle_onevent] = true v-keywords[`pulsestyle_ondetect] = true v-keywords[`pure] = true v-keywords[`rand] = true v-keywords[`randc] = true v-keywords[`randcase] = true v-keywords[`randsequence] = true v-keywords[`rcmos] = true v-keywords[`real] = true v-keywords[`realtime] = true v-keywords[`ref] = true v-keywords[`reg] = true v-keywords[`release] = true v-keywords[`repeat] = true v-keywords[`return] = true v-keywords[`rnmos] = true v-keywords[`rpmos] = true v-keywords[`rtran] = true v-keywords[`rtranif0] = true v-keywords[`rtranif1] = true v-keywords[`scalared] = true v-keywords[`sequence] = true v-keywords[`shortint] = true v-keywords[`shortreal] = true v-keywords[`showcancelled] = true v-keywords[`signed] = true v-keywords[`small] = true v-keywords[`solve] = true v-keywords[`specify] = true v-keywords[`specparam] = true v-keywords[`static] = true v-keywords[`strength] = true v-keywords[`string] = true v-keywords[`strong0] = true v-keywords[`strong1] = true v-keywords[`struct] = true v-keywords[`super] = true v-keywords[`supply0] = true v-keywords[`supply1] = true v-keywords[`table] = true v-keywords[`tagged] = true v-keywords[`task] = true v-keywords[`this] = true v-keywords[`throughout] = true v-keywords[`time] = true v-keywords[`timeprecision] = true v-keywords[`timeunit] = true v-keywords[`tran] = true v-keywords[`tranif0] = true v-keywords[`tranif1] = true v-keywords[`tri] = true v-keywords[`tri0] = true v-keywords[`tri1] = true v-keywords[`triand] = true v-keywords[`trior] = true v-keywords[`trireg] = true v-keywords[`type] = true v-keywords[`typedef] = true v-keywords[`union] = true v-keywords[`unique] = true v-keywords[`unsigned] = true v-keywords[`use] = true v-keywords[`var] = true v-keywords[`vectored] = true v-keywords[`virtual] = true v-keywords[`void] = true v-keywords[`wait] = true v-keywords[`wait_order] = true v-keywords[`wand] = true v-keywords[`weak0] = true v-keywords[`weak1] = true v-keywords[`while] = true v-keywords[`wildcard] = true v-keywords[`wire] = true v-keywords[`with] = true v-keywords[`within] = true v-keywords[`wor] = true v-keywords[`xnor] = true v-keywords[`xor] = true v-keywords[`SYNTHESIS] = true v-keywords[`PRINTF_COND] = true v-keywords[`VCS] = true