aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam Izraelevitz2015-07-17 16:49:22 -0700
committerAdam Izraelevitz2015-07-17 16:49:22 -0700
commit70567d4d57ac178660fbef0ef660069b52857562 (patch)
treeac0ed0127ddb99a72cbc760f6be97b99c574d018 /src
parent98bb81d9d99150a80c77ed8f22d44748a02df628 (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.stanza1
-rw-r--r--src/main/stanza/errors.stanza66
-rw-r--r--src/main/stanza/firrtl-ir.stanza8
-rw-r--r--src/main/stanza/ir-parser.stanza5
-rw-r--r--src/main/stanza/ir-utils.stanza12
-rw-r--r--src/main/stanza/passes.stanza206
-rw-r--r--src/main/stanza/verilog.stanza20
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 :