aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorazidar2015-05-27 17:15:44 -0700
committerazidar2015-05-27 17:15:44 -0700
commitb44b49e6a6589add30b5b1d89d85f2e20432a515 (patch)
tree36a70d1d330f7163fe66af1adcd126c6f92af699 /src
parenta2a48576534f87b28566504bb1e0c7faa493f463 (diff)
Added sequential memories. mem no longer exists, must declare either cmem or smem. Added firrtl-gensym utility to generate a hashmap of names
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/firrtl-ir.stanza1
-rw-r--r--src/main/stanza/flo.stanza12
-rw-r--r--src/main/stanza/ir-parser.stanza3
-rw-r--r--src/main/stanza/ir-utils.stanza50
-rw-r--r--src/main/stanza/passes.stanza61
-rw-r--r--src/main/stanza/verilog.stanza45
6 files changed, 114 insertions, 58 deletions
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index eef48b11..e92f4854 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -117,6 +117,7 @@ public defstruct DefMemory <: Stmt : ;LOW
info: FileInfo with: (as-method => true)
name: Symbol
type: VectorType
+ seq?: True|False
public defstruct DefNode <: Stmt : ;LOW
info: FileInfo with: (as-method => true)
name: Symbol
diff --git a/src/main/stanza/flo.stanza b/src/main/stanza/flo.stanza
index 0f1f4eeb..41de8f82 100644
--- a/src/main/stanza/flo.stanza
+++ b/src/main/stanza/flo.stanza
@@ -200,7 +200,7 @@ defn maybe-mov (e:Expression) -> String :
(e) : false
if need-mov?: "mov " else: ""
-defn emit-s (s:Stmt, v:List<Symbol>, top:Symbol) :
+defn emit-s (s:Stmt, v:List<Symbol>, top:Symbol,sh:HashTable<Symbol,Int>) :
match(s) :
(s:DefWire) : ""
(s:DefInstance) : error("Shouldn't be here")
@@ -209,7 +209,7 @@ defn emit-s (s:Stmt, v:List<Symbol>, top:Symbol) :
emit-all([top "::" name(s) " = mem'" prim-width(type(vtype)) " " size(vtype) "\n"], top)
(s:DefNode) :
emit-all([top "::" name(s) " = " maybe-mov(value(s)) value(s) "\n"], top)
- (s:Begin) : do(emit-s{_, v, top}, body(s))
+ (s:Begin) : do(emit-s{_, v, top,sh}, body(s))
(s:Connect) :
match(loc(s)) :
(r:Ref) :
@@ -219,14 +219,14 @@ defn emit-s (s:Stmt, v:List<Symbol>, top:Symbol) :
else :
emit-all([top "::" n " = " maybe-mov(exp(s)) exp(s) "\n"], top)
(w:WritePort) :
- val n = firrtl-gensym(`F)
+ val n = firrtl-gensym(`F,sh)
emit-all([top "::" n " = wr'" prim-width(type(w)) " " enable(w) " " mem(w) " " index(w) " " exp(s) "\n"], top)
(o) :
println-all(["CONNEcT LOC " loc(s)])
error("Unknown Connect")
(s) : s
-defn emit-module (m:InModule) :
+defn emit-module (m:InModule,sh:HashTable<Symbol,Int>) :
val v = Vector<Symbol>()
for port in ports(m) do :
if name(port) ==`reset :
@@ -234,10 +234,10 @@ defn emit-module (m:InModule) :
else : switch {_ == direction(port)} :
INPUT : print-all([name(m) "::" name(port) " = " "in'" prim-width(type(port)) "\n"])
OUTPUT : add(v,name(port))
- emit-s(body(m), to-list(v), name(m))
+ emit-s(body(m), to-list(v), name(m),sh)
public defn emit-flo (file:String, c:Circuit) :
with-output-file{file, _} $ fn () :
- emit-module(modules(c)[0] as InModule)
+ emit-module(modules(c)[0] as InModule,get-sym-hash(modules(c)[0] as InModule))
false
c
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index db3324e4..cbfe106e 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -193,7 +193,8 @@ defsyntax firrtl :
defrule statements :
stmt = (wire ?name:#id! #:! ?t:#type!) : DefWire(first-info(form),name, t)
stmt = (reg ?name:#id! #:! ?t:#type!) : DefRegister(first-info(form),name, t)
- stmt = (mem ?name:#id! #:! ?t:#vectype!) : DefMemory(first-info(form),name, t)
+ stmt = (cmem ?name:#id! #:! ?t:#vectype!) : DefMemory(first-info(form),name, t, false)
+ stmt = (smem ?name:#id! #:! ?t:#vectype!) : DefMemory(first-info(form),name, t, true)
stmt = (inst ?name:#id! #of! ?m:#ref!) : DefInstance(first-info(form),name, m)
stmt = (node ?name:#id! #=! ?e:#exp!) : DefNode(first-info(form),name, e)
stmt = (accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i)
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 4271edca..c39a1ad1 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -9,19 +9,42 @@ public defmulti print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field|M
;============== GENSYM STUFF ======================
-val sym-hash = HashTable<Symbol,Int>(symbol-hash)
-public defn firrtl-gensym (s:Symbol) -> Symbol :
- val cur = get?(sym-hash,s,0)
- val nxt = cur + 1
- sym-hash[s] = nxt
- symbol-join([s cur])
-
-public defn firrtl-gensym () -> Symbol :
- firrtl-gensym(`gen)
-;public defn get-sym-hash (m:Circuit) -> HashTable<Symbol,Int> :
- ;public defn get-sym-hash (c:Circuit) -> HashTable<Symbol,Int> :
+public defn firrtl-gensym (s:Symbol) -> Symbol : firrtl-gensym(s,HashTable<Symbol,Int>(symbol-hash))
+
+public defn firrtl-gensym (s:Symbol,sym-hash:HashTable<Symbol,Int>) -> Symbol :
+ defn get-new (s:Symbol, i:Int) -> Symbol :
+ val s* = symbol-join([s i])
+ if contains?(keys(sym-hash),s*) :
+ get-new(s,i + 1)
+ else :
+ sym-hash[s] = i
+ sym-hash[s*] = 0
+ s*
+ get-new(s,0)
+public defn firrtl-gensym (sym-hash:HashTable<Symbol,Int>) -> Symbol :
+ firrtl-gensym(`gen,sym-hash)
+
+public defn get-sym-hash (m:InModule) -> HashTable<Symbol,Int> :
+ val sym-hash = HashTable<Symbol,Int>(symbol-hash)
+ defn add-name (s:Symbol) -> False :
+ sym-hash[s] = 0
+ defn to-port (p:Port) -> False : add-name(name(p))
+ defn to-stmt (s:Stmt) -> Stmt :
+ match(s) :
+ (s:DefWire) : add-name(name(s))
+ (s:DefRegister) : add-name(name(s))
+ (s:DefInstance) : add-name(name(s))
+ (s:DefMemory) : add-name(name(s))
+ (s:DefNode) : add-name(name(s))
+ (s:DefAccessor) : add-name(name(s))
+ (s) : false
+ map(to-stmt,s)
+
+ to-stmt(body(m))
+ map(to-port,ports(m))
+ sym-hash
;============== Exceptions =====================
@@ -131,7 +154,8 @@ defmethod print (o:OutputStream, c:Stmt) :
(c:DefRegister) :
print-all(o,["reg " name(c) " : " type(c)])
(c:DefMemory) :
- print-all(o,["mem " name(c) " : " type(c)])
+ if seq?(c) : print-all(o,["smem " name(c) " : " type(c)])
+ else : print-all(o,["cmem " name(c) " : " type(c)])
(c:DefInstance) :
print-all(o,["inst " name(c) " of " module(c)])
(c:DefNode) :
@@ -287,7 +311,7 @@ defmethod map (f: Type -> Type, c:Stmt) -> Stmt :
match(c) :
(c:DefWire) : DefWire(info(c),name(c),f(type(c)))
(c:DefRegister) : DefRegister(info(c),name(c),f(type(c)))
- (c:DefMemory) : DefMemory(info(c),name(c),f(type(c)) as VectorType)
+ (c:DefMemory) : DefMemory(info(c),name(c),f(type(c)) as VectorType,seq?(c))
(c) : c
public defmulti mapr<?T> (f: Width -> Width, t:?T&Type) -> T
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 3e2a058b..80035325 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -866,7 +866,7 @@ defn lower (body:Stmt) -> Stmt :
DefNode(info(s),name(s),exp(x))
(s:DefMemory) : Begin $
for x in generate-entry(name(s),type(type(s))) map :
- DefMemory(info(s),name(x),VectorType(type(x),size(s)))
+ DefMemory(info(s),name(x),VectorType(type(x),size(s)), seq?(s))
(s:WDefAccessor) :
val ls = generate-entry(name(s),type(s))
val rs = generate-entry(name(source(s) as WRef),type(s))
@@ -980,7 +980,7 @@ public defmethod pass (b:ExpandIndexedConnects) -> (Circuit -> Circuit) : expand
public defmethod name (b:ExpandIndexedConnects) -> String : "Expand Indexed Connects"
public defmethod short-name (b:ExpandIndexedConnects) -> String : "expand-indexed-connects"
-defn expand-connect-indexed-stmt (s: Stmt) -> Stmt :
+defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable<Symbol,Int>) -> Stmt :
defn equality (e1:Expression,e2:Expression) -> Expression :
DoPrim(EQUAL-OP,list(e1,e2),List(),UIntType(UnknownWidth()))
defn get-name (e:Expression) -> Symbol :
@@ -993,7 +993,7 @@ defn expand-connect-indexed-stmt (s: Stmt) -> Stmt :
(s:ConnectToIndexed) : Begin $
if length(locs(s)) == 0 : list(EmptyStmt())
else :
- val ref = WRef(firrtl-gensym(get-name(index(s))),type(index(s)),NodeKind(),UNKNOWN-GENDER)
+ val ref = WRef(firrtl-gensym(get-name(index(s)),sh),type(index(s)),NodeKind(),UNKNOWN-GENDER)
append(
list(DefNode(info(s),name(ref),index(s)))
to-list $
@@ -1007,7 +1007,7 @@ defn expand-connect-indexed-stmt (s: Stmt) -> Stmt :
(s:ConnectFromIndexed) : Begin $
if length(exps(s)) == 0 : list(EmptyStmt())
else :
- val ref = WRef(firrtl-gensym(get-name(index(s))),type(index(s)),NodeKind(),UNKNOWN-GENDER)
+ val ref = WRef(firrtl-gensym(get-name(index(s)),sh),type(index(s)),NodeKind(),UNKNOWN-GENDER)
append(
list(Connect(info(s),loc(s),head(exps(s))),DefNode(info(s),name(ref),index(s)))
to-list $
@@ -1018,11 +1018,13 @@ defn expand-connect-indexed-stmt (s: Stmt) -> Stmt :
EmptyStmt()
)
)
- (s) : map(expand-connect-indexed-stmt,s)
+ (s) : map(expand-connect-indexed-stmt{_,sh},s)
defn expand-connect-indexed (m: Module) -> Module :
match(m) :
- (m:InModule) : InModule(info(m),name(m),ports(m),expand-connect-indexed-stmt(body(m)))
+ (m:InModule) :
+ val sh = get-sym-hash(m)
+ InModule(info(m),name(m),ports(m),expand-connect-indexed-stmt(body(m),sh))
(m:ExModule) : m
defn expand-connect-indexed (c: Circuit) -> Circuit :
@@ -1450,6 +1452,8 @@ public defstruct MaxWidth <: 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
defmethod map (f: Width -> Width, w:Width) -> Width :
match(w) :
@@ -1641,7 +1645,7 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
match(map(gen-constraints-s,s)) :
(s:DefWire) : DefWire(info(s),name(s),h[name(s)])
(s:DefInstance) : DefInstance(info(s),name(s),gen-constraints(module(s)))
- (s:DefMemory) : DefMemory(info(s),name(s),h[name(s)] as VectorType)
+ (s:DefMemory) : DefMemory(info(s),name(s),h[name(s)] as VectorType,seq?(s))
(s:DefNode) :
val l = h[name(s)]
val r = gen-constraints(value(s))
@@ -1677,14 +1681,14 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
(e:UIntValue) :
match(width(e)) :
(w:UnknownWidth) :
- val w* = VarWidth(firrtl-gensym(`w))
+ val w* = VarWidth(firrtl-gensym(`w,width-name-hash))
add(v,WGeq(w*,IntWidth(ceil-log2(value(e)))))
UIntValue(value(e),w*)
(w) : e
(e:SIntValue) :
match(width(e)) :
(w:UnknownWidth) :
- val w* = VarWidth(firrtl-gensym(`w))
+ val w* = VarWidth(firrtl-gensym(`w,width-name-hash))
add(v,WGeq(w*,IntWidth(1 + ceil-log2(abs(value(e))))))
SIntValue(value(e),w*)
(w) : e
@@ -1763,7 +1767,7 @@ defn reduce-var-widths (c:Circuit,h:HashTable<Symbol,Width>) -> Circuit :
defn remove-unknowns-w (w:Width) -> Width :
match(w) :
- (w:UnknownWidth) : VarWidth(firrtl-gensym(`w))
+ (w:UnknownWidth) : VarWidth(firrtl-gensym(`w,width-name-hash))
(w) : w
defn remove-unknowns (t:Type) -> Type : mapr(remove-unknowns-w,t)
@@ -1847,7 +1851,7 @@ defn inline-instances (c:Circuit) :
map{rename-e{_,n},_} $ match(map(rename-s{_,n},s)) :
(s:DefWire) : DefWire(info(s),rename(name(s),n),type(s))
(s:DefInstance) : error("Shouldn't be here")
- (s:DefMemory) : DefMemory(info(s),rename(name(s),n),type(s))
+ (s:DefMemory) : DefMemory(info(s),rename(name(s),n),type(s),seq?(s))
(s:DefNode) : DefNode(info(s),rename(name(s),n),value(s))
(s) : s
for m in modules(c) do :
@@ -1872,35 +1876,36 @@ defn full-name (e:Expression) -> Symbol :
(e) : error("Non-supported expression.")
defn split-exp (c:Circuit) :
- defn split-exp-s (s:Stmt,v:Vector<Stmt>) -> False :
+ defn split-exp-s (s:Stmt,v:Vector<Stmt>,sh:HashTable<Symbol,Int>) -> False :
+ defn split-exp-e (e:Expression,n:Symbol|False,info:FileInfo) -> Expression :
+ match(map(split-exp-e{_,n,info},e)) :
+ (e:DoPrim) :
+ val n* =
+ if n typeof False : firrtl-gensym(`T,sh)
+ else : firrtl-gensym(symbol-join([n as Symbol gen-delin]),sh)
+ add(v,DefNode(info,n*,e))
+ WRef(n*,type(e),NodeKind(),UNKNOWN-GENDER)
+ (e) : e
match(s) :
(s:Begin) :
- defn f (s:Stmt) -> False: split-exp-s(s,v)
+ defn f (s:Stmt) -> False: split-exp-s(s,v,sh)
do(f,s)
(s:Conditionally) : error("Shouldn't be here")
(s:Connect) :
match(loc(s)) :
- (e:WritePort) : add(v,map(split-exp-e{_,v,full-name(exp(s)),info(s)},s))
- (e) : add(v,map(split-exp-e{_,v,full-name(loc(s)),info(s)},s))
- (s:DefNode) : add(v,map(split-exp-e{_,v,name(s),info(s)},s))
- (s) : add(v,map(split-exp-e{_,v,false,info(s)},s))
+ (e:WritePort) : add(v,map(split-exp-e{_,full-name(exp(s)),info(s)},s))
+ (e) : add(v,map(split-exp-e{_,full-name(loc(s)),info(s)},s))
+ (s:DefNode) : add(v,map(split-exp-e{_,name(s),info(s)},s))
+ (s) : add(v,map(split-exp-e{_,false,info(s)},s))
false
- defn split-exp-e (e:Expression,v:Vector<Stmt>,n:Symbol|False,info:FileInfo) -> Expression :
- match(map(split-exp-e{_,v,n,info},e)):
- (e:DoPrim) :
- val n* =
- if n typeof False : firrtl-gensym(`T)
- else : firrtl-gensym(symbol-join([n as Symbol gen-delin]))
- add(v,DefNode(info,n*,e))
- WRef(n*,type(e),NodeKind(),UNKNOWN-GENDER)
- (e) : e
Circuit{info(c),_,main(c)} $
for m in modules(c) map :
match(m) :
(m:InModule) :
val v = Vector<Stmt>()
- split-exp-s(body(m),v)
+ val sh = get-sym-hash(m)
+ split-exp-s(body(m),v,sh)
InModule(info(m),name(m),ports(m),Begin(to-list(v)))
(m:ExModule) : m
@@ -1970,7 +1975,7 @@ public defn special-rename (original-sym:Symbol,new-sym:Symbol,c:Circuit) :
(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))
- (s:DefMemory) : DefMemory(info(s),rename(name(s)),type(s))
+ (s:DefMemory) : DefMemory(info(s),rename(name(s)),type(s),seq?(s))
(s:DefNode) : DefNode(info(s),rename(name(s)),value(s))
(s:DefAccessor) : DefAccessor(info(s),rename(name(s)),source(s),index(s))
(s) : map(to-stmt,s)
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
index 79bccefb..bee10177 100644
--- a/src/main/stanza/verilog.stanza
+++ b/src/main/stanza/verilog.stanza
@@ -38,6 +38,11 @@ defn remove-subfield (e:Expression) -> Expression :
(e:Subfield) : Ref(to-symbol $ string-join $ [emit(exp(e)) "_" name(e)],type(e))
(e) : e
+definterface VKind
+defstruct WireKind <: VKind
+defstruct RegKind <: VKind
+defstruct SeqMemKind <: VKind
+defstruct ComMemKind <: VKind
;============ Verilog Backend =============
@@ -110,13 +115,17 @@ defn emit (e:Expression) -> String :
v
defn emit-module (m:InModule) :
- val h = Vector<Symbol>()
+ val h = HashTable<Symbol,VKind>(symbol-hash)
defn build-table (m:InModule) :
defn build-table (s:Stmt) -> Stmt :
match(map(build-table,s)) :
+ (s:DefWire) : h[name(s)] = WireKind()
+ (s:DefMemory) :
+ if seq?(s) : h[name(s)] = SeqMemKind()
+ else : h[name(s)] = ComMemKind()
(s:Connect) :
match(exp(s)) :
- (e:Register) : add(h,name(loc(s) as Ref))
+ (e:Register) : h[name(loc(s) as Ref)] = RegKind()
(e) : false
(s) : false
s
@@ -130,11 +139,13 @@ defn emit-module (m:InModule) :
val updates = Vector<Streamable>()
val insts = HashTable<Symbol,Symbol>(symbol-hash) ; inst -> module
val inst-ports = HashTable<Symbol,Vector<Streamable>>(symbol-hash)
+
+ val sh = get-sym-hash(m)
defn emit-s (s:Stmt) :
match(map(remove-subfield,s)) :
(s:DefWire) :
- if contains?(to-list $ h, name(s)) :
+ if h[name(s)] == RegKind() :
add(regs,["reg " get-width(type(s)) " " name(s) ";"])
else :
add(wires,["wire " get-width(type(s)) " " name(s) ";"])
@@ -147,13 +158,17 @@ defn emit-module (m:InModule) :
add(inst-ports[name(s)], ["." name(f) "( " n* " )"])
(s:DefMemory) :
val vtype = type(s) as VectorType
- val innerwidth =
- add(regs,["reg " get-width(type(vtype)) " " name(s) " [0:" size(vtype) "];"])
- add(inits,["for (initvar = 0; initvar < " size(vtype) "; initvar = initvar+1)"])
- add(inits,[name(s) " = {" width!(type(vtype)) "{$random}};"])
+ if seq?(s) :
+ add(regs,["reg " get-width(type(vtype)) " " name(s) " [0:" size(vtype) "];"])
+ add(inits,["for (initvar = 0; initvar < " size(vtype) "; initvar = initvar+1)"])
+ add(inits,[name(s) " = {" width!(type(vtype)) "{$random}};"])
+ else :
+ add(regs,["reg " get-width(type(vtype)) " " name(s) " [0:" size(vtype) "];"])
+ add(inits,["for (initvar = 0; initvar < " size(vtype) "; initvar = initvar+1)"])
+ add(inits,[name(s) " = {" width!(type(vtype)) "{$random}};"])
(s:DefNode) :
- add(wires,["wire " get-width(type(value(s))) " " name(s) ";"])
- add(assigns,["assign " name(s) " = " emit(value(s)) ";"])
+ add(wires,["wire " get-width(type(value(s))) " " name(s) ";"])
+ add(assigns,["assign " name(s) " = " emit(value(s)) ";"])
(s:Begin) : do(emit-s, body(s))
(s:Connect) :
if loc(s) typeof WritePort :
@@ -172,7 +187,17 @@ defn emit-module (m:InModule) :
else if exp(s) typeof ReadPort :
val n = name(loc(s) as Ref)
val rp = exp(s) as ReadPort
- add(assigns,["assign " n " = " emit(mem(rp)) "[" emit(index(rp)) "];"])
+ match(h[name(mem(rp) as Ref)]) :
+ (k:SeqMemKind) :
+ val index* = Ref(firrtl-gensym(name(index(rp) as Ref),sh),type(index(rp)))
+ add(regs,[ "reg " get-width(type(index*)) " " name(index*) ";"])
+ add(inits,[name(index*) " = {" width!(type(index*)) "{$random}};"])
+ add(updates,["if(" emit(enable(rp)) ") begin"])
+ add(updates,[" " name(index*) " <= " emit(index(rp)) ";"])
+ add(updates,["end"])
+ add(assigns,["assign " n " = " emit(mem(rp)) "[" emit(index*) "];"])
+ (k:ComMemKind) :
+ add(assigns,["assign " n " = " emit(mem(rp)) "[" emit(index(rp)) "];"])
else :
add(assigns,["assign " emit(loc(s)) " = " emit(exp(s)) ";"])
(s) : s