diff options
| author | Adam Izraelevitz | 2015-07-17 16:49:22 -0700 |
|---|---|---|
| committer | Adam Izraelevitz | 2015-07-17 16:49:22 -0700 |
| commit | 70567d4d57ac178660fbef0ef660069b52857562 (patch) | |
| tree | ac0ed0127ddb99a72cbc760f6be97b99c574d018 /src | |
| parent | 98bb81d9d99150a80c77ed8f22d44748a02df628 (diff) | |
Datapath compiles with Chisel 2.0 -> FIRRTL -> Verilog!
Had to separate initialization check pass
Need to write dead code elimination pass
Added LongWidth to support dshl that are huge
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/compilers.stanza | 1 | ||||
| -rw-r--r-- | src/main/stanza/errors.stanza | 66 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 8 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 5 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 12 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 206 | ||||
| -rw-r--r-- | src/main/stanza/verilog.stanza | 20 |
7 files changed, 231 insertions, 87 deletions
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza index d65e7718..db6781c5 100644 --- a/src/main/stanza/compilers.stanza +++ b/src/main/stanza/compilers.stanza @@ -65,6 +65,7 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> : RemoveSpecialChars() CheckHighForm() CheckLowForm() + CheckInitialization() Verilog(file(c)) ] diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza index e36ec06d..e36d52a4 100644 --- a/src/main/stanza/errors.stanza +++ b/src/main/stanza/errors.stanza @@ -827,3 +827,69 @@ public defn check-low-form (c:Circuit) -> Circuit : throw(PassExceptions(errors)) when not empty?(errors) c + +;;================ Initialization Check ================== +; Error on all componenents that are not connected to. + +public defstruct CheckInitialization <: Pass +public defmethod pass (b:CheckInitialization) -> (Circuit -> Circuit) : check-init +public defmethod name (b:CheckInitialization) -> String : "Check Initialization" +public defmethod short-name (b:CheckInitialization) -> String : "check-init" + +;----------------- Errors ------------------------ + +defn RefNotInitialized (info:FileInfo, name:Symbol) : + PassException $ string-join $ + [info ": Reference " name " is not fully initialized."] + +;------------ Helper Functions ------------- + +;------------ Pass ------------------ + +public defn check-init (c:Circuit) : + val errors = Vector<PassException>() + + defn check-init-m (m:InModule) : + val init? = HashTable<Symbol,FileInfo|True>(symbol-hash) + defn get-name (e:Expression) -> Symbol : + match(e) : + (e:Ref) : name(e) + (e:Subfield) : symbol-join([get-name(exp(e)) `. name(e)]) + (e) : error("Shouldn't be here") + + defn check-init-s (s:Stmt) : + do(check-init-s,s) + match(s) : + (s:DefWire|DefRegister) : init?[name(s)] = info(s) + (s:DefAccessor) : + if acc-dir(s) == WRITE : init?[name(s)] = info(s) + (s:DefInstance) : + for f in fields(type(module(s)) as BundleType) do : + if flip(f) == REVERSE : + init?[symbol-join([name(s) `. name(f)])] = info(s) + (s:Connect) : + init?[get-name(loc(s))] = true + (s) : false + + for p in ports(m) do : + if direction(p) == OUTPUT : + init?[name(p)] = info(p) + + check-init-s(body(m)) + + for x in init? do : + match(value(x)) : + (v:FileInfo) : add(errors, RefNotInitialized(v,key(x))) + (v) : false + + for m in modules(c) do : + match(m) : + (m:InModule) : check-init-m(m) + (m) : false + + 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 e57c5f74..15666a9a 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -7,6 +7,7 @@ public defmethod info! (x:?) : FileInfo() public val vector-expand-delin = `$ public val bundle-expand-delin = `$ +public val module-expand-delin = `$ public val scope-delin = `% public val temp-delin = `! public val inline-delin = `^ @@ -29,6 +30,8 @@ public definterface Width public defstruct UnknownWidth <: Width public defstruct IntWidth <: Width : width: Int +public defstruct LongWidth <: Width : + width : Long public definterface PrimOp public val ADD-OP = new PrimOp @@ -174,15 +177,16 @@ public defstruct Port : public definterface Module public defmulti name (m:Module) -> Symbol public defmulti ports (m:Module) -> List<Port> +public defmulti info (m:Module) -> FileInfo public defstruct InModule <: Module : - info: FileInfo + info: FileInfo with: (as-method => true) name: Symbol with: (as-method => true) ports: List<Port> with: (as-method => true) body: Stmt public defstruct ExModule <: Module : - info: FileInfo + info: FileInfo with: (as-method => true) name: Symbol with: (as-method => true) ports: List<Port> with: (as-method => true) diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index 96c50c3c..5b7c1106 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -210,7 +210,10 @@ defsyntax firrtl : accdir = (rdwr) : RDWR defrule width : - width = (?x:#int) : IntWidth(x) + width = (?x:#intorlong) : + match(x) : + (x:Int) : IntWidth(x) + (x:Long) : LongWidth(x) width = (?) : UnknownWidth() ;Main Statement Productions diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza index bd8a0fd6..9a983cff 100644 --- a/src/main/stanza/ir-utils.stanza +++ b/src/main/stanza/ir-utils.stanza @@ -117,6 +117,7 @@ defmethod print (o:OutputStream, w:Width) : match(w) : (w:UnknownWidth) : "?" (w:IntWidth) : width(w) + (w:LongWidth) : width(w) defmethod print (o:OutputStream, op:PrimOp) : print{o, _} $ @@ -451,13 +452,12 @@ public defn merge!<?K,?V> (a:HashTable<?K,?V>, b:HashTable<K,V>) : for e in b do : a[key(e)] = value(e) -public defn pow (x:Int,y:Int) -> Int : +public defn pow (x:Long,y:Long) -> Long : var x* = to-long(1) - var y* = to-long(y) + var y* = y while y* != to-long(0) : - x* = x* * to-long(x) - y* = y* - to-long(1) - if x* > to-long(2147483647) : error("Value too big for Int") - else : to-int $ to-string(x*) + x* = times(x*,x) + y* = minus(y*,to-long(1)) + x* diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index c03e2194..7002d7aa 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -295,19 +295,19 @@ public defmethod short-name (b:RemoveSpecialChars) -> String : "rem-spec-chars" defn get-new-string (n:Char) -> String : switch {n == _} : ;'_' : "__" - '~' : "_A" - '!' : "_B" - '@' : "_C" - '#' : "_D" - ;'$' : "_E" - '%' : "_F" - '^' : "_G" - '*' : "_H" - '-' : "_I" - '+' : "_J" - '=' : "_K" - '?' : "_L" - '/' : "_M" + '~' : "$A" + '!' : "$B" + '@' : "$C" + '#' : "$D" + ;'$' : "$E" + '%' : "$F" + '^' : "$G" + '*' : "$H" + '-' : "$I" + '+' : "$J" + '=' : "$K" + '?' : "$L" + '/' : "$M" else : to-string(n) ;------------ Pass ------------------ @@ -1378,16 +1378,6 @@ defn reduce-or (l:List<Expression>) -> Expression : ; kinds: Used to know the kind of reference, so we know whether we should error if it isn't initialized. We also know how we should declare the refernce. ; enables:Calculated off of assigns. -;----------------- Errors ------------------------ - -defn RefNotInitialized (info:FileInfo, name:Symbol) : - PassException $ string-join $ - [info ": Reference " name " is not fully initialized."] - -defn RefNotConnected (info:FileInfo, name:Symbol) : - PassException $ string-join $ - [info ": Reference " name " is never connected to."] - ;---------------- Helper Functions -------------- defn get-read-enable (sym:Symbol,table:HashTable<Symbol,SymbolicValue>) -> Expression : defn get-single-read-enable (sym:Symbol,sv:SymbolicValue) -> Expression : @@ -1497,15 +1487,13 @@ defn build-tables (s:Stmt, ;--------------- Expand Whens Pass ------------------- public defn expand-whens (c:Circuit) -> Circuit : - val errors = Vector<PassException>() defn expand-whens (ports:List<Port>, table:HashTable<Symbol,SymbolicValue>,cons:Vector<Stmt>) -> False : for p in ports do : if direction(p) == OUTPUT : val ref = WRef(name(p),type(p),PortKind(),FEMALE) - if has-nul?(table[name(p)]) : - add(errors,RefNotInitialized(info(p), name(p))) - else : add{cons,_} $ Connect(FileInfo(),ref,to-exp(table[name(p)]) as Expression) + if not has-nul?(table[name(p)]) : + add{cons,_} $ Connect(FileInfo(),ref,to-exp(table[name(p)]) as Expression) defn expand-whens (s:Stmt, table:HashTable<Symbol,SymbolicValue>,decs:Vector<Stmt>,cons:Vector<Stmt>) -> Stmt : match(map(expand-whens{_,table,decs,cons},s)) : @@ -1513,9 +1501,8 @@ public defn expand-whens (c:Circuit) -> Circuit : (s:DefWire) : add(decs,s) val ref = WRef(name(s),type(s),NodeKind(),FEMALE) - if has-nul?(table[name(s)]) : - add(errors,RefNotInitialized(info(s), name(s))) - else : add{cons,_} $ Connect(info(s),ref,to-exp(table[name(s)]) as Expression) + if not has-nul?(table[name(s)]) : + add{cons,_} $ Connect(info(s),ref,to-exp(table[name(s)]) as Expression) (s:DefRegister) : add(decs,s) val e = to-exp(table[name(s)]) @@ -1527,8 +1514,7 @@ public defn expand-whens (c:Circuit) -> Circuit : add{cons,_} $ Connect(info(s),ref,e) else : add{cons,_} $ Conditionally(info(s),en,Connect(info(s),ref,e),EmptyStmt()) - (e:False) : - add(errors,RefNotConnected(info(s), name(s))) + (e:False) : false (s:DefAccessor) : add(decs,s) val t = type(type(source(s)) as VectorType) @@ -1543,8 +1529,7 @@ public defn expand-whens (c:Circuit) -> Circuit : add{cons,_} $ Connect(info(s),ref,e) else : add{cons,_} $ Conditionally(info(s),en,Connect(info(s),ref,e),EmptyStmt()) - (e:False) : - add(errors,RefNotConnected(info(s), n)) + (e:False) : false (s:DefInstance) : add(decs,s) for f in fields(type(module(s)) as BundleType) map : @@ -1554,9 +1539,8 @@ public defn expand-whens (c:Circuit) -> Circuit : val f = to-symbol(split(to-string(n),'.')[1]) val ref = WRef(x,type(module(s)),InstanceKind(),FEMALE) val sref = WSubfield(ref,f,bundle-field-type(type(module(s)),f),FEMALE) - if has-nul?(table[n]) : - add(errors,RefNotInitialized(info(s), n)) - else : add{cons,_} $ Connect(info(s),sref,to-exp(table[n]) as Expression) + if not has-nul?(table[n]) : + add{cons,_} $ Connect(info(s),sref,to-exp(table[n]) as Expression) (s:Connect|Conditionally|OnReset|Begin|EmptyStmt) : false s @@ -1577,6 +1561,7 @@ public defn expand-whens (c:Circuit) -> Circuit : build-tables(body(m),assign,resets,flattn,rsignals) for x in assign do : assign[key(x)] = optimize(value(x)) for x in resets do : resets[key(x)] = optimize(value(x)) + ;val enables = get-enables(assign,kinds) ;for x in enables do : enables[key(x)] = optimize(value(x)) @@ -1598,9 +1583,69 @@ public defn expand-whens (c:Circuit) -> Circuit : val modules* = for m in modules(c) map : expand-whens(m) - throw(PassExceptions(errors)) when not empty?(errors) + ;throw(PassExceptions(errors)) when not empty?(errors) c* +;;================ Module Duplication ================== +; Duplicates modules so that no module is instantiated +; more than once. + +public defstruct ModuleDuplication <: Pass +public defmethod pass (b:ModuleDuplication) -> (Circuit -> Circuit) : module-duplication +public defmethod name (b:ModuleDuplication) -> String : "Module Duplication" +public defmethod short-name (b:ModuleDuplication) -> String : "mod-dup" + +;------------ Helper Functions ------------- + +;------------ Pass ------------------ + +public defn module-duplication (c:Circuit) : + val modules* = Vector<Module>() + val m-names = HashTable<Symbol,Int>(symbol-hash) + defn rename (n:Symbol) -> Symbol : + val int = get?(m-names,n,0) + m-names[n] = int + 1 + val n* = symbol-join([n module-expand-delin int]) + val m = for x in modules(c) find : name(x) == n + match(m) : + (m:InModule) : add(modules*,InModule(info(m),n*, ports(m), rename-s(body(m)))) + (m:ExModule) : add(modules*,ExModule(info(m),n*, ports(m))) + (m:False) : error("Shouldn't be here") + n* + + defn rename-e (e:Expression) -> Expression : + match(e) : + (e:Ref) : Ref(rename(name(e)),type(e)) + (e) : error("Shouldn't be here") + defn rename-s (s:Stmt) -> Stmt : + match(s) : + (s:DefInstance) : DefInstance(info(s),name(s),rename-e(module(s))) + (s) : map(rename-s,s) + + val top = for m in modules(c) find : name(m) == main(c) + match(top) : + (m:InModule) : add(modules*,InModule(info(m),name(m), ports(m), rename-s(body(m)))) + (m:ExModule) : m + (m:False) : error("Shouldn't be here") + + Circuit(info(c),to-list(modules*), main(c)) + + +;;================ Deadcode Elimination =================== +; Walks the circuit, starting from the outputs from the top +; level module. All components that are not reached are +; deleted + +public defstruct DeadcodeElimination <: Pass +public defmethod pass (b:DeadcodeElimination) -> (Circuit -> Circuit) : deadcode-elimination +public defmethod name (b:DeadcodeElimination) -> String : "Deadcode Elimination" +public defmethod short-name (b:DeadcodeElimination) -> String : "deadcode-elim" + +;------------ Helper Functions ------------- + +;------------ Pass ------------------ + +public defn deadcode-elimination (c:Circuit) : c ;;================ INFER WIDTHS ============================= ; First, you replace all unknown widths with a unique width @@ -1627,7 +1672,6 @@ public defstruct MaxWidth <: Width : args : List<Width> public defstruct ExpWidth <: Width : arg1 : Width - val width-name-hash = HashTable<Symbol,Int>(symbol-hash) public defmulti map<?T> (f: Width -> Width, w:?T&Width) -> T @@ -1667,6 +1711,9 @@ defmethod equal? (w1:Width,w2:Width) -> True|False : if not contains?(args(w2),w) : ret(false) ret(true) (w1:IntWidth,w2:IntWidth) : width(w1) == width(w2) + (w1:LongWidth,w2:IntWidth) : width(w1) == to-long $ width(w2) + (w1:IntWidth,w2:LongWidth) : to-long(width(w1)) == width(w2) + (w1:LongWidth,w2:LongWidth) : width(w1) == width(w2) (w1:PlusWidth,w2:PlusWidth) : (arg1(w1) == arg1(w2) and arg2(w1) == arg2(w2)) or (arg1(w1) == arg2(w2) and arg2(w1) == arg1(w2)) (w1:MinusWidth,w2:MinusWidth) : @@ -1703,14 +1750,21 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Width> : (w:PlusWidth) : match(arg1(w),arg2(w)) : (w1:IntWidth,w2:IntWidth) : IntWidth(width(w1) + width(w2)) + (w1:LongWidth,w2:IntWidth) : LongWidth(plus(width(w1),to-long $ width(w2))) + (w1:IntWidth,w2:LongWidth) : LongWidth(plus(to-long $ width(w1), width(w2))) + (w1:LongWidth,w2:LongWidth) : LongWidth(plus(width(w1),width(w2))) (w1,w2) : w (w:MinusWidth) : match(arg1(w),arg2(w)) : - (w1:IntWidth,w2:IntWidth) : IntWidth(width(w1) - width(w2)) + (w1:IntWidth,w2:IntWidth) : IntWidth(width(w1) + width(w2)) + (w1:LongWidth,w2:IntWidth) : LongWidth(minus(width(w1),to-long $ width(w2))) + (w1:IntWidth,w2:LongWidth) : LongWidth(minus(to-long $ width(w1), width(w2))) + (w1:LongWidth,w2:LongWidth) : LongWidth(minus(width(w1),width(w2))) (w1,w2) : w (w:ExpWidth) : match(arg1(w)) : - (w1:IntWidth) : IntWidth(pow(2,width(w1)) - 1) + (w1:IntWidth) : LongWidth(pow(to-long(2),to-long(width(w1) - 1))) + (w1:LongWidth) : LongWidth(pow(to-long(2),minus(width(w1), to-long(1)))) (w1) : w (w) : w defn substitute (w:Width,h:HashTable<Symbol,Width>) -> Width : @@ -1893,36 +1947,40 @@ defn build-environment (c:Circuit,m:Module,h:HashTable<Symbol,Type>) -> HashTabl defn reduce-var-widths (c:Circuit,h:HashTable<Symbol,Width>) -> Circuit : defn evaluate (w:Width) -> Width : - defn apply (a:Int|False,f:(Int) -> Int) -> Int|False : - if a typeof Int : f(a as Int) + defn apply (a:Long|False,f:(Long) -> Long) -> Long|False : + if a typeof Long : f(a as Long) else : 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) + defn apply (a:Long|False,b:Long|False, f: (Long,Long) -> Long) -> Long|False : + if a typeof Long and b typeof Long : f(a as Long, b as Long) else : false - defn apply-l (l:List<Int|False>,f:(Int,Int) -> Int) -> Int|False : - if length(l) == 0 : 0 + defn apply-l (l:List<Long|False>,f:(Long,Long) -> Long) -> Long|False : + if length(l) == 0 : to-long(0) else : apply(head(l),apply-l(tail(l),f),f) - defn max (a:Int,b:Int) -> Int : + defn max (a:Long,b:Long) -> Long : if a >= b : a else : b - defn solve (w:Width) -> Int|False : + defn solve (w:Width) -> False|Long : match(w) : (w:VarWidth) : val w* = h[name(w)] if w* typeof VarWidth : false else : solve(w*) (w:MaxWidth) : apply-l(map(solve,args(w)),max) - (w:PlusWidth) : apply(solve(arg1(w)),solve(arg2(w)),{_ + _}) - (w:MinusWidth) : apply(solve(arg1(w)),solve(arg2(w)),{_ - _}) - (w:ExpWidth) : apply(2,solve(arg1(w)),{pow(_,_) - 1}) - (w:IntWidth) : width(w) + (w:PlusWidth) : apply(solve(arg1(w)),solve(arg2(w)),{plus(_,_)}) + (w:MinusWidth) : apply(solve(arg1(w)),solve(arg2(w)),{minus(_,_)}) + (w:ExpWidth) : apply(to-long(2),solve(arg1(w)),{minus(pow(_,_),to-long(1))}) + (w:IntWidth) : to-long(width(w)) + (w:LongWidth) : width(w) (w) : println(w) error("Shouldn't be here") val s = solve(w) - if s typeof Int : IntWidth(s as Int) - else : w + match(s) : + (s:Long) : + if s > to-long(2147483647) : LongWidth(s) + else : IntWidth(to-int $ to-string $ s) + (s) : w defn reduce-var-widths-w (w:Width) -> Width : println-all-debug(["REPLACE: " w]) @@ -2193,25 +2251,33 @@ public defstruct Pad <: Pass public defmethod pass (b:Pad) -> (Circuit -> Circuit) : pad-widths public defmethod name (b:Pad) -> String : "Pad Widths" -defn int-width! (t:Type) -> Int : +;------------ Helper Functions -------------- +defn int-width! (t:Type) -> Long : match(width!(t)) : - (w:IntWidth) : width(w) + (w:IntWidth) : to-long(width(w)) + (w:LongWidth) : width(w) (w) : error("Non-int width") -defn set-width (desired:Int,t:Type) -> Type : +defn set-width (desired:Long,t:Type) -> Type : match(t) : - (t:UIntType) : UIntType(IntWidth(desired)) - (t:SIntType) : SIntType(IntWidth(desired)) + (t:UIntType) : UIntType(LongWidth(desired)) + (t:SIntType) : SIntType(LongWidth(desired)) (t) : error("Non-ground type") -defn pad-widths-e (desired:Int,e:Expression) -> Expression : - defn trim (desired:Int, e:Expression) : +defn lmax (l1:Long, l2:Long) -> Long : + if l1 > l2 : l1 + else : l2 + +;------------- Pad Widths ------------------- + +defn pad-widths-e (desired:Long,e:Expression) -> Expression : + defn trim (desired:Long, e:Expression) : ;; println-all(["TRIM " desired " e " e]) - DoPrim(BITS-SELECT-OP,list(e),list(desired - 1, 0),set-width(desired,type(e))) - defn pad (desired:Int, e:Expression) : + DoPrim(BITS-SELECT-OP,list(e),list(to-int(to-string(desired)) - 1, 0),set-width(desired,type(e))) + defn pad (desired:Long, e:Expression) : ;; println-all(["PAD " desired " e " e]) - DoPrim(PAD-OP,list(e),list(desired),set-width(desired,type(e))) - defn trim-pad (desired:Int, e:Expression) : + DoPrim(PAD-OP,list(e),list(to-int $ to-string(desired)),set-width(desired,type(e))) + defn trim-pad (desired:Long, e:Expression) : val i = int-width!(type(e)) if i > desired : trim(desired, e) else if i == desired : e @@ -2221,13 +2287,13 @@ defn pad-widths-e (desired:Int,e:Expression) -> Expression : ;; println-all(["PAD-E " desired " " e]) match(e) : (e:DoPrim) : - val new-desired = reduce(max, 0, map(int-width!{type(_)}, args(e))) + val new-desired = reduce(lmax, to-long(0), map(int-width!{type(_)}, args(e))) ;; println-all([" NEW DESIRED " new-desired]) val e* = if contains?([CONCAT-OP, DYN-SHIFT-RIGHT-OP, DYN-SHIFT-LEFT-OP], op(e)) : DoPrim(op(e), map(self-pad-widths-e, args(e)), consts(e), type(e)) else if contains?([MUX-OP], op(e)) : - DoPrim(op(e), list(pad-widths-e(1, args(e)[0]), pad-widths-e(new-desired, args(e)[1]), pad-widths-e(new-desired, args(e)[2])), consts(e), type(e)) + DoPrim(op(e), list(pad-widths-e(to-long(1), args(e)[0]), pad-widths-e(new-desired, args(e)[1]), pad-widths-e(new-desired, args(e)[2])), consts(e), type(e)) else : map(pad-widths-e{new-desired,_},e) trim-pad(desired, e*) @@ -2236,11 +2302,11 @@ defn pad-widths-e (desired:Int,e:Expression) -> Expression : (e:UIntValue) : val i = int-width!(type(e)) if i > desired : trim(desired, e) - else : UIntValue(value(e),IntWidth(desired)) + else : UIntValue(value(e),LongWidth(desired)) (e:SIntValue) : val i = int-width!(type(e)) if i > desired : trim(desired, e) - else : SIntValue(value(e),IntWidth(desired)) + else : SIntValue(value(e),LongWidth(desired)) (e) : error(to-string $ e) defn pad-widths-s (s:Stmt) -> Stmt : diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza index 8d6bfecf..2921c964 100644 --- a/src/main/stanza/verilog.stanza +++ b/src/main/stanza/verilog.stanza @@ -13,12 +13,13 @@ public defmethod name (b:Verilog) -> String : "To Verilog" public defmethod short-name (b:Verilog) -> String : "To Verilog" ;============ Utilz ============= -defn width! (w:Width) -> Int : +defn width! (w:Width) -> Long : match(w) : - (w:IntWidth) : width(w) + (w:IntWidth) : to-long(width(w)) + (w:LongWidth) : width(w) (w) : error("Non-supported width type.") -defn width! (t:Type) -> Int : +defn width! (t:Type) -> Long : match(t) : (t:UIntType) : width!(width(t)) (t:SIntType) : width!(width(t)) @@ -29,6 +30,9 @@ defn emit (w:Width) -> String : (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:LongWidth) : + if width(w) >= to-long(1) : string-join $ ["[" width(w) - to-long(1) ":0]"] ;TODO check if need to special case 0 or 1 width wires + else : "" (w) : error("Non-supported width type.") @@ -41,7 +45,7 @@ defn get-width (t:Type) -> String : defn remove-subfield (e:Expression) -> Expression : match(map(remove-subfield,e)) : - (e:Subfield) : Ref(to-symbol $ string-join $ [emit(exp(e)) "_" name(e)],type(e)) + (e:Subfield) : Ref(to-symbol $ string-join $ [emit(exp(e)) bundle-expand-delin name(e)],type(e)) (e) : e ;============ Verilog Backend ============= @@ -90,10 +94,10 @@ defn emit (e:Expression) -> String : PAD-OP : val x = args(e)[0] val w = width!(type(x)) - val diff = consts(e)[0] - w - if w == 0 : [ emit(x) ] + val diff = (to-long(consts(e)[0]) - w) + if w == to-long(0) : [ emit(x) ] else : - if type(e) typeof SIntType : ["{{" diff "{" emit(x) "[" w - 1 "]}}, " emit(x) " }"] + if type(e) typeof SIntType : ["{{" diff "{" emit(x) "[" w - to-long(1) "]}}, " emit(x) " }"] else : ["{{" diff "'d0 }, " emit(x) " }"] AS-UINT-OP : ["$unsigned(" emit(args(e)[0]) ")"] @@ -207,7 +211,7 @@ defn emit-module (m:InModule) : inst-ports[sym] = Vector<Streamable>() insts[sym] = name(module(s) as Ref) for f in fields(type(module(s)) as BundleType) do : - val n* = to-symbol $ string-join $ [sym "_" name(f)] + val n* = to-symbol $ string-join $ [sym bundle-expand-delin name(f)] add(wires,["wire " get-width(type(f)) " " n* ";"]) add(inst-ports[sym], ["." name(f) "( " n* " )"]) if flip(f) == REVERSE : |
