aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorazidar2015-08-20 15:31:22 -0700
committerazidar2015-08-20 15:31:22 -0700
commit169164c3ad828ccae89c43d4bdbb531f3a2e6237 (patch)
tree4eadf26bb6c5c102633c524ab11a4ddd039e79ab
parentc50afcbdd1a6a2835aaa97d28412d7b913193135 (diff)
Added Poison node. Includes tests. #26.
-rw-r--r--src/main/stanza/errors.stanza38
-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.stanza1
-rw-r--r--src/main/stanza/ir-utils.stanza4
-rw-r--r--src/main/stanza/passes.stanza26
-rw-r--r--src/main/stanza/verilog.stanza5
-rw-r--r--test/errors/high-form/Flip-Poison.fir8
-rw-r--r--test/features/Poison.fir18
9 files changed, 91 insertions, 14 deletions
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index 5c77c2a4..321349d6 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -68,6 +68,10 @@ defn UndeclaredReference (info:FileInfo, name:Symbol) :
PassException $ string-join $
[info ": [module " mname "] Reference " name " is not declared."]
+defn PoisonWithFlip (info:FileInfo, name:Symbol) :
+ PassException $ string-join $
+ [info ": [module " mname "] Poison " name " cannot be a bundle type with flips."]
+
defn MemWithFlip (info:FileInfo, name:Symbol) :
PassException $ string-join $
[info ": [module " mname "] Memory " name " cannot be a bundle type with flips."]
@@ -108,6 +112,10 @@ defn NegVecSize (info:FileInfo) :
PassException $ string-join $
[info ": [module " mname "] Vector type size cannot be negative."]
+defn IllegalUnknownWidth (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Widths must be defined for memories and poison nodes."]
+
;---------------- Helper Functions --------------
defn has-flip? (t:Type) -> True|False :
var has? = false
@@ -253,19 +261,22 @@ public defn check-high-form (c:Circuit) -> Circuit :
add(errors,InvalidLOC(info))
(e) : false
- defn check-high-form-w (info:FileInfo,w:Width) -> Width :
+ defn check-high-form-w (info:FileInfo,w:Width,unknown-ok?:True|False) -> Width :
match(w) :
(w:IntWidth) :
if width(w) < 0 : add(errors,NegWidth(info))
w
+ (w:UnknownWidth) :
+ if unknown-ok? == false : add(errors,IllegalUnknownWidth(info))
+ w
(w) : w
- defn check-high-form-t (info:FileInfo,t:Type) -> Type :
- match(map(check-high-form-t{info,_},t)) :
+ defn check-high-form-t (info:FileInfo,t:Type,unknown-ok?:True|False) -> Type :
+ match(map(check-high-form-t{info,_,true},t)) :
(t:VectorType) :
if size(t) < 0 : add(errors,NegVecSize(info))
(t) : false
- map(check-high-form-w{info,_:Width},t)
+ map(check-high-form-w{info,_:Width,unknown-ok?},t)
defn check-high-form-e (info:FileInfo,e:Expression,names:HashTable<Symbol,True>) -> Expression :
match(map(check-high-form-e{info,_,names},e)) :
@@ -284,20 +295,25 @@ public defn check-high-form (c:Circuit) -> Circuit :
(e:UIntValue) : false
;if neg?(value(e)) : add(errors,NegUInt(info))
(e) : false
- map(check-high-form-w{info,_:Width},e)
- map(check-high-form-t{info,_:Type},e)
+ map(check-high-form-w{info,_:Width,true},e)
+ map(check-high-form-t{info,_:Type,true},e)
e
defn check-high-form-s (s:Stmt,names:HashTable<Symbol,True>,mnames:HashTable<Symbol,True>) -> Stmt :
defn check-name (info:FileInfo,name:Symbol) -> False :
if key?(names,name) : add(errors,NotUnique(info,name))
- map(check-high-form-t{info(s),_:Type},s)
+ map(check-high-form-t{info(s),_:Type,true},s)
map{check-high-form-s{_,names,mnames},_} $ {
match(s) : ;map(check-high-form-e{info(s),_,names},s)) :
(s:DefWire) :
check-name(info(s),name(s))
names[name(s)] = true
+ (s:DefPoison) :
+ check-name(info(s),name(s))
+ if has-flip?(type(s)) : add(errors, PoisonWithFlip(info(s), name(s)))
+ names[name(s)] = true
+ check-high-form-t(info(s),type(s),false)
(s:DefRegister) :
check-name(info(s),name(s))
names[name(s)] = true
@@ -307,6 +323,7 @@ public defn check-high-form (c:Circuit) -> Circuit :
check-name(info(s),name(s))
names[name(s)] = true
if has-flip?(type(s)) : add(errors, MemWithFlip(info(s), name(s)))
+ check-high-form-t(info(s),type(s),false)
check-high-form-e(info(s),clock(s),names)
(s:DefInstance) :
if not contains?(name(module(s) as Ref),map(name,modules(c))) :
@@ -355,8 +372,8 @@ public defn check-high-form (c:Circuit) -> Circuit :
; 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))
+ map(check-high-form-t{info(p),_,true},type(p))
+ map(check-high-form-w{info(p),_,true},type(p))
match(m) :
(m:ExModule) : false
@@ -773,6 +790,7 @@ public defn check-genders (c:Circuit) -> Circuit :
do(check-genders-s{_:Stmt,genders},s)
match(s) :
(s:DefWire) : genders[name(s)] = BI-GENDER
+ (s:DefPoison) : genders[name(s)] = MALE
(s:DefRegister) : genders[name(s)] = BI-GENDER
(s:DefNode) :
check-gender(info(s),genders,value(s),MALE)
@@ -882,6 +900,8 @@ public defn check-low-form (c:Circuit) -> Circuit :
match(s) :
(s:DefWire) :
check-low-form-t(info(s),type(s),name(s))
+ (s:DefPoison) :
+ check-low-form-t(info(s),type(s),name(s))
(s:DefMemory) :
check-low-form-t(info(s),type(type(s)),name(s))
add(mems,name(s))
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index fbe22463..de9b6cb3 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -132,6 +132,10 @@ public defstruct DefAccessor <: Stmt :
source: Expression
index: Expression
acc-dir: AccDirection
+public defstruct DefPoison <: Stmt : ;LOW
+ info: FileInfo with: (as-method => true)
+ name: Symbol
+ type: Type
public defstruct Conditionally <: Stmt :
info: FileInfo with: (as-method => true)
pred: Expression
diff --git a/src/main/stanza/flo.stanza b/src/main/stanza/flo.stanza
index 16360543..b34af613 100644
--- a/src/main/stanza/flo.stanza
+++ b/src/main/stanza/flo.stanza
@@ -162,6 +162,7 @@ defn emit-s (s:Stmt, flokinds:HashTable<Symbol,FloKind>, top:Symbol,sh:HashTable
error("Unknown Connect")
match(s) :
(s:DefWire) : ""
+ (s:DefPoison) : ""
(s:DefInstance) : error("Shouldn't be here")
(e:DefAccessor) :
if acc-dir == READ :
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index 13b23906..adffc62d 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -239,6 +239,7 @@ defsyntax firrtl :
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 = (poison ?name:#id! #:! ?t:#type!) : DefPoison(first-info(form),name, t)
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)
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 8f260e8c..3e375e81 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -71,6 +71,7 @@ public defn get-sym-hash (m:InModule,keywords:Streamable<Symbol>) -> HashTable<S
(s:DefInstance) : add-name(name(s))
(s:DefMemory) : add-name(name(s))
(s:DefNode) : add-name(name(s))
+ (s:DefPoison) : add-name(name(s))
(s:DefAccessor) : add-name(name(s))
(s) : false
map(to-stmt,s)
@@ -219,6 +220,8 @@ defmethod print (o:OutputStream, e:Expression) :
defmethod print (o:OutputStream, c:Stmt) :
val io = IndentedStream(o, 3)
match(c) :
+ (c:DefPoison) :
+ print-all(o,["poison " name(c) " : " type(c)])
(c:DefWire) :
print-all(o,["wire " name(c) " : " type(c)])
(c:DefRegister) :
@@ -381,6 +384,7 @@ defmethod map (f: Type -> Type, c:Expression) -> Expression :
public defmulti map<?T> (f: Type -> Type, c:?T&Stmt) -> T
defmethod map (f: Type -> Type, c:Stmt) -> Stmt :
match(c) :
+ (c:DefPoison) : DefPoison(info(c),name(c),f(type(c)))
(c:DefWire) : DefWire(info(c),name(c),f(type(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))
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index a6239baa..bf2e27bf 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -32,6 +32,7 @@ public val standard-passes = to-list $ [
;=============== WORKING IR ================================
public definterface Kind
public defstruct WireKind <: Kind
+public defstruct PoisonKind <: Kind
public defstruct RegKind <: Kind
public defstruct InstanceKind <: Kind
public defstruct ReadAccessorKind <: Kind
@@ -196,6 +197,7 @@ defmethod print (o:OutputStream, k:Kind) :
print{o, _} $
match(k) :
(k:WireKind) : "wire"
+ (k:PoisonKind) : "poison"
(k:RegKind) : "reg"
(k:AccessorKind) : "accessor"
(k:PortKind) : "port"
@@ -214,7 +216,7 @@ defn hasWidth (e:?) :
defn hasType (e:?) :
e typeof Ref|Subfield|Index|DoPrim|WRef|WSubfield
- |WIndex|DefWire|DefRegister|DefMemory
+ |WIndex|DefWire|DefRegister|DefMemory|DefPoison
|VectorType|Port|Field|UIntValue|SIntValue
defn hasKind (e:?) :
@@ -341,6 +343,7 @@ defn remove-special-chars (c:Circuit) :
defn rename-s (s:Stmt) -> Stmt :
match(s) :
(s:DefWire) : DefWire(info(s),rename(name(s)),rename-t(type(s)))
+ (s:DefPoison) : DefPoison(info(s),rename(name(s)),rename-t(type(s)))
(s:DefRegister) : DefRegister(info(s),rename(name(s)),rename-t(type(s)),rename-e(clock(s)),rename-e(reset(s)))
(s:DefInstance) : DefInstance(info(s),rename(name(s)),rename-e(module(s)))
(s:DefMemory) : DefMemory(info(s),rename(name(s)),rename-t(type(s)) as VectorType,seq?(s),rename-e(clock(s)))
@@ -396,7 +399,7 @@ defn remove-scopes (c:Circuit) :
else : n
defn build-s (s:Stmt) :
match(s) :
- (s:DefWire|DefRegister|DefInstance|DefMemory|DefNode|DefAccessor) :
+ (s:DefWire|DefRegister|DefInstance|DefMemory|DefNode|DefAccessor|DefPoison) :
occurrences[name(s)] = get?(occurrences,name(s),0) + 1
(s) : do(build-s,s)
defn remove-scopes-e (e:Expression,env:Vector<HashTable<Symbol,Int>>) :
@@ -406,6 +409,7 @@ defn remove-scopes (c:Circuit) :
defn remove-scopes-s (s:Stmt,env:Vector<HashTable<Symbol,Int>>) -> Stmt :
match(map(remove-scopes-e{_,env},s)) :
(s:DefWire) : DefWire(info(s),rename(name(s),env),type(s))
+ (s:DefPoison) : DefPoison(info(s),rename(name(s),env),type(s))
(s:DefRegister) : DefRegister(info(s),rename(name(s),env),type(s),clock(s),reset(s))
(s:DefInstance) : DefInstance(info(s),rename(name(s),env),module(s))
(s:DefMemory) : DefMemory(info(s),rename(name(s),env),type(s),seq?(s),clock(s))
@@ -584,6 +588,7 @@ defn resolve-kinds (c:Circuit) :
defn find-stmt (s:Stmt) -> Stmt :
match(s) :
(s:DefWire) : kinds[name(s)] = NodeKind()
+ (s:DefPoison) : kinds[name(s)] = PoisonKind()
(s:DefNode) : kinds[name(s)] = NodeKind()
(s:DefRegister) : kinds[name(s)] = RegKind()
(s:DefInstance) : kinds[name(s)] = InstanceKind()
@@ -676,6 +681,7 @@ defn infer-types (s:Stmt, l:List<KeyValue<Symbol,Type>>) -> [Stmt List<KeyValue<
s*
[Begin(body*),env]
(s:DefWire) : [s,List(name(s) => type(s),l)]
+ (s:DefPoison) : [s,List(name(s) => type(s),l)]
(s:DefRegister) : [s,List(name(s) => type(s),l)]
(s:DefMemory) : [s,List(name(s) => type(s),l)]
(s:DefInstance) : [s, List(name(s) => type(module(s)),l)]
@@ -771,6 +777,9 @@ defn resolve-genders (c:Circuit) :
defn resolve-stmt (s:Stmt) -> Stmt :
match(s) :
+ (s:DefPoison) :
+ get-gender(name(s),MALE)
+ s
(s:DefWire) :
get-gender(name(s),BI-GENDER)
s
@@ -1015,6 +1024,9 @@ defn lower (body:Stmt) -> Stmt :
defn lower-stmt (s:Stmt) -> Stmt :
;; println(s)
match(s) :
+ (s:DefPoison) : Begin $
+ for x in generate-entry(name(s),type(s)) map :
+ DefPoison(info(s),name(x),type(x))
(s:DefWire) : Begin $
for x in generate-entry(name(s),type(s)) map :
DefWire(info(s),name(x),type(x))
@@ -1510,7 +1522,7 @@ defn build-tables (s:Stmt,
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,rsignals)
- (s:DefMemory|DefNode|EmptyStmt) : false
+ (s:DefMemory|DefPoison|DefNode|EmptyStmt) : false
defn mark-referenced (referenced?:HashTable<Symbol,True>, s:Stmt) -> False :
@@ -1535,7 +1547,7 @@ defn mark-referenced (referenced?:HashTable<Symbol,True>, sv:SymbolicValue) -> S
defn is-referenced? (referenced?:HashTable<Symbol,True>, s:Stmt) -> True|False :
match(s) :
- (s:DefWire|DefRegister|DefAccessor|DefMemory|DefNode) : key?(referenced?,name(s))
+ (s:DefPoison|DefWire|DefRegister|DefAccessor|DefMemory|DefNode) : key?(referenced?,name(s))
(s:DefInstance) : true
;--------------- Expand Whens Pass -------------------
@@ -1555,6 +1567,8 @@ public defn expand-whens (c:Circuit) -> Circuit :
add(decs,s)
(s:DefMemory) :
add(decs,s)
+ (s:DefPoison) :
+ add(decs,s)
(s:DefWire) :
add(decs,s)
val ref = WRef(name(s),type(s),NodeKind(),FEMALE)
@@ -1947,6 +1961,7 @@ 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:DefPoison) : DefPoison(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)))
@@ -2001,6 +2016,7 @@ defn build-environment (c:Circuit,m:Module,h:HashTable<Symbol,Type>) -> HashTabl
defn build-environment (s:Stmt) -> False :
match(s) :
(s:DefWire) : h[name(s)] = remove-unknowns(type(s))
+ (s:DefPoison) : h[name(s)] = remove-unknowns(type(s))
(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))
@@ -2154,6 +2170,7 @@ 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:DefPoison) : DefPoison(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),clock(s))
@@ -2302,6 +2319,7 @@ 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:DefPoison) : DefPoison(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),clock(s))
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
index d4b360f0..053b78e7 100644
--- a/src/main/stanza/verilog.stanza
+++ b/src/main/stanza/verilog.stanza
@@ -165,7 +165,7 @@ defn emit-module (m:InModule) :
defn build-table (m:InModule) :
defn build-table (s:Stmt) -> Stmt :
match(map(build-table,map(remove-subfield,s))) :
- (s:DefWire|DefRegister|DefAccessor|DefMemory|DefNode|DefInstance) :
+ (s:DefWire|DefPoison|DefRegister|DefAccessor|DefMemory|DefNode|DefInstance) :
add(vdecs,name(s) => s)
decs[name(s)] = s
(s:Conditionally) :
@@ -195,6 +195,9 @@ defn emit-module (m:InModule) :
for x in vdecs do :
val sym = key(x)
match(value(x)) :
+ (s:DefPoison) :
+ add(regs,["reg " get-width(type(s)) " " sym ";"])
+ add(inits,[sym " = " rand-string(width!(type(s)))])
(s:DefWire) :
add(wires,["wire " get-width(type(s)) " " sym ";"])
add(assigns,["assign " sym " = " emit(cons[sym]) ";"])
diff --git a/test/errors/high-form/Flip-Poison.fir b/test/errors/high-form/Flip-Poison.fir
new file mode 100644
index 00000000..95a8c471
--- /dev/null
+++ b/test/errors/high-form/Flip-Poison.fir
@@ -0,0 +1,8 @@
+; RUN: firrtl -i %s -o %s.flo -X flo -p c | tee %s.out | FileCheck %s
+; CHECK: Poison p cannot be a bundle type with flips.
+
+circuit Flip-Poison :
+ module Flip-Poison :
+ input clk : Clock
+ poison p : {x : UInt<10>, flip y : UInt<10>}
+
diff --git a/test/features/Poison.fir b/test/features/Poison.fir
new file mode 100644
index 00000000..d8aa4411
--- /dev/null
+++ b/test/features/Poison.fir
@@ -0,0 +1,18 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+; CHECK: Done!
+circuit Poison :
+ module Poison :
+ input clk : Clock
+ input reset : UInt<1>
+ input index : UInt<7>
+ input p : UInt<1>
+ output out : {x : UInt<10>, y : UInt<10>}
+
+ poison q : {x : UInt<10>, y : UInt<10>}
+ smem m : {x : UInt<10>, y : UInt<10>}[128],clk
+ infer accessor r = m[index]
+ when p :
+ out := r
+ else :
+ out := q
+