diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/compilers.stanza | 4 | ||||
| -rw-r--r-- | src/main/stanza/custom-passes.stanza | 6 | ||||
| -rw-r--r-- | src/main/stanza/errors.stanza | 141 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 4 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 10 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 19 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 28 | ||||
| -rw-r--r-- | src/main/stanza/verilog.stanza | 24 |
8 files changed, 201 insertions, 35 deletions
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza index efa8c992..5a2e2278 100644 --- a/src/main/stanza/compilers.stanza +++ b/src/main/stanza/compilers.stanza @@ -56,9 +56,11 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> : ExpandIndexedConnects() ExpandWhens() InferWidths() + Pad() SplitExp() ToRealIR() - SpecialRename(`#,`_) + SpecialRename(`#,`__) + SpecialRename(`$,`_) Verilog(file(c)) ] diff --git a/src/main/stanza/custom-passes.stanza b/src/main/stanza/custom-passes.stanza index e4c3d9d3..3b6c28ff 100644 --- a/src/main/stanza/custom-passes.stanza +++ b/src/main/stanza/custom-passes.stanza @@ -45,7 +45,7 @@ defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Sym val sym = HashTable<Symbol,Int>(symbol-hash) val w1 = IntWidth(1) val t1 = UIntType(w1) - val u1 = UIntValue(1,w1) + val u1 = UIntValue(to-long $ 1,w1) defn when-coverage (s:Stmt) -> Stmt : match(s) : (s:Conditionally) : @@ -70,7 +70,7 @@ defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Sym if length(w-ls) != 0 : val reg-ref = Ref(reg-name,UIntType(IntWidth(length(w-ls)))) add{logic,_} $ DefRegister(FileInfo(),name(reg-ref),type(reg-ref)) - add{logic,_} $ OnReset(FileInfo(),reg-ref,UIntValue(0,IntWidth(length(w-ls)))) + add{logic,_} $ OnReset(FileInfo(),reg-ref,UIntValue(to-long $ 0,IntWidth(length(w-ls)))) for (x in w-ls, i in 0 to false) do : add{logic,_} $ DefWire(FileInfo(),name(x),type(x)) add{logic,_} $ Connect(FileInfo(),x,DoPrim(BIT-SELECT-OP,list(reg-ref),list(i),UIntType(w1))) @@ -80,7 +80,7 @@ defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Sym if length(i-ls) != 0 : for (x in i-ls, i in 0 to false) do : add{logic,_} $ DefWire(FileInfo(),name(x),type(x)) - add{logic,_} $ Connect(FileInfo(),x,UIntValue(0,UnknownWidth())) + add{logic,_} $ Connect(FileInfo(),x,UIntValue(to-long $ 0,UnknownWidth())) if instrument?[name(m)] : add{logic,_} $ Connect(FileInfo(),port-ref,concat-all(append(w-ls,i-ls))) diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza index 0795a2a9..aff22460 100644 --- a/src/main/stanza/errors.stanza +++ b/src/main/stanza/errors.stanza @@ -22,11 +22,6 @@ defpackage firrtl/errors : ; o pad's width is greater than value's width ; o widths are large enough to contain value -;AFTER LOWERING -; o All things connect to once -; o no reg -; o no accessors - ;AFTER ?????? ; o No combinational loops ; o cannot connect to a pad, or a register. only connct to a reference @@ -233,9 +228,8 @@ public defn check-high-form (c:Circuit,sym:Symbol) -> Circuit : (e:Ref|Subfield|Index) : false (e) : add(errors,InvalidIndex(info)) (e:DoPrim) : check-high-form-primop(e,errors,info) - ;; (e:UIntValue) : - ;; if value(e) < 0 : - ;; add(errors,NegUInt(info)) + (e:UIntValue) : + if value(e) < to-long $ 0 : add(errors,NegUInt(info)) (e) : false map(check-high-form-w{info,_:Width},e) map(check-high-form-t{info,_:Type},e) @@ -694,3 +688,134 @@ public defn check-genders (c:Circuit) -> Circuit : throw(PassExceptions(errors)) when not empty?(errors) c +;================= High Form Check ========================== +;AFTER LOWERING +; o All things connect to once +; o no reg +; o no accessors +; o only vecs are for memories +; o no bundles (future, will have them for mems) +; o +; +;public defstruct CheckLowForm <: Pass : +; sym : Symbol +;public defmethod pass (b:CheckLowForm) -> (Circuit -> Circuit) : check-low-form{_,sym(b)} +;public defmethod name (b:CheckLowForm) -> String : "Low Form Check" +;public defmethod short-name (b:CheckLowForm) -> String : "low-form-check" +; +;;----------------- Errors ------------------------ +;defn NotUnique (info:FileInfo, name:Symbol) : +; PassException $ string-join $ +; [info ": Reference " name " does not have a unique name."] +; +; +;;---------------- Helper Functions -------------- +; +;;--------------- Check Low Form Pass ------------------- +;public defn check-low-form (c:Circuit,sym:Symbol) -> Circuit : +; val errors = Vector<PassException>() +; +; defn check-high-form-w (info:FileInfo,w:Width) -> Width : +; match(w) : +; (w:IntWidth) : +; if width(w) < 0 : add(errors,NegWidth(info)) +; w +; (w) : w +; +; defn check-high-form-t (info:FileInfo,t:Type) -> Type : +; match(map(check-high-form-t{info,_},t)) : +; (t:VectorType) : +; if size(t) < 0 : add(errors,NegVecSize(info)) +; (t) : false +; map(check-high-form-w{info,_:Width},t) +; +; defn check-high-form-e (info:FileInfo,e:Expression,names:Vector<Symbol>) -> Expression : +; match(map(check-high-form-e{info,_,names},e)) : +; (e:Ref) : +; if not contains?(name(e),names) : +; add(errors,UndeclaredReference(info,name(e))) +; (e:Subfield) : +; match(exp(e)) : +; (e:Ref|Subfield|Index) : false +; (e) : add(errors,InvalidSubfield(info)) +; (e:Index) : +; match(exp(e)) : +; (e:Ref|Subfield|Index) : false +; (e) : add(errors,InvalidIndex(info)) +; (e:DoPrim) : check-high-form-primop(e,errors,info) +; (e:UIntValue) : +; if value(e) < to-long $ 0 : add(errors,NegUInt(info)) +; (e) : false +; map(check-high-form-w{info,_:Width},e) +; map(check-high-form-t{info,_:Type},e) +; e +; +; defn check-high-form-s (s:Stmt,names:Vector<Symbol>) -> Stmt : +; defn check-name (info:FileInfo,name:Symbol) -> False : +; if contains?(name,names) : add(errors,NotUnique(info,name)) +; val prefix = is-prefix?(name,names,sym) +; if prefix typeof Symbol : add(errors,IsPrefix(info,name,prefix as Symbol)) +; +; map(check-high-form-t{info(s),_:Type},s) +; +; map{check-high-form-s{_,names},_} $ { +; match(map(check-high-form-e{info(s),_,names},s)) : +; (s:DefWire|DefRegister) : +; check-name(info(s),name(s)) +; add(names,name(s)) +; (s:DefMemory) : +; check-name(info(s),name(s)) +; add(names,name(s)) +; if has-flip?(type(s)) : add(errors, MemWithFlip(info(s), name(s))) +; (s:DefInstance) : +; if not contains?(name(module(s) as Ref),map(name,modules(c))) : +; add(errors, ModuleNotDefined(info(s),name(module(s) as Ref))) +; check-name(info(s),name(s)) +; add(names,name(s)) +; (s:DefNode) : +; check-name(info(s),name(s)) +; add(names,name(s)) +; (s:DefAccessor) : +; check-name(info(s),name(s)) +; add(names,name(s)) +; (s:Connect) : +; check-valid-loc(info(s),loc(s)) +; (s:BulkConnect) : +; check-valid-loc(info(s),loc(s)) +; (s) : false +; s }() +; +; defn check-high-form-m (m:Module) -> False : +; val names = Vector<Symbol>() +; for m in modules(c) do : +; add(names,name(m)) +; for p in ports(m) do : +; add(names,name(p)) +; if name(p) == `reset : +; if direction(p) == OUTPUT : +; add(errors,WrongReset(info!(m),name(m))) +; else : +; if type(p) typeof UIntType : +; if width(type(p) as UIntType) != IntWidth(1) : +; add(errors,WrongReset(info!(m),name(m))) +; else : +; add(errors,WrongReset(info!(m),name(m))) +; map(check-high-form-t{info(p),_},type(p)) +; map(check-high-form-w{info(p),_},type(p)) +; +; +; +; add(names,`reset) +; match(m) : +; (m:ExModule) : false +; (m:InModule) : check-high-form-s(body(m),names) +; false +; +; var number-top-m = 0 +; for m in modules(c) do : +; if name(m) == main(c) : number-top-m = number-top-m + 1 +; check-high-form-m(m) +; if number-top-m != 1 : add(errors,NoTopModule(info!(c),main(c))) +; throw(PassExceptions(errors)) when not empty?(errors) +; c +; diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index 18e069b4..aeaecf47 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -73,10 +73,10 @@ public defstruct Index <: Expression : value: Int type: Type with: (as-method => true) public defstruct UIntValue <: Expression : - value: Int + value: Long width: Width public defstruct SIntValue <: Expression : - value: Int + value: Long width: Width public defstruct DoPrim <: Expression : op: PrimOp diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index cbfe106e..588efeac 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -81,6 +81,10 @@ defsyntax firrtl : int = (?x) when unwrap-token(x) typeof Int : unwrap-token(x) + ;Parses next form if long literal + intorlong = (?x) when unwrap-token(x) typeof Int|Long : + unwrap-token(x) + ;Parses next form if symbol sym = (?x) when unwrap-token(x) typeof Symbol : unwrap-token(x) @@ -107,6 +111,10 @@ defsyntax firrtl : int$ = (?i:#int ?rest ...) when empty?(rest) : i int$ != () : FPE(form, "Expected a single integer literal here.") + ;Error if not a single long integer + long$ = (?i:#intorlong ?rest ...) when empty?(rest) : to-long(i) + long$ != () : FPE(form, "Expected a single long integer literal here.") + ;Error if not a single width width$ = (?w:#width ?rest ...) when empty?(rest) : w width$ != () : FPE(form, "Expected a single width specifier here.") @@ -227,7 +235,7 @@ defsyntax firrtl : expop = (. ?f:#id!) : (fn (x) : Subfield(x, f, UnknownType())) ;Prefix Operators - expterm = (?t:#inttype(?v:#int$)) : + expterm = (?t:#inttype(?v:#long$)) : match(t) : (t:UIntType) : UIntValue(v, width(t)) (t:SIntType) : SIntValue(v, width(t)) diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza index c39a1ad1..1d209622 100644 --- a/src/main/stanza/ir-utils.stanza +++ b/src/main/stanza/ir-utils.stanza @@ -69,7 +69,26 @@ public defmulti name (p:Pass) -> String public defmulti short-name (p:Pass) -> String public defmethod print (o:OutputStream, p:Pass) : print(o,name(p)) + +;============== Various Useful Functions ============== + +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 to-int (x:Long) -> Int : + ;if x > to-long(2147483647) or x < to-long(–2147483648) : error("Long too big to convert to Int") + ;else : x + 0 ;============== PRINTERS =================================== diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 80035325..fb889cf4 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -999,7 +999,7 @@ defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable<Symbol,Int>) -> Stmt : to-list $ for (i in 0 to false, l in locs(s)) stream : Conditionally( info(s), - equality(ref,UIntValue(i,UnknownWidth())), + equality(ref,UIntValue(to-long $ i,UnknownWidth())), Connect(info(s),l,exp(s)), EmptyStmt() ) @@ -1013,7 +1013,7 @@ defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable<Symbol,Int>) -> Stmt : to-list $ for (i in 1 to false, e in tail(exps(s))) stream : Conditionally( info(s), - equality(ref,UIntValue(i,UnknownWidth())), + equality(ref,UIntValue(to-long $ i,UnknownWidth())), Connect(info(s),loc(s),e), EmptyStmt() ) @@ -1059,8 +1059,8 @@ public defmethod short-name (b:ExpandWhens) -> String : "expand-whens" ; ======== Expression Computation Library =========== -val zero = UIntValue(0,IntWidth(1)) -val one = UIntValue(1,IntWidth(1)) +val zero = UIntValue(to-long $ 0,IntWidth(1)) +val one = UIntValue(to-long $ 1,IntWidth(1)) defmethod equal? (e1:Expression,e2:Expression) -> True|False : match(e1,e2) : @@ -1501,7 +1501,6 @@ defmethod equal? (w1:Width,w2:Width) -> True|False : defn apply (a:Int|False,b:Int|False, f: (Int,Int) -> Int) -> Int|False : if a typeof Int and b typeof Int : f(a as Int, b as Int) else : false - defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Width> : defn contains? (n:Symbol,h:HashTable<Symbol,?>) -> True|False : key?(h,n) @@ -1682,14 +1681,14 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod match(width(e)) : (w:UnknownWidth) : val w* = VarWidth(firrtl-gensym(`w,width-name-hash)) - add(v,WGeq(w*,IntWidth(ceil-log2(value(e))))) + add(v,WGeq(w*,IntWidth(to-int $ to-string $ ceil-log2(value(e))))) UIntValue(value(e),w*) (w) : e (e:SIntValue) : match(width(e)) : (w:UnknownWidth) : val w* = VarWidth(firrtl-gensym(`w,width-name-hash)) - add(v,WGeq(w*,IntWidth(1 + ceil-log2(abs(value(e)))))) + add(v,WGeq(w*,IntWidth(1 + to-int $ to-string $ ceil-log2(abs(value(e)))))) SIntValue(value(e),w*) (w) : e (e) : e @@ -1869,10 +1868,10 @@ public defmethod pass (b:SplitExp) -> (Circuit -> Circuit) : split-exp public defmethod name (b:SplitExp) -> String : "Split Expressions" public defmethod short-name (b:SplitExp) -> String : "split-expressions" -defn full-name (e:Expression) -> Symbol : +defn full-name (e:Expression) -> Symbol|False : match(e) : (e:WRef) : name(e) - (e:WSubfield) : to-symbol $ string-join([full-name(exp(e)) "." name(e)]) + (e:WSubfield) : false (e) : error("Non-supported expression.") defn split-exp (c:Circuit) : @@ -1959,19 +1958,26 @@ public defn special-rename (original-sym:Symbol,new-sym:Symbol,c:Circuit) : else : if substring(st,0,length(os)) == os : add(y,ns) + println(st) + println(substring(st,length(os),length(st))) rename(substring(st,length(os),length(st))) else : add(y,substring(st,0,1)) rename(substring(st,1,length(st))) rename(to-string(s)) to-symbol $ string-join $ to-list(y) + defn to-type (t:Type) -> Type : + match(map(to-type,t)) : + (t:BundleType) : BundleType $ + for f in fields(t) map : Field(rename(name(f)),flip(f),type(f)) + (t) : t defn to-exp (e:Expression) -> Expression : - match(map(to-exp,e)) : + map{to-type,_} $ match(map(to-exp,e)) : (e:Ref) : Ref(rename(name(e)), type(e)) (e:Subfield) : Subfield(exp(e),rename(name(e)),type(e)) (e) : e defn to-stmt (s:Stmt) -> Stmt : - match(map(to-exp,s)) : + map{to-type,_} $ match(map(to-exp,s)) : (s:DefWire) : DefWire(info(s),rename(name(s)),type(s)) (s:DefRegister) : DefRegister(info(s),rename(name(s)),type(s)) (s:DefInstance) : DefInstance(info(s),rename(name(s)),module(s)) diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza index bee10177..50ea1fc1 100644 --- a/src/main/stanza/verilog.stanza +++ b/src/main/stanza/verilog.stanza @@ -24,7 +24,10 @@ defn width! (t:Type) -> Int : defn emit (w:Width) -> String : match(w) : - (w:IntWidth) : string-join $ ["[" width(w) ":0]"] ;TODO check if need to special case 0 or 1 width wires + (w:IntWidth) : + if width(w) >= 1 : string-join $ ["[" width(w) - 1 ":0]"] ;TODO check if need to special case 0 or 1 width wires + else : "" + (w) : error("Non-supported width type.") defn get-width (t:Type) -> String : @@ -77,15 +80,15 @@ defn emit (e:Expression) -> String : val x = args(e)[0] val w = width!(type(x)) val diff = consts(e)[0] - w - ["{" diff "{" x "[" w - 1 "]}," emit(x)] + ["{{" diff "{" emit(x) "[" w - 1 "]}}, " emit(x) " }"] AS-UINT-OP : - ["$unsigned(" emit(args(e)[0]) " "] + ["$unsigned(" emit(args(e)[0]) ")"] AS-SINT-OP : - ["$signed(" emit(args(e)[0]) " "] + ["$signed(" emit(args(e)[0]) ")"] DYN-SHIFT-LEFT-OP : [emit(args(e)[0]) " << " emit(args(e)[1])] DYN-SHIFT-RIGHT-OP : [emit(args(e)[0]) " >> " emit(args(e)[1])] - SHIFT-LEFT-OP : [emit(args(e)[0]) " << " emit(args(e)[1])] - SHIFT-RIGHT-OP : [emit(args(e)[0]) " >> " emit(args(e)[1])] + SHIFT-LEFT-OP : [emit(args(e)[0]) " << " consts(e)[0]] + SHIFT-RIGHT-OP : [emit(args(e)[0]) " >> " consts(e)[0]] NEG-OP : ["-{" emit(args(e)[0]) "}"] CONVERT-OP : match(type(args(e)[0])) : @@ -239,12 +242,15 @@ defn emit-module (m:InModule) : println-all(a) for x in insts do : - println-all([" " value(x) " " key(x) ".clk(clk),"]) + println-all([" " value(x) " " key(x) " ("]) + print(" ") + print-all([".clk( clk )"]) for (y in inst-ports[key(x)],i in 1 to false) do : + print(",\n") print(" ") print-all(y) - if length(inst-ports[key(x)]) != i : - print(",\n") + ;if length(inst-ports[key(x)]) != i : + ;print(",\n") println("\n );") if length(updates) != 0 : |
