aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorazidar2016-01-23 15:36:09 -0800
committerazidar2016-01-23 15:36:09 -0800
commitd98526e50f9dee6edd4d885c707972cfa9666e34 (patch)
treedb879c88982cf5a16a224bdadc8d95a1bd1d3580
parent854b5d1b1e8929f74294dcce1bfb18dfbf7c874e (diff)
Added inference to mports
-rw-r--r--spec/spec.tex19
-rw-r--r--src/main/stanza/chirrtl.stanza68
-rw-r--r--src/main/stanza/compilers.stanza1
-rw-r--r--src/main/stanza/ir-parser.stanza2
-rw-r--r--test/chirrtl/infer-mport-dir.fir22
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