diff options
| author | azidar | 2016-01-23 15:36:09 -0800 |
|---|---|---|
| committer | azidar | 2016-01-23 15:36:09 -0800 |
| commit | d98526e50f9dee6edd4d885c707972cfa9666e34 (patch) | |
| tree | db879c88982cf5a16a224bdadc8d95a1bd1d3580 | |
| parent | 854b5d1b1e8929f74294dcce1bfb18dfbf7c874e (diff) | |
Added inference to mports
| -rw-r--r-- | spec/spec.tex | 19 | ||||
| -rw-r--r-- | src/main/stanza/chirrtl.stanza | 68 | ||||
| -rw-r--r-- | src/main/stanza/compilers.stanza | 1 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 2 | ||||
| -rw-r--r-- | test/chirrtl/infer-mport-dir.fir | 22 |
5 files changed, 98 insertions, 14 deletions
diff --git a/spec/spec.tex b/spec/spec.tex index fff0bbff..be0bae93 100644 --- a/spec/spec.tex +++ b/spec/spec.tex @@ -1791,19 +1791,18 @@ The concrete syntax of FIRRTL is defined in section \ref{syntax_tree}. Productio %\section{TODO} % -%- Check sponsor paragraph -% %- FIRRTL implementation -% - Make register reset/init optional -% - Rework readwrite port types -% - Add memory read-under-write flag -% - Add partial connect algorithm +% - Make register reset/init optional ; good +% - Rework readwrite port types ; limits optimizations but probably ok +% - Add memory read-under-write flag ; probably overengineering, but could be a wash +% - Add partial connect algorithm ; % - Add oriented types to type checker -% - Add is invalid -% - Add validif -% - Add UBits +% - Add is invalid ; good +% - Add validif ; good +% - Add UBits ; andrew doesn't care, favors overloading UInt % - Add SBits -% - Add Mux expression +% - Add Mux expression ; that's lovely, need glitch-free mux for clock types +% - removed addw, added head and tail ; great! \end{document} diff --git a/src/main/stanza/chirrtl.stanza b/src/main/stanza/chirrtl.stanza index fd39c001..6c56a357 100644 --- a/src/main/stanza/chirrtl.stanza +++ b/src/main/stanza/chirrtl.stanza @@ -7,12 +7,14 @@ defpackage firrtl/chirrtl : ; CHIRRTL Additional IR Nodes public definterface MPortDir +public val MInfer = new MPortDir public val MRead = new MPortDir public val MWrite = new MPortDir public val MReadWrite = new MPortDir defmethod print (o:OutputStream, m:MPortDir) : switch { m == _ } : + MInfer : print(o,"infer") MRead : print(o,"read") MWrite : print(o,"write") MReadWrite : print(o,"rdwr") @@ -52,8 +54,8 @@ defmethod map (f: Symbol -> Symbol, c:CDefMPort) -> CDefMPort : ;======================= Infer Chirrtl Types ====================== public defstruct CInferTypes <: Pass public defmethod pass (b:CInferTypes) -> (Circuit -> Circuit) : infer-types -public defmethod name (b:CInferTypes) -> String : "Infer CTypes" -public defmethod short-name (b:CInferTypes) -> String : "infer-ctypes" +public defmethod name (b:CInferTypes) -> String : "CInfer Types" +public defmethod short-name (b:CInferTypes) -> String : "c-infer-types" ;--------------- Utils ----------------- @@ -139,6 +141,63 @@ defn infer-types (c:Circuit) -> Circuit : ;========================================== +public defstruct CInferMDir <: Pass +public defmethod pass (b:CInferMDir) -> (Circuit -> Circuit) : infer-mdir +public defmethod name (b:CInferMDir) -> String : "CInfer MDir" +public defmethod short-name (b:CInferMDir) -> String : "cinfer-mdir" + +defn infer-mdir (c:Circuit) -> Circuit : + defn infer-mdir (m:Module) -> Module : + val mports = HashTable<Symbol,MPortDir>(symbol-hash) + defn infer-mdir-e (e:Expression,dir:MPortDir) -> Expression : + match(map(infer-mdir-e{_,dir},e)) : + (e:Ref) : + println(mports) + println(e) + if key?(mports,name(e)) : + println("HERE") + val new_mport_dir = + switch fn ([x,y]) : mports[name(e)] == x and dir == y : + [MInfer,MInfer] : error("Shouldn't be here") + [MInfer,MWrite] : MWrite + [MInfer,MRead] : MRead + [MWrite,MInfer] : error("Shouldn't be here") + [MWrite,MWrite] : MWrite + [MWrite,MRead] : MReadWrite + [MRead,MInfer] : error("Shouldn't be here") + [MRead,MWrite] : MReadWrite + [MRead,MRead] : MRead + mports[name(e)] = new_mport_dir + e + (e) : e + defn infer-mdir-s (s:Stmt) -> Stmt : + match(s) : + (s:CDefMPort) : + mports[name(s)] = direction(s) + map(infer-mdir-e{_,MRead},s) + (s:Connect|BulkConnect) : + infer-mdir-e(exp(s),MRead) + infer-mdir-e(loc(s),MWrite) + s + (s) : map{infer-mdir-e{_,MRead},_} $ map(infer-mdir-s,s) + defn set-mdir-s (s:Stmt) -> Stmt : + match(s) : + (s:CDefMPort) : + CDefMPort(info(s),name(s),type(s),mem(s),exps(s),mports[name(s)]) + (s) : map(set-mdir-s,s) + match(m) : + (m:InModule) : + infer-mdir-s(body(m)) + println(mports) + InModule(info(m),name(m),ports(m),set-mdir-s(body(m))) + (m:ExModule) : m + + ; MAIN + Circuit{info(c), _, main(c) } $ + for m in modules(c) map : + infer-mdir(m) + +;========================================== public defstruct RemoveCHIRRTL <: Pass public defmethod pass (b:RemoveCHIRRTL) -> (Circuit -> Circuit) : remove-chirrtl public defmethod name (b:RemoveCHIRRTL) -> String : "Remove CHIRRTL" @@ -241,8 +300,9 @@ defn remove-chirrtl (c:Circuit) : val masks = Vector<Symbol>() switch { _ == direction(s) } : MReadWrite : - repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`wdata,`rdata,`wmask) - add(addrs,`addr) + repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`rdata,`wdata,`wmask) + add(addrs,`waddr) + add(addrs,`raddr) add(ens,`wen) add(ens,`ren) add(masks,`wmask) diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza index 167efc26..bb409189 100644 --- a/src/main/stanza/compilers.stanza +++ b/src/main/stanza/compilers.stanza @@ -51,6 +51,7 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> : ;TempElimination() ; Needs to check number of uses ;=============== CInferTypes() + CInferMDir() RemoveCHIRRTL() ;=============== CheckHighForm() diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index 951d341c..7c457c19 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -270,6 +270,8 @@ defsyntax firrtl : CDefMPort(first-info(form),name,UnknownType(),mem,list(index,clk),MWrite) stmt = (rdwr mport ?name:#id! #=! ?mem:#id! (@get ?index:#exp!) ?clk:#exp!) : CDefMPort(first-info(form),name,UnknownType(),mem,list(index,clk),MReadWrite) + stmt = (infer mport ?name:#id! #=! ?mem:#id! (@get ?index:#exp!) ?clk:#exp!) : + CDefMPort(first-info(form),name,UnknownType(),mem,list(index,clk),MInfer) stmt = (mem ?name:#id! #:! (?ms:#mstat ...)) : defn grab (f:MStat -> True|False) : diff --git a/test/chirrtl/infer-mport-dir.fir b/test/chirrtl/infer-mport-dir.fir new file mode 100644 index 00000000..50baeff2 --- /dev/null +++ b/test/chirrtl/infer-mport-dir.fir @@ -0,0 +1,22 @@ +; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s +; CHECK: Done! +circuit top : + module top : + input clk : Clock + wire p : UInt + wire q : UInt + cmem m : {a:UInt<4>,b:UInt<4>}[10] + p <= UInt(1) + q <= UInt(1) + wire x : {a:UInt<4>,b:UInt<4>} + x.a <= UInt(1) + x.b <= UInt(1) + when p : + infer mport a = m[UInt(3)],clk + infer mport b = m[UInt(3)],clk + infer mport c = m[UInt(3)],clk + when q : + a <= x + x <= b + c <= x + x <= c |
