diff options
| author | azidar | 2015-07-10 13:25:21 -0700 |
|---|---|---|
| committer | azidar | 2015-07-14 11:29:55 -0700 |
| commit | 0bfb3618b654a4082cc2780887b3ca32e374f455 (patch) | |
| tree | 230b7cbc96589be229e6f3d87f21300fb8fd84c3 /src | |
| parent | 0d63d521de85d1c6b9109e019101d0f575d063f7 (diff) | |
Added clock support
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/compilers.stanza | 4 | ||||
| -rw-r--r-- | src/main/stanza/custom-compiler.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/custom-passes.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/errors.stanza | 31 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 4 | ||||
| -rw-r--r-- | src/main/stanza/flo.stanza | 1 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 47 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 40 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 157 | ||||
| -rw-r--r-- | src/main/stanza/verilog.stanza | 79 |
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") |
