aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorazidar2015-07-10 13:25:21 -0700
committerazidar2015-07-14 11:29:55 -0700
commit0bfb3618b654a4082cc2780887b3ca32e374f455 (patch)
tree230b7cbc96589be229e6f3d87f21300fb8fd84c3 /src
parent0d63d521de85d1c6b9109e019101d0f575d063f7 (diff)
Added clock support
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/compilers.stanza4
-rw-r--r--src/main/stanza/custom-compiler.stanza2
-rw-r--r--src/main/stanza/custom-passes.stanza2
-rw-r--r--src/main/stanza/errors.stanza31
-rw-r--r--src/main/stanza/firrtl-ir.stanza4
-rw-r--r--src/main/stanza/flo.stanza1
-rw-r--r--src/main/stanza/ir-parser.stanza47
-rw-r--r--src/main/stanza/ir-utils.stanza40
-rw-r--r--src/main/stanza/passes.stanza157
-rw-r--r--src/main/stanza/verilog.stanza79
10 files changed, 198 insertions, 169 deletions
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza
index 2f6329dc..c458f1e1 100644
--- a/src/main/stanza/compilers.stanza
+++ b/src/main/stanza/compilers.stanza
@@ -15,7 +15,7 @@ public defmethod passes (c:StandardFlo) -> List<Pass> :
CheckHighForm(expand-delin)
;; TempElimination()
ToWorkingIR()
- MakeExplicitReset()
+ ;; MakeExplicitReset()
ResolveKinds()
CheckKinds()
InferTypes()
@@ -45,7 +45,7 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> :
CheckHighForm(expand-delin)
TempElimination()
ToWorkingIR()
- MakeExplicitReset()
+ ;; MakeExplicitReset()
ResolveKinds()
CheckKinds()
InferTypes()
diff --git a/src/main/stanza/custom-compiler.stanza b/src/main/stanza/custom-compiler.stanza
index 773b63ca..91732f22 100644
--- a/src/main/stanza/custom-compiler.stanza
+++ b/src/main/stanza/custom-compiler.stanza
@@ -17,7 +17,7 @@ public defmethod passes (c:InstrumentedVerilog) -> List<Pass> :
CheckHighForm(expand-delin)
TempElimination()
ToWorkingIR()
- MakeExplicitReset()
+ ;; MakeExplicitReset()
ResolveKinds()
CheckKinds()
InferTypes()
diff --git a/src/main/stanza/custom-passes.stanza b/src/main/stanza/custom-passes.stanza
index 6c1e58f6..4904d6d1 100644
--- a/src/main/stanza/custom-passes.stanza
+++ b/src/main/stanza/custom-passes.stanza
@@ -70,7 +70,7 @@ defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Sym
val w-ls = to-list $ when-bits
if length(w-ls) != 0 :
val reg-ref = Ref(reg-name,UIntType(IntWidth(length(w-ls))))
- add{logic,_} $ DefRegister(FileInfo(),name(reg-ref),type(reg-ref))
+ ;add{logic,_} $ DefRegister(FileInfo(),name(reg-ref),type(reg-ref)) TODO add clock and reset
add{logic,_} $ OnReset(FileInfo(),reg-ref,UIntValue(to-long $ 0,IntWidth(length(w-ls))))
for (x in w-ls, i in 0 to false) do :
add{logic,_} $ DefWire(FileInfo(),name(x),type(x))
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index e726fd00..b92939d7 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -24,7 +24,6 @@ defpackage firrtl/errors :
;AFTER ??????
; o No combinational loops
-; o cannot connect to a pad, or a register. only connct to a reference
;================= High Form Check ==========================
; * Subexps of Subfield and Index can only be subfields, index, or refs
@@ -32,7 +31,6 @@ defpackage firrtl/errors :
; * A module has the same name as main of circuit
; * mems cannot be a bundle with flips
; * instance module must have the same name as a defined module
-; * reset must be UInt<1>
; * Unique names per module
; * No name can be a prefix of any other name.
; * all references are declared
@@ -88,9 +86,9 @@ defn ModuleNotDefined (info:FileInfo, name:Symbol) :
PassException $ string-join $
[info ": Module " name " is not defined."]
-defn WrongReset (info:FileInfo, name:Symbol) :
- PassException $ string-join $
- [info ": Module " name " has a reset that is not of type UInt<1>."]
+;defn WrongReset (info:FileInfo, name:Symbol) :
+; PassException $ string-join $
+; [info ": Module " name " has a reset that is not of type UInt<1>."]
defn IncorrectNumArgs (info:FileInfo, op:Symbol, n:Int) :
PassException $ string-join $
@@ -324,15 +322,15 @@ public defn check-high-form (c:Circuit,sym:Symbol) -> Circuit :
names[name(m)] = true
for p in ports(m) do :
names[name(p)] = true
- if name(p) == `reset :
- if direction(p) == OUTPUT :
- add(errors,WrongReset(info!(m),name(m)))
- else :
- if type(p) typeof UIntType :
- if width(type(p) as UIntType) != IntWidth(1) :
- add(errors,WrongReset(info!(m),name(m)))
- else :
- add(errors,WrongReset(info!(m),name(m)))
+ ;if name(p) == `reset :
+ ; if direction(p) == OUTPUT :
+ ; add(errors,WrongReset(info!(m),name(m)))
+ ; else :
+ ; if type(p) typeof UIntType :
+ ; if width(type(p) as UIntType) != IntWidth(1) :
+ ; add(errors,WrongReset(info!(m),name(m)))
+ ; else :
+ ; add(errors,WrongReset(info!(m),name(m)))
map(check-high-form-t{info(p),_},type(p))
map(check-high-form-w{info(p),_},type(p))
@@ -436,6 +434,8 @@ public defn check-kinds (c:Circuit) -> Circuit :
; o node's value cannot be a bundle with a flip in it
; o := has same types
; o 2nd arg in dshr/l must be UInt, in general do primops
+; o clock must be ClockType
+; o reset must be UInt<1>
public defstruct CheckTypes <: Pass
public defmethod pass (b:CheckTypes) -> (Circuit -> Circuit) : check-types
@@ -499,6 +499,7 @@ defn NodeWithFlips (info:FileInfo) :
;---------------- Helper Functions --------------
defmethod equal? (t1:Type,t2:Type) -> True|False :
match(t1,t2) :
+ (t1:ClockType,t2:ClockType) : true
(t1:UIntType,t2:UIntType) : true
(t1:SIntType,t2:SIntType) : true
(t1:BundleType,t2:BundleType) :
@@ -648,7 +649,6 @@ defn gender (s:DefAccessor) -> Gender :
INFER : UNKNOWN-GENDER
RDWR : BI-GENDER
-
;----------------- Check Genders Pass ---------------------
public defn check-genders (c:Circuit) -> Circuit :
@@ -728,6 +728,7 @@ public defn check-genders (c:Circuit) -> Circuit :
; o no accessors
; o only vecs are for memories
; o no bundles (future, will have them for mems)
+; o only predicated conditional connects
public defstruct CheckLowForm <: Pass
public defmethod pass (b:CheckLowForm) -> (Circuit -> Circuit) : check-low-form
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index b698bae2..b9d2cee4 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -101,6 +101,8 @@ public defstruct DefRegister <: Stmt :
info: FileInfo with: (as-method => true)
name: Symbol
type: Type
+ clock: Expression
+ reset: Expression
public defstruct DefInstance <: Stmt : ;LOW
info: FileInfo with: (as-method => true)
name: Symbol
@@ -110,6 +112,7 @@ public defstruct DefMemory <: Stmt : ;LOW
name: Symbol
type: VectorType
seq?: True|False
+ clock: Expression
public defstruct DefNode <: Stmt : ;LOW
info: FileInfo with: (as-method => true)
name: Symbol
@@ -151,6 +154,7 @@ public defstruct BundleType <: Type :
public defstruct VectorType <: Type :
type: Type
size: Int
+public defstruct ClockType <: Type
public defstruct UnknownType <: Type
public defstruct Field :
diff --git a/src/main/stanza/flo.stanza b/src/main/stanza/flo.stanza
index 9f4cdc8c..d8fe705f 100644
--- a/src/main/stanza/flo.stanza
+++ b/src/main/stanza/flo.stanza
@@ -69,6 +69,7 @@ defn prim-width (type:Type) -> Int :
match(type) :
(t:UIntType) : sane-width(width(t))
(t:SIntType) : sane-width(width(t))
+ (t:ClockType) : 1
(t) : error("Bad prim width type")
defn sizeof (in: Int) -> Int :
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index f85ff7c9..96c50c3c 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -38,8 +38,8 @@ OPERATORS[`div] = DIV-OP
OPERATORS[`mod] = MOD-OP
OPERATORS[`quo] = QUO-OP
OPERATORS[`rem] = REM-OP
-OPERATORS[`add-wrap] = ADD-WRAP-OP
-OPERATORS[`sub-wrap] = SUB-WRAP-OP
+OPERATORS[`addw] = ADD-WRAP-OP
+OPERATORS[`subw] = SUB-WRAP-OP
OPERATORS[`lt] = LESS-OP
OPERATORS[`leq] = LESS-EQ-OP
OPERATORS[`gt] = GREATER-OP
@@ -49,20 +49,20 @@ OPERATORS[`neq] = NEQUAL-OP
OPERATORS[`mux] = MUX-OP
OPERATORS[`pad] = PAD-OP
OPERATORS[`neg] = NEG-OP
-OPERATORS[`as-UInt] = AS-UINT-OP
-OPERATORS[`as-SInt] = AS-SINT-OP
+OPERATORS[`asUInt] = AS-UINT-OP
+OPERATORS[`asSInt] = AS-SINT-OP
OPERATORS[`dshl] = DYN-SHIFT-LEFT-OP
OPERATORS[`dshr] = DYN-SHIFT-RIGHT-OP
OPERATORS[`shl] = SHIFT-LEFT-OP
OPERATORS[`shr] = SHIFT-RIGHT-OP
-OPERATORS[`convert] = CONVERT-OP
-OPERATORS[`bit-and-reduce] = BIT-AND-REDUCE-OP
-OPERATORS[`bit-or-reduce] = BIT-OR-REDUCE-OP
-OPERATORS[`bit-xor-reduce] = BIT-XOR-REDUCE-OP
-OPERATORS[`bit-not] = BIT-NOT-OP
-OPERATORS[`bit-and] = BIT-AND-OP
-OPERATORS[`bit-or] = BIT-OR-OP
-OPERATORS[`bit-xor] = BIT-XOR-OP
+OPERATORS[`cvt] = CONVERT-OP
+OPERATORS[`andr] = BIT-AND-REDUCE-OP
+OPERATORS[`orr] = BIT-OR-REDUCE-OP
+OPERATORS[`xorr] = BIT-XOR-REDUCE-OP
+OPERATORS[`not] = BIT-NOT-OP
+OPERATORS[`and] = BIT-AND-OP
+OPERATORS[`or] = BIT-OR-OP
+OPERATORS[`xor] = BIT-XOR-OP
OPERATORS[`cat] = CONCAT-OP
OPERATORS[`bit] = BIT-SELECT-OP
OPERATORS[`bits] = BITS-SELECT-OP
@@ -187,7 +187,10 @@ defsyntax firrtl :
inttype = (SInt<?w:#width$>) : SIntType(w)
inttype = (SInt) : SIntType(UnknownWidth())
+ clktype = (Clock) : ClockType()
+
type = (?t:#typeterm ?ops:#typeop ...) : apply-suffix-ops(t, ops)
+ type = (?t:#clktype) : t
typeop = ((@get ?size:#int$)) : (fn (t) : VectorType(t, size))
typeterm = (?t:#inttype) : t
@@ -213,16 +216,16 @@ defsyntax firrtl :
;Main Statement Productions
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 = (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 = (on-reset ?x:#exp := ?y:#exp!) : OnReset(first-info(form),x, y)
- stmt = (read accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i,READ)
- stmt = (write accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i,WRITE)
- stmt = (infer accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i,INFER)
- stmt = (rdwr accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name, s, i,RDWR)
+ stmt = (reg ?name:#id! #:! ?t:#type! ?clk:#exp! ?reset:#exp!) : DefRegister(first-info(form),name, t,clk,reset)
+ stmt = (cmem ?name:#id! #:! ?t:#vectype! ?clk:#exp!) : DefMemory(first-info(form),name, t, false, clk)
+ stmt = (smem ?name:#id! #:! ?t:#vectype! ?clk:#exp!) : DefMemory(first-info(form),name, t, true, clk)
+ 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 = (onreset ?x:#exp := ?y:#exp!) : OnReset(first-info(form),x,y)
+ stmt = (read accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name,s,i,READ)
+ stmt = (write accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name,s,i,WRITE)
+ stmt = (infer accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name,s,i,INFER)
+ stmt = (rdwr accessor ?name:#id! #=! ?s:#exp![?i:#exp$]) : DefAccessor(first-info(form),name,s, i,RDWR)
stmt = (?s:#stmt/when) : s
stmt = (?x:#exp := ?y:#exp!) : Connect(first-info(form),x, y)
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 8e65005f..bd8a0fd6 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -128,8 +128,8 @@ defmethod print (o:OutputStream, op:PrimOp) :
MOD-OP : "mod"
QUO-OP : "quo"
REM-OP : "rem"
- ADD-WRAP-OP : "add-wrap"
- SUB-WRAP-OP : "sub-wrap"
+ ADD-WRAP-OP : "addw"
+ SUB-WRAP-OP : "subw"
LESS-OP : "lt"
LESS-EQ-OP : "leq"
GREATER-OP : "gt"
@@ -138,21 +138,21 @@ defmethod print (o:OutputStream, op:PrimOp) :
NEQUAL-OP : "neq"
MUX-OP : "mux"
PAD-OP : "pad"
- AS-UINT-OP : "as-UInt"
- AS-SINT-OP : "as-SInt"
+ AS-UINT-OP : "asUInt"
+ AS-SINT-OP : "asSInt"
DYN-SHIFT-LEFT-OP : "dshl"
DYN-SHIFT-RIGHT-OP : "dshr"
SHIFT-LEFT-OP : "shl"
SHIFT-RIGHT-OP : "shr"
- CONVERT-OP : "convert"
+ CONVERT-OP : "cvt"
NEG-OP : "neg"
- BIT-NOT-OP : "bit-not"
- BIT-AND-OP : "bit-and"
- BIT-OR-OP : "bit-or"
- BIT-XOR-OP : "bit-xor"
- BIT-AND-REDUCE-OP : "bit-and-reduce"
- BIT-OR-REDUCE-OP : "bit-or-reduce"
- BIT-XOR-REDUCE-OP : "bit-xor-reduce"
+ BIT-NOT-OP : "not"
+ BIT-AND-OP : "and"
+ BIT-OR-OP : "or"
+ BIT-XOR-OP : "xor"
+ BIT-AND-REDUCE-OP : "andr"
+ BIT-OR-REDUCE-OP : "orr"
+ BIT-XOR-REDUCE-OP : "xorr"
CONCAT-OP : "cat"
BIT-SELECT-OP : "bit"
BITS-SELECT-OP : "bits"
@@ -176,10 +176,10 @@ defmethod print (o:OutputStream, c:Stmt) :
(c:DefWire) :
print-all(o,["wire " name(c) " : " type(c)])
(c:DefRegister) :
- print-all(o,["reg " name(c) " : " type(c)])
+ print-all(o,["reg " name(c) " : " type(c) ", " clock(c) ", " reset(c)])
(c:DefMemory) :
- if seq?(c) : print-all(o,["smem " name(c) " : " type(c)])
- else : print-all(o,["cmem " name(c) " : " type(c)])
+ if seq?(c) : print-all(o,["smem " name(c) " : " type(c) ", " clock(c)])
+ else : print-all(o,["cmem " name(c) " : " type(c) ", " clock(c)])
(c:DefInstance) :
print-all(o,["inst " name(c) " of " module(c)])
(c:DefNode) :
@@ -206,7 +206,7 @@ defmethod print (o:OutputStream, c:Stmt) :
(c:BulkConnect) :
print-all(o, [loc(c) " <> " exp(c)])
(c:OnReset) :
- print-all(o, ["on-reset " loc(c) " := " exp(c)])
+ print-all(o, ["onreset " loc(c) " := " exp(c)])
(c:EmptyStmt) :
print(o, "skip")
if not c typeof Conditionally|Begin|EmptyStmt : print-debug(o,c)
@@ -215,6 +215,8 @@ defmethod print (o:OutputStream, t:Type) :
match(t) :
(t:UnknownType) :
print(o, "?")
+ (t:ClockType) :
+ print(o, "Clock")
(t:UIntType) :
match(width(t)) :
(w:UnknownWidth) : print-all(o, ["UInt"])
@@ -290,6 +292,8 @@ public defmulti map<?T> (f: Expression -> Expression, c:?T&Stmt) -> T
defmethod map (f: Expression -> Expression, c:Stmt) -> Stmt :
match(c) :
(c:DefAccessor) : DefAccessor(info(c),name(c), f(source(c)), f(index(c)),acc-dir(c))
+ (c:DefRegister) : DefRegister(info(c),name(c), type(c), f(clock(c)), f(reset(c)))
+ (c:DefMemory) : DefMemory(info(c),name(c), type(c), seq?(c), f(clock(c)))
(c:DefNode) : DefNode(info(c),name(c), f(value(c)))
(c:DefInstance) : DefInstance(info(c),name(c), f(module(c)))
(c:Conditionally) : Conditionally(info(c),f(pred(c)), conseq(c), alt(c))
@@ -332,8 +336,8 @@ public defmulti map<?T> (f: Type -> Type, c:?T&Stmt) -> T
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,seq?(c))
+ (c:DefRegister) : DefRegister(info(c),name(c),f(type(c)),clock(c),reset(c))
+ (c:DefMemory) : DefMemory(info(c),name(c),f(type(c)) as VectorType,seq?(c),clock(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 95f2f33d..a20bec5a 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -12,7 +12,7 @@ public val standard-passes = to-list $ [
CheckHighForm(expand-delin)
TempElimination()
ToWorkingIR()
- MakeExplicitReset()
+ ;MakeExplicitReset()
ResolveKinds()
CheckKinds()
InferTypes()
@@ -350,47 +350,48 @@ defn to-working-ir (c:Circuit) :
; If reset is not explicitly passed to instantiations, then this
; pass autmatically connects the parent module's reset to the
; instantiation's reset
-public defstruct MakeExplicitReset <: Pass
-public defmethod pass (b:MakeExplicitReset) -> (Circuit -> Circuit) : make-explicit-reset
-public defmethod name (b:MakeExplicitReset) -> String : "Make Explicit Reset"
-public defmethod short-name (b:MakeExplicitReset) -> String : "make-explicit-reset"
-
-defn make-explicit-reset (c:Circuit) :
- defn find-explicit (c:Circuit) -> List<Symbol> :
- defn explicit? (m:Module) -> True|False :
- for p in ports(m) any? :
- name(p) == `reset
- val explicit-reset = Vector<Symbol>()
- for m in modules(c) do:
- if explicit?(m) : add(explicit-reset,name(m))
- to-list(explicit-reset)
-
- defn make-explicit (m:Module, explicit-reset:List<Symbol>) -> Module :
- defn route-reset (s:Stmt) -> Stmt :
- match(s) :
- (s:DefInstance) :
- val iref = WSubfield(WRef(name(s), UnknownType(), InstanceKind(), UNKNOWN-GENDER),`reset,UnknownType(),UNKNOWN-GENDER)
- val pref = WRef(`reset, UnknownType(), PortKind(), MALE)
- Begin(to-list([s,Connect(info(s),iref,pref)]))
- (s) : map(route-reset,s)
-
- var ports! = ports(m)
- if not contains?(explicit-reset,name(m)) :
- ports! = append(ports(m),list(Port(FileInfo(),`reset,INPUT,UIntType(IntWidth(1)))))
- match(m) :
- (m:InModule) :
- val body! = route-reset(body(m))
- InModule(info(m),name(m),ports!,body!)
- (m:ExModule) : ExModule(info(m),name(m),ports!)
-
- defn make-explicit-reset (m:Module, c:Circuit) -> Module :
- val explicit-reset = find-explicit(c)
- make-explicit(m,explicit-reset)
- Circuit(info(c),modules*, main(c)) where :
- val modules* =
- for m in modules(c) map :
- make-explicit-reset(m,c)
+;public defstruct MakeExplicitReset <: Pass
+;public defmethod pass (b:MakeExplicitReset) -> (Circuit -> Circuit) : make-explicit-reset
+;public defmethod name (b:MakeExplicitReset) -> String : "Make Explicit Reset"
+;public defmethod short-name (b:MakeExplicitReset) -> String : "make-explicit-reset"
+;
+;defn make-explicit-reset (c:Circuit) :
+; defn find-explicit (c:Circuit) -> List<Symbol> :
+; defn explicit? (m:Module) -> True|False :
+; for p in ports(m) any? :
+; name(p) == `reset
+; val explicit-reset = Vector<Symbol>()
+; for m in modules(c) do:
+; if explicit?(m) : add(explicit-reset,name(m))
+; to-list(explicit-reset)
+;
+; defn make-explicit (m:Module, explicit-reset:List<Symbol>) -> Module :
+; defn route-reset (s:Stmt) -> Stmt :
+; match(s) :
+; (s:DefInstance) :
+; val iref = WSubfield(WRef(name(s), UnknownType(), InstanceKind(), UNKNOWN-GENDER),`reset,UnknownType(),UNKNOWN-GENDER)
+; val pref = WRef(`reset, UnknownType(), PortKind(), MALE)
+; Begin(to-list([s,Connect(info(s),iref,pref)]))
+; (s) : map(route-reset,s)
+;
+; var ports! = ports(m)
+; if not contains?(explicit-reset,name(m)) :
+; ports! = append(ports(m),list(Port(FileInfo(),`reset,INPUT,UIntType(IntWidth(1)))))
+; match(m) :
+; (m:InModule) :
+; val body! = route-reset(body(m))
+; InModule(info(m),name(m),ports!,body!)
+; (m:ExModule) : ExModule(info(m),name(m),ports!)
+;
+; defn make-explicit-reset (m:Module, c:Circuit) -> Module :
+; val explicit-reset = find-explicit(c)
+; make-explicit(m,explicit-reset)
+;
+; Circuit(info(c),modules*, main(c)) where :
+; val modules* =
+; for m in modules(c) map :
+; make-explicit-reset(m,c)
;=============== Resolve Kinds =============================
; It is useful for the compiler to know information about
@@ -852,7 +853,7 @@ defn lower (body:Stmt) -> Stmt :
DefWire(info(s),name(x),type(x))
(s:DefRegister) : Begin{_} $
for x in generate-entry(name(s),type(s)) map :
- DefRegister(info(s),name(x),type(x))
+ DefRegister(info(s),name(x),type(x),clock(s),reset(s))
(s:DefInstance) :
val fields =
for f in fields(type(module(s)) as BundleType) map-append :
@@ -866,7 +867,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)), seq?(s))
+ DefMemory(info(s),name(x),VectorType(type(x),size(s)),seq?(s),clock(s))
(s:DefAccessor) :
val ls = generate-entry(name(s),type(s))
val rs = generate-entry(name(source(s) as WRef),type(s))
@@ -1265,14 +1266,13 @@ defn get-write-enable (sv:SymbolicValue) -> SymbolicValue :
(sv: SVNul) : SVExp(zero)
(sv) : sv
-defn merge-resets (assign:HashTable<Symbol,SymbolicValue>, resets:HashTable<Symbol,SymbolicValue>) -> HashTable<Symbol,SymbolicValue> :
+defn merge-resets (assign:HashTable<Symbol,SymbolicValue>, resets:HashTable<Symbol,SymbolicValue>, rsignals:HashTable<Symbol,Expression>) -> HashTable<Symbol,SymbolicValue> :
val table = HashTable<Symbol,SymbolicValue>(symbol-hash)
- val reset = WRef(`reset, UnknownType(), PortKind(), MALE)
for i in get-unique-keys(list(assign,resets)) do :
table[i] = match(get?(assign,i,false),get?(resets,i,false)) :
- (a:SymbolicValue,r:SymbolicValue) : SVMux(reset,r,a)
+ (a:SymbolicValue,r:SymbolicValue) : SVMux(rsignals[i],r,a)
(a:SymbolicValue,r:False) : a
- (a:False,r:SymbolicValue) : SVMux(reset,r,SVNul())
+ (a:False,r:SymbolicValue) : SVMux(rsignals[i],r,SVNul())
(a:False,r:False) : error("Shouldn't be here")
table
@@ -1280,12 +1280,17 @@ defn build-tables (s:Stmt,
assign:HashTable<Symbol,SymbolicValue>,
resets:HashTable<Symbol,SymbolicValue>,
flattn:HashTable<Symbol,True|False>,
+ rsignals:HashTable<Symbol,Expression>,
) -> False :
match(s) :
(s:DefWire) :
assign[name(s)] = SVNul()
flattn[name(s)] = true
- (s:DefRegister|DefAccessor) :
+ (s:DefRegister) :
+ assign[name(s)] = SVNul()
+ flattn[name(s)] = false
+ rsignals[name(s)] = reset(s)
+ (s:DefAccessor) :
assign[name(s)] = SVNul()
flattn[name(s)] = false
(s:DefInstance) : ;TODO only add instance input ports. This probably involves correcting instance genders
@@ -1316,8 +1321,8 @@ defn build-tables (s:Stmt,
val assign-a = deepcopy(assign)
val resets-c = deepcopy(resets)
val resets-a = deepcopy(resets)
- build-tables(conseq(s),assign-c,resets-c,flattn)
- build-tables(alt(s),assign-a,resets-a,flattn)
+ build-tables(conseq(s),assign-c,resets-c,flattn,rsignals)
+ build-tables(alt(s),assign-a,resets-a,flattn,rsignals)
for i in get-unique-keys(list(assign-c,assign-a)) do :
assign[i] = combine(flattn,assign-c,assign-a,i) as SymbolicValue
val r = combine(flattn,resets-c,resets-a,i)
@@ -1337,7 +1342,7 @@ defn build-tables (s:Stmt,
(e) : error("Shouldn't be here with ~" % [e])
if s typeof Connect : assign[key*] = SVExp(exp(s))
if s typeof OnReset : resets[key*] = SVExp(exp(s))
- (s:Begin) : for s* in body(s) do: build-tables(s*,assign,resets,flattn)
+ (s:Begin) : for s* in body(s) do: build-tables(s*,assign,resets,flattn,rsignals)
(s:DefMemory|DefNode|EmptyStmt) : false
;--------------- Expand Whens Pass -------------------
@@ -1413,13 +1418,14 @@ public defn expand-whens (c:Circuit) -> Circuit :
val assign = HashTable<Symbol,SymbolicValue>(symbol-hash)
val resets = HashTable<Symbol,SymbolicValue>(symbol-hash)
val flattn = HashTable<Symbol,True|False>(symbol-hash)
+ val rsignals = HashTable<Symbol,Expression>(symbol-hash)
for p in ports(m) do :
if direction(p) == OUTPUT :
assign[name(p)] = SVNul()
flattn[name(p)] = false
- build-tables(body(m),assign,resets,flattn)
+ 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)
@@ -1430,7 +1436,7 @@ public defn expand-whens (c:Circuit) -> Circuit :
println-debug("====== Resets ======")
for x in resets do : println-debug(x)
- val table = merge-resets(assign,resets)
+ val table = merge-resets(assign,resets,rsignals)
println-debug("====== Table ======")
for x in table do : println-debug(x)
val decs = Vector<Stmt>()
@@ -1657,6 +1663,7 @@ public defn width! (t:Type) -> Width :
match(t) :
(t:UIntType) : width(t)
(t:SIntType) : width(t)
+ (t:ClockType) : IntWidth(1)
(t) : error("No width!")
public defn width! (e:Expression) -> Width : width!(type(e))
@@ -1664,10 +1671,10 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
defn gen-constraints-s (s:Stmt) -> Stmt :
match(map(gen-constraints-s,s)) :
(s:DefWire) : DefWire(info(s),name(s),h[name(s)])
- (s:DefRegister) : DefRegister(info(s),name(s),h[name(s)])
+ (s:DefRegister) : DefRegister(info(s),name(s),h[name(s)],gen-constraints(clock(s)),gen-constraints(reset(s)))
(s:DefAccessor) : DefAccessor(info(s),name(s),gen-constraints(source(s)),gen-constraints(index(s)), acc-dir(s))
(s:DefInstance) : DefInstance(info(s),name(s),gen-constraints(module(s)))
- (s:DefMemory) : DefMemory(info(s),name(s),h[name(s)] as VectorType,seq?(s))
+ (s:DefMemory) : DefMemory(info(s),name(s),h[name(s)] as VectorType,seq?(s),gen-constraints(clock(s)))
(s:DefNode) :
val l = h[name(s)]
val r = gen-constraints(value(s))
@@ -1723,8 +1730,7 @@ defn build-environment (c:Circuit,m:Module,h:HashTable<Symbol,Type>) -> HashTabl
(s:DefRegister) : h[name(s)] = remove-unknowns(type(s))
(s:DefInstance) : h[name(s)] = h[name(module(s) as WRef)]
(s:DefMemory) : h[name(s)] = remove-unknowns(type(s))
- (s:DefAccessor) :
- h[name(s)] = remove-unknowns(type(type(source(s)) as VectorType))
+ (s:DefAccessor) : h[name(s)] = remove-unknowns(type(type(source(s)) as VectorType))
(s:DefNode) : h[name(s)] = remove-unknowns(type(value(s)))
(s) : false
do(build-environment,s)
@@ -1870,9 +1876,9 @@ defn inline-instances (c:Circuit) :
defn rename-s (s:Stmt,n:Symbol) -> Stmt :
map{rename-e{_,n},_} $ match(map(rename-s{_,n},s)) :
(s:DefWire) : DefWire(info(s),rename(name(s),n),type(s))
- (s:DefRegister) : DefRegister(info(s),rename(name(s),n),type(s))
+ (s:DefRegister) : DefRegister(info(s),rename(name(s),n),type(s),clock(s),reset(s))
(s:DefInstance) : error("Shouldn't be here")
- (s:DefMemory) : DefMemory(info(s),rename(name(s),n),type(s),seq?(s))
+ (s:DefMemory) : DefMemory(info(s),rename(name(s),n),type(s),seq?(s),clock(s))
(s:DefNode) : DefNode(info(s),rename(name(s),n),value(s))
(s) : s
for m in modules(c) do :
@@ -1901,11 +1907,17 @@ defn split-exp (c:Circuit) :
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)
+ var all-same-type? = true
+ for x in args(e) do :
+ if type(x) != type(e) : all-same-type? = false
+ all-same-type? = false
+ if not all-same-type? :
+ 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)
+ else : e
(e) : e
defn f (s:Stmt) -> False: split-exp-s(s,v,sh)
match(s) :
@@ -1916,25 +1928,24 @@ defn split-exp (c:Circuit) :
do(f,s)
(s:Connect) :
match(loc(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
- val start-time = current-time-us()
+ ;val start-time = current-time-us()
Circuit{info(c),_,main(c)} $
for m in modules(c) map :
match(m) :
(m:InModule) :
val v = Vector<Stmt>()
val sh = get-sym-hash(m)
- val before = current-time-us() - start-time
- println-all(["Before split: " before])
+ ;val before = current-time-us() - start-time
+ ;println-all(["Before split: " before])
split-exp-s(body(m),v,sh)
- val now = current-time-us() - start-time
- println-all(["After split: " now])
- println-all(["Diff: " now - before])
+ ;val now = current-time-us() - start-time
+ ;println-all(["After split: " now])
+ ;println-all(["Diff: " now - before])
InModule(info(m),name(m),ports(m),Begin(to-list(v)))
(m:ExModule) : m
@@ -2008,9 +2019,9 @@ public defn special-rename (original-sym:Symbol,new-sym:Symbol,c:Circuit) :
defn to-stmt (s:Stmt) -> Stmt :
map{to-type,_} $ match(map(to-exp,s)) :
(s:DefWire) : DefWire(info(s),rename(name(s)),type(s))
- (s:DefRegister) : DefRegister(info(s),rename(name(s)),type(s))
+ (s:DefRegister) : DefRegister(info(s),rename(name(s)),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))
+ (s:DefMemory) : DefMemory(info(s),rename(name(s)),type(s),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(to-stmt,s)
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
index 1904f92f..23591f45 100644
--- a/src/main/stanza/verilog.stanza
+++ b/src/main/stanza/verilog.stanza
@@ -36,6 +36,7 @@ defn get-width (t:Type) -> String :
match(t) :
(t:UIntType) : emit(width(t))
(t:SIntType) : emit(width(t))
+ (t:ClockType) : emit(IntWidth(1))
(t) : error("Non-supported type.")
defn remove-subfield (e:Expression) -> Expression :
@@ -140,8 +141,8 @@ defn get-name (e:Expression) -> Symbol :
(e) : error("Shouldn't be here")
defn emit-module (m:InModule) :
- val vdecs = Vector<KeyValue<Symbol,Stmt>>() ; all declarations
- val decs = HashTable<Symbol,Stmt>(symbol-hash) ; all declarations
+ val vdecs = Vector<KeyValue<Symbol,Stmt>>() ; all declarations in order, to preserve ordering
+ val decs = HashTable<Symbol,Stmt>(symbol-hash) ; all declarations, for fast lookups
val cons = HashTable<Symbol,Expression>(symbol-hash) ; all connections
val ens = HashTable<Symbol,Expression>(symbol-hash) ; all enables
defn build-table (m:InModule) :
@@ -166,7 +167,7 @@ defn emit-module (m:InModule) :
val regs = Vector<Streamable>()
val inits = Vector<Streamable>()
val assigns = Vector<Streamable>()
- val updates = Vector<Streamable>()
+ val updates = HashTable<Symbol,Vector<Streamable>>(symbol-hash)
val insts = HashTable<Symbol,Symbol>(symbol-hash) ; inst -> module
val inst-ports = HashTable<Symbol,Vector<Streamable>>(symbol-hash)
@@ -180,12 +181,14 @@ defn emit-module (m:InModule) :
add(assigns,["assign " sym " = " emit(cons[sym]) ";"])
(s:DefRegister) :
add(regs,["reg " get-width(type(s)) " " sym ";"])
+ val my-clk-update = get?(updates,get-name(clock(s)),Vector<Streamable>())
if key?(ens,sym) :
- add(updates,["if(" emit(ens[sym]) ") begin"])
- add(updates,[" " sym " <= " emit(cons[sym]) ";"])
- add(updates,["end"])
+ add(my-clk-update,["if(" emit(ens[sym]) ") begin"])
+ add(my-clk-update,[" " sym " <= " emit(cons[sym]) ";"])
+ add(my-clk-update,["end"])
else :
- add(updates,[sym " <= " emit(cons[sym]) ";"])
+ add(my-clk-update,[sym " <= " emit(cons[sym]) ";"])
+ updates[get-name(clock(s))] = my-clk-update
(s:DefMemory) :
val vtype = type(s) as VectorType
add(regs,["reg " get-width(type(vtype)) " " sym " [0:" size(vtype) "];"])
@@ -204,15 +207,17 @@ defn emit-module (m:InModule) :
if flip(f) == REVERSE :
add(assigns,["assign " n* " = " emit(cons[n*]) ";"])
(s:DefAccessor) :
+ val mem-declaration = decs[name(source(s) as Ref)] as DefMemory
switch {_ == acc-dir(s)} :
READ :
- val mem-declaration = decs[name(source(s) as Ref)]
- if seq?(mem-declaration as DefMemory) :
+ if seq?(mem-declaration) :
; to make it sequential, register the index for an additional cycle
val index* = Ref(firrtl-gensym(name(index(s) as Ref),sh),type(index(s)))
add(regs,[ "reg " get-width(type(index*)) " " name(index*) ";"])
add(inits,[name(index*) " = {" width!(type(index*)) "{$random}};"])
- add(updates,[name(index*) " <= " emit(index(s)) ";"])
+ val my-clk-update = get?(updates,get-name(clock(mem-declaration)),Vector<Streamable>())
+ add(my-clk-update,[name(index*) " <= " emit(index(s)) ";"])
+ updates[get-name(clock(mem-declaration))] = my-clk-update
; emit read accessor
add(wires,["wire " get-width(type(type(source(s)) as VectorType)) " " sym ";"])
@@ -222,27 +227,28 @@ defn emit-module (m:InModule) :
add(wires,["wire " get-width(type(type(source(s)) as VectorType)) " " sym ";"])
add(assigns,["assign " sym " = " emit(source(s)) "[" emit(index(s)) "];"])
WRITE :
+ val my-clk-update = get?(updates,get-name(clock(mem-declaration)),Vector<Streamable>())
if key?(ens,sym) :
- add(updates,["if(" emit(ens[sym]) ") begin"])
- add(updates,[" " emit(source(s)) "[" emit(index(s)) "] <= " emit(cons[sym]) ";"])
- add(updates,["end"])
+ add(my-clk-update,["if(" emit(ens[sym]) ") begin"])
+ add(my-clk-update,[" " emit(source(s)) "[" emit(index(s)) "] <= " emit(cons[sym]) ";"])
+ add(my-clk-update,["end"])
else :
- add(updates,[emit(source(s)) "[" emit(index(s)) "] <= " emit(cons[sym]) ";"])
+ add(my-clk-update,[emit(source(s)) "[" emit(index(s)) "] <= " emit(cons[sym]) ";"])
+ updates[get-name(clock(mem-declaration))] = my-clk-update
;==== Actually printing module =====
val port-indent = " "
- print-all(["module " name(m) "(input clk, input reset,\n"])
+ print-all(["module " name(m) "(\n"])
for (p in ports(m),i in 1 to false) do :
- if name(p) !=`reset :
- var end = ",\n"
- if length(ports(m)) - 1 == i :
- end = "\n);\n"
- switch {_ == direction(p)} :
- INPUT :
- print-all([port-indent "input " get-width(type(p)) " " name(p) end])
- OUTPUT :
- print-all([port-indent "output " get-width(type(p)) " " name(p) end])
- add(assigns,["assign " name(p) " = " emit(cons[name(p)]) ";"])
+ var end = ",\n"
+ if length(ports(m)) == i :
+ end = "\n);\n"
+ switch {_ == direction(p)} :
+ INPUT :
+ print-all([port-indent "input " get-width(type(p)) " " name(p) end])
+ OUTPUT :
+ print-all([port-indent "output " get-width(type(p)) " " name(p) end])
+ add(assigns,["assign " name(p) " = " emit(cons[name(p)]) ";"])
for w in wires do :
print(" ")
@@ -268,23 +274,22 @@ defn emit-module (m:InModule) :
for x in insts do :
println-all([" " value(x) " " key(x) " ("])
- print(" ")
- print-all([".clk( clk )"])
+ ;print-all([".clk( clk )"])
for (y in inst-ports[key(x)],i in 1 to false) do :
- print(",\n")
print(" ")
print-all(y)
- ;if length(inst-ports[key(x)]) != i :
- ;print(",\n")
+ if length(inst-ports[key(x)]) != i :
+ print(",\n")
println("\n );")
- if length(updates) != 0 :
- println(" always @(posedge clk) begin")
- for u in updates do :
- print(" ")
- println-all(u)
- println(" end")
-
+ for x in updates do :
+ if length(value(x)) != 0 :
+ println-all([" always @(posedge " key(x) ") begin"])
+ for u in value(x) do :
+ print(" ")
+ println-all(u)
+ println(" end")
+
println("endmodule")