aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorazidar2015-07-21 11:42:06 -0700
committerazidar2015-07-21 11:42:06 -0700
commitd1c11b612201d1d167ece627350a35b303cf4e8b (patch)
treefc7a634030d7b18c8db4e4a76f08271e6a9ac200 /src
parentc093b68df9c461fb44306a1845bba7dc40d3136c (diff)
parentc69a45738f40e234ffb82db0f6030f7d185dc305 (diff)
Merge branch 'new-low-firrtl' of github.com:ucb-bar/firrtl into new-low-firrtl
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/compilers.stanza24
-rw-r--r--src/main/stanza/errors.stanza97
-rw-r--r--src/main/stanza/firrtl-ir.stanza8
-rw-r--r--src/main/stanza/ir-parser.stanza7
-rw-r--r--src/main/stanza/ir-utils.stanza14
-rw-r--r--src/main/stanza/passes.stanza334
-rw-r--r--src/main/stanza/verilog.stanza20
7 files changed, 362 insertions, 142 deletions
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza
index d65e7718..64d4a7c4 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))
]
@@ -76,16 +77,25 @@ public defn run-passes (c:Circuit,ls:List<Pass>) :
println("Compiling!")
if PRINT-CIRCUITS : println("Original Circuit")
if PRINT-CIRCUITS : print(c)
- val start-time = current-time-us()
+ ;val start-time = current-time-us()
+ val start-time = to-int(to-string(current-time-us() / to-long(1000)))
var t = start-time
- val tables = Vector<HashTable<Symbol,HashTable<Symbol,Symbol>>>()
+ val time-table = Vector<[String,Int]>()
for p in ls do :
+ println-all(STANDARD-ERROR,["Starting " name(p)])
if PRINT-CIRCUITS : println(name(p))
c* = pass(p)(c*)
if PRINT-CIRCUITS : print(c*)
- val current-time = current-time-us()
- println-all(["Finished " name(p) "\n"])
- println-all(["Time since start: " current-time - start-time])
- println-all(["Time for this pass: " current-time - t])
+ val current-time = to-int(to-string(current-time-us() / to-long(1000)))
+ println-all(STANDARD-ERROR,["Finished " name(p)])
+ println-all(STANDARD-ERROR,["Milliseconds since start: " current-time - start-time])
+ println-all(STANDARD-ERROR,["Milliseconds for this pass: " current-time - t])
+ println-all(STANDARD-ERROR,["\n"])
+ add(time-table,[name(p), current-time - t])
t = current-time
- println("Done!")
+
+ println(STANDARD-ERROR,"===== Time Breakdown =====")
+ for x in time-table do :
+ println-all(STANDARD-ERROR,[x[0] " --- " to-float(x[1] as Int) / to-float(t - start-time) "%"])
+ println(STANDARD-ERROR,"==========================")
+ println(STANDARD-ERROR,"Done!")
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index e36ec06d..d8969dd3 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -283,20 +283,26 @@ public defn check-high-form (c:Circuit) -> Circuit :
map(check-high-form-t{info,_:Type},e)
e
- defn check-high-form-s (s:Stmt,names:HashTable<Symbol,True>) -> Stmt :
+ defn check-high-form-s (s:Stmt,names:HashTable<Symbol,True>,mnames:HashTable<Symbol,True>) -> Stmt :
defn check-name (info:FileInfo,name:Symbol) -> False :
if key?(names,name) : add(errors,NotUnique(info,name))
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) :
+ map{check-high-form-s{_,names,mnames},_} $ {
+ match(s) : ;map(check-high-form-e{info(s),_,names},s)) :
+ (s:DefWire) :
check-name(info(s),name(s))
names[name(s)] = true
+ (s:DefRegister) :
+ check-name(info(s),name(s))
+ names[name(s)] = true
+ check-high-form-e(info(s),reset(s),names)
+ check-high-form-e(info(s),clock(s),names)
(s:DefMemory) :
check-name(info(s),name(s))
names[name(s)] = true
if has-flip?(type(s)) : add(errors, MemWithFlip(info(s), name(s)))
+ check-high-form-e(info(s),clock(s),names)
(s:DefInstance) :
if not contains?(name(module(s) as Ref),map(name,modules(c))) :
add(errors, ModuleNotDefined(info(s),name(module(s) as Ref)))
@@ -304,21 +310,34 @@ public defn check-high-form (c:Circuit) -> Circuit :
names[name(s)] = true
(s:DefNode) :
check-name(info(s),name(s))
+ check-high-form-e(info(s),value(s),names)
names[name(s)] = true
(s:DefAccessor) :
check-name(info(s),name(s))
+ check-high-form-e(info(s),index(s),names)
+ check-high-form-e(info(s),source(s),names)
names[name(s)] = true
(s:Connect) :
check-valid-loc(info(s),loc(s))
+ check-high-form-e(info(s),loc(s),names)
+ check-high-form-e(info(s),exp(s),names)
(s:BulkConnect) :
check-valid-loc(info(s),loc(s))
+ check-high-form-e(info(s),loc(s),names)
+ check-high-form-e(info(s),exp(s),names)
+ (s:OnReset) :
+ check-high-form-e(info(s),loc(s),names)
+ check-high-form-e(info(s),exp(s),names)
+ (s:Conditionally) :
+ check-high-form-e(info(s),pred(s),names)
(s) : false
s }()
defn check-high-form-m (m:Module) -> False :
val names = HashTable<Symbol,True>(symbol-hash)
+ val mnames = HashTable<Symbol,True>(symbol-hash)
for m in modules(c) do :
- names[name(m)] = true
+ mnames[name(m)] = true
for p in ports(m) do :
names[name(p)] = true
;if name(p) == `reset :
@@ -335,7 +354,7 @@ public defn check-high-form (c:Circuit) -> Circuit :
match(m) :
(m:ExModule) : false
- (m:InModule) : check-high-form-s(body(m),names)
+ (m:InModule) : check-high-form-s(body(m),names,mnames)
;match(any-prefixes?(names,to-string(sym),to-string(sym))) :
;(s:False) : false
;(s:String) : add(errors,IsPrefix(info,to-symbol(s)))
@@ -827,3 +846,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..7e07eb8b 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -167,7 +167,7 @@ defsyntax firrtl :
if not empty?(rest) :
FPE(rest, "Expected a statement here.")
InModule(first-info(form),name, ps, Begin(cs))
- module = (exmodule ?name:#id! #:! (?ps:#port ... ?rest ...)) :
+ module = (extmodule ?name:#id! #:! (?ps:#port ... ?rest ...)) :
if not empty?(rest) :
FPE(rest, "Expected a port here.")
ExModule(first-info(form),name, ps)
@@ -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..0118c73b 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, _} $
@@ -251,7 +252,7 @@ defmethod print (o:OutputStream, m:InModule) :
print(io,body(m))
defmethod print (o:OutputStream, m:ExModule) :
- print-all(o, ["exmodule " name(m) " :"])
+ print-all(o, ["extmodule " name(m) " :"])
print-debug(o,m)
print(o,"\n")
val io = IndentedStream(o, 3)
@@ -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..cfcbb36b 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 ------------------
@@ -319,25 +319,25 @@ defn remove-special-chars (c:Circuit) :
add(n*,get-new-string(c))
symbol-join(n*)
defn rename-t (t:Type) -> Type :
- match(map(rename-t,t)) :
+ match(t) :
(t:BundleType) : BundleType $
for f in fields(t) map :
- Field(rename(name(f)),flip(f),type(f))
- (e) : e
+ Field(rename(name(f)),flip(f),rename-t(type(f)))
+ (e) : map(rename-t,e)
defn rename-e (e:Expression) -> Expression :
- map{rename-t,_} $ match(map(rename-e,e)) :
- (e:Ref) : Ref(rename(name(e)),type(e))
- (e:Subfield) : Subfield(exp(e),rename(name(e)),type(e))
- (e) : e
+ match(e) :
+ (e:Ref) : Ref(rename(name(e)),rename-t(type(e)))
+ (e:Subfield) : Subfield(exp(e),rename(name(e)),rename-t(type(e)))
+ (e) : map(rename-t,map(rename-e,e))
defn rename-s (s:Stmt) -> Stmt :
- map{rename-t,_} $ match(map(rename-e,s)) :
- (s:DefWire) : DefWire(info(s),rename(name(s)),type(s))
- (s:DefRegister) : DefRegister(info(s),rename(name(s)),type(s),clock(s),reset(s))
+ match(map(rename-e,s)) :
+ (s:DefWire) : DefWire(info(s),rename(name(s)),rename-t(type(s)))
+ (s:DefRegister) : DefRegister(info(s),rename(name(s)),rename-t(type(s)),clock(s),reset(s))
(s:DefInstance) : DefInstance(info(s),rename(name(s)),module(s))
- (s:DefMemory) : DefMemory(info(s),rename(name(s)),type(s),seq?(s),clock(s))
+ (s:DefMemory) : DefMemory(info(s),rename(name(s)),rename-t(type(s)) as VectorType,seq?(s),clock(s))
(s:DefNode) : DefNode(info(s),rename(name(s)),value(s))
(s:DefAccessor) : DefAccessor(info(s),rename(name(s)),source(s),index(s),acc-dir(s))
- (s) : map(rename-s,s)
+ (s) : map(rename-t,map(rename-s,s))
Circuit(info(c),modules*, main(c)) where :
val modules* =
@@ -743,16 +743,14 @@ defn resolve-genders (c:Circuit) :
genders[n] = g
done? = false
g
- val entry = for kv in genders find :
- key(kv) == n
+ val entry = get?(genders,n,false)
match(entry) :
- (e:KeyValue<Symbol,Gender>) :
- val value = value(e)
- if value == UNKNOWN-GENDER and g == UNKNOWN-GENDER : g
- else if value != UNKNOWN-GENDER and g == UNKNOWN-GENDER : value
- else if value == UNKNOWN-GENDER and g != UNKNOWN-GENDER : force-gender(n,g)
- else : value
- (e:False) : force-gender(n,g)
+ (g*:Gender) :
+ if g* == UNKNOWN-GENDER and g == UNKNOWN-GENDER : g
+ else if g* != UNKNOWN-GENDER and g == UNKNOWN-GENDER : g*
+ else if g* == UNKNOWN-GENDER and g != UNKNOWN-GENDER : force-gender(n,g)
+ else : g*
+ (g*:False) : force-gender(n,g)
defn resolve-stmt (s:Stmt) -> Stmt :
match(s) :
@@ -1281,6 +1279,12 @@ defmethod print (o:OutputStream, sv:SymbolicValue) :
(sv: SVMux) : print-all(o, ["(" pred(sv) " ? " conseq(sv) " : " alt(sv) ")"])
(sv: SVNul) : print(o, "SVNUL")
+defn map (f: Expression -> Expression, sv:SymbolicValue) -> SymbolicValue :
+ match(sv) :
+ (sv:SVMux) : SVMux(f(pred(sv)),conseq(sv),alt(sv))
+ (sv:SVExp) : SVExp(f(exp(sv)))
+ (sv:SVNul) : sv
+
defmulti map<?T> (f: SymbolicValue -> SymbolicValue, sv:?T&SymbolicValue) -> T
defmethod map (f: SymbolicValue -> SymbolicValue, sv:SymbolicValue) -> SymbolicValue :
match(sv) :
@@ -1288,15 +1292,18 @@ defmethod map (f: SymbolicValue -> SymbolicValue, sv:SymbolicValue) -> SymbolicV
(sv) : sv
defn do (f:SymbolicValue -> ?, s:SymbolicValue) -> False :
- for x in s map :
- f(x)
- x
+ defn f* (sv:SymbolicValue) -> SymbolicValue :
+ f(sv)
+ sv
+ map(f*,s)
false
+
defn dor (f:SymbolicValue -> ?, e:SymbolicValue) -> False :
do(f,e)
- for x in e map :
+ defn f* (x:SymbolicValue) -> SymbolicValue :
dor(f,x)
x
+ map(f*,e)
false
defmethod equal? (a:SymbolicValue,b:SymbolicValue) -> True|False :
@@ -1328,13 +1335,13 @@ defn deepcopy (t:HashTable<Symbol,SymbolicValue>) -> HashTable<Symbol,SymbolicVa
val t0 = HashTable<Symbol,SymbolicValue>(symbol-hash)
for x in t do :
t0[key(x)] = value(x)
-defn get-unique-keys (ts:List<HashTable<Symbol,SymbolicValue>>) -> Vector<Symbol> :
- t0 where :
- val t0 = Vector<Symbol>()
- for v in ts do :
- for t in v do :
- val duplicate? = for x in t0 any? : x == key(t)
- if not duplicate? : add(t0,key(t))
+defn get-unique-keys (ts:List<HashTable<Symbol,SymbolicValue>>) -> Streamable<Symbol> :
+ val h = HashTable<Symbol,True>(symbol-hash)
+ for v in ts do :
+ for t in v do :
+ h[key(t)] = true
+ keys(h)
+
defn has-nul? (sv:SymbolicValue) -> True|False :
var has? = false
if sv typeof SVNul : has? = true
@@ -1378,16 +1385,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 :
@@ -1494,28 +1491,55 @@ defn build-tables (s:Stmt,
(s:Begin) : for s* in body(s) do: build-tables(s*,assign,resets,flattn,rsignals)
(s:DefMemory|DefNode|EmptyStmt) : false
+
+defn mark-referenced (referenced?:HashTable<Symbol,True>, s:Stmt) -> False :
+ defn mark-referenced-e (e:Expression) -> Expression :
+ match(map(mark-referenced-e,e)) :
+ (e:Ref) :
+ referenced?[name(e)] = true
+ e
+ (e) : e
+ do(mark-referenced{referenced?,_:Stmt},s)
+ map(mark-referenced-e,s)
+ false
+
+defn mark-referenced (referenced?:HashTable<Symbol,True>, sv:SymbolicValue) -> False :
+ defn mark-referenced-e (e:Expression) -> Expression :
+ match(map(mark-referenced-e,e)) :
+ (e:Ref) :
+ referenced?[name(e)] = true
+ e
+ (e) : e
+ map(mark-referenced-e,sv)
+ false
+
+defn is-referenced? (referenced?:HashTable<Symbol,True>, s:Stmt) -> True|False :
+ match(s) :
+ (s:DefWire|DefRegister|DefAccessor|DefMemory|DefNode) : key?(referenced?,name(s))
+ (s:DefInstance) : true
+
;--------------- 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)) :
- (s:DefNode|DefMemory) : add(decs,s)
+ (s:DefNode) :
+ add(decs,s)
+ (s:DefMemory) :
+ add(decs,s)
(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 +1551,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 +1566,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 +1576,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,30 +1598,102 @@ 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))
- println-debug("====== Assigns ======")
- for x in assign do : println-debug(x)
- println-debug("====== Resets ======")
- for x in resets do : println-debug(x)
+ ;println-debug("====== Assigns ======")
+ ;for x in assign do : println-debug(x)
+ ;println-debug("====== Resets ======")
+ ;for x in resets do : println-debug(x)
val table = merge-resets(assign,resets,rsignals)
- println-debug("====== Table ======")
- for x in table do : println-debug(x)
+ ;println-debug("====== Table ======")
+ ;for x in table do : println-debug(x)
+
val decs = Vector<Stmt>()
val cons = Vector<Stmt>()
expand-whens(ports(m),table,cons)
expand-whens(body(m),table,decs,cons)
- InModule(info(m),name(m),ports(m),Begin(append(to-list(decs),to-list(cons))))
+
+ val referenced? = HashTable<Symbol,True>(symbol-hash)
+ for x in table do :
+ mark-referenced(referenced?,value(x))
+ for x in decs do :
+ mark-referenced(referenced?,x)
+ val decs* = Vector<Stmt>()
+ for x in decs do :
+ if is-referenced?(referenced?,x) : add(decs*,x)
+
+ InModule(info(m),name(m),ports(m),Begin(to-list(append(decs*,to-list(cons)))))
val c* = Circuit(info(c),modules*, main(c)) where :
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 +1720,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 +1759,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 +1798,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 +1995,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 +2299,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 +2335,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 +2350,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 :