aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/errors.stanza82
-rw-r--r--src/main/stanza/firrtl-ir.stanza11
-rw-r--r--src/main/stanza/ir-parser.stanza6
-rw-r--r--src/main/stanza/ir-utils.stanza155
-rw-r--r--src/main/stanza/passes.stanza134
-rw-r--r--src/main/stanza/verilog.stanza57
6 files changed, 380 insertions, 65 deletions
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza
index 8b8c86fb..b6a854af 100644
--- a/src/main/stanza/errors.stanza
+++ b/src/main/stanza/errors.stanza
@@ -101,10 +101,27 @@ defn NegVecSize (info:FileInfo) :
PassException $ string-join $
[info ": [module " mname "] Vector type size cannot be negative."]
+defn NegMemSize (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Memory size cannot be negative or zero."]
+
defn IllegalUnknownWidth (info:FileInfo) :
PassException $ string-join $
[info ": [module " mname "] Widths must be defined for memories and poison nodes."]
+defn BadPrintf (info:FileInfo,x:Char) :
+ PassException $ string-join $
+ [info ": [module " mname "] Bad printf format: \"%" x "\""];"
+
+defn BadPrintfTrailing (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Bad printf format: trailing \"%\""];"
+
+defn BadPrintfIncorrectNum (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Bad printf format: incorrect number of arguments"];"
+
+
;---------------- Helper Functions --------------
defn has-flip? (t:Type) -> True|False :
var has? = false
@@ -194,7 +211,7 @@ defn contains?<?T> (c:?T,cs:Streamable<?T>) -> True|False :
; (s:False) : false
; (s:String) : myret(string-join([char(trie) s]))
; false
-
+
defn check-high-form-primop (e:DoPrim, errors:Vector<PassException>,info:FileInfo) -> False :
defn correct-num (ne:Int|False,nc:Int) -> False :
if not (ne typeof False) :
@@ -244,6 +261,20 @@ defn check-high-form-primop (e:DoPrim, errors:Vector<PassException>,info:FileInf
public defn check-high-form (c:Circuit) -> Circuit :
val errors = Vector<PassException>()
+
+ defn check-fstring (info:FileInfo,s:String,i:Int) -> False :
+ val valid-formats = "bedxs"
+ var percent = false
+ var ret = true
+ var npercents = 0
+ for x in s do :
+ if (not contains?(valid-formats,x)) and percent :
+ add(errors,BadPrintf(info,x))
+ if x == '%' : npercents = npercents + 1
+ percent = x == '%'
+ if percent : add(errors,BadPrintfTrailing(info))
+ if npercents != i : add(errors,BadPrintfIncorrectNum(info))
+
defn check-valid-loc (info:FileInfo,e:Expression) -> False :
match(e) :
(e:UIntValue|SIntValue|DoPrim) :
@@ -312,6 +343,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)))
+ if size(s) <= 0 : add(errors,NegMemSize(info(s)))
check-high-form-t(info(s),type(s),false)
check-high-form-e(info(s),clock(s),names)
(s:DefInstance) :
@@ -332,6 +364,10 @@ public defn check-high-form (c:Circuit) -> Circuit :
check-valid-loc(info(s),loc(s))
check-high-form-e(info(s),loc(s),names)
check-high-form-e(info(s),exp(s),names)
+ (s:PrintfStmt) :
+ for x in args(s) do:
+ check-high-form-e(info(s),x,names)
+ check-fstring(info(s),string(s),length(args(s)))
(s:BulkConnect) :
check-valid-loc(info(s),loc(s))
check-high-form-e(info(s),loc(s),names)
@@ -394,11 +430,20 @@ defn OnResetNotReg (info:FileInfo, name:Symbol) :
PassException $ string-join $
[info ": [module " mname "] Illegal on-reset to non-reg reference " name "."]
+defn AccessVecOrMem (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Accessors can only access vector-typed components or memories."]
+
;----------------- Check Kinds Pass ---------------------
; I may have been overeager in looking for places where mems can't be, as mems are guaranteed to have a vector
; type, and this will get caught in the type check pass
public defn check-kinds (c:Circuit) -> Circuit :
val errors = Vector<PassException>()
+ defn get-kind (e:Expression) -> Kind :
+ match(e) :
+ (e:WRef) : kind(e)
+ (e:WSubfield) : get-kind(exp(e))
+ (e:WIndex) : get-kind(exp(e))
defn check-not-mem (info:FileInfo,e:Expression) -> False :
do(check-not-mem{info,_},e)
match(e) :
@@ -424,8 +469,16 @@ public defn check-kinds (c:Circuit) -> Circuit :
defn check-kinds-s (s:Stmt) -> False :
match(s) :
(s:DefNode) : check-not-mem(info(s),value(s))
- (s:DefAccessor) : check-not-mem(info(s),index(s))
+ (s:DefAccessor) :
+ check-not-mem(info(s),index(s))
+ if (get-kind(source(s)) != MemKind()) and (not type(source(s)) typeof VectorType) :
+ println(get-kind(source(s)))
+ println(type(source(s)))
+ add(errors,AccessVecOrMem(info(s)))
(s:Conditionally) : check-not-mem(info(s),pred(s))
+ (s:PrintfStmt) :
+ for x in args(s) do :
+ check-not-mem(info(s),x)
(s:Connect) :
check-not-mem(info(s),loc(s))
check-not-mem(info(s),exp(s))
@@ -491,6 +544,10 @@ defn InvalidConnect (info:FileInfo) :
PassException $ string-join $
[info ": [module " mname "] Type mismatch."]
+defn PrintfArgNotGround (info:FileInfo) :
+ PassException $ string-join $
+ [info ": [module " mname "] Printf arguments must be either UIntType or SIntType."]
+
defn PredNotUInt (info:FileInfo) :
PassException $ string-join $
[info ": [module " mname "] Predicate not a UIntType."]
@@ -519,7 +576,6 @@ defn OnResetIllegalFlips (info:FileInfo) :
PassException $ string-join $
[info ": [module " mname "] The register in onreset cannot be a bundle type with flips."]
-
;---------------- Helper Functions --------------
defmethod equal? (t1:Type,t2:Type) -> True|False :
match(t1,t2) :
@@ -538,8 +594,8 @@ defmethod equal? (t1:Type,t2:Type) -> True|False :
else : false
(t1,t2) : false
-defn u () -> UIntType : UIntType(UnknownWidth())
-defn s () -> SIntType : SIntType(UnknownWidth())
+defn ut () -> UIntType : UIntType(UnknownWidth())
+defn st () -> SIntType : SIntType(UnknownWidth())
defn check-types-primop (e:DoPrim, errors:Vector<PassException>,info:FileInfo) -> False :
defn all-same-type (ls:List<Expression>) -> False :
@@ -658,8 +714,12 @@ public defn check-types (c:Circuit) -> Circuit :
(s:OnReset) :
if type(loc(s)) != type(exp(s)) : add(errors,InvalidConnect(info(s)))
if has-flip?(type(loc(s))) : add(errors,OnResetIllegalFlips(info(s)))
+ (s:PrintfStmt) :
+ for x in args(s) do :
+ if type(x) != ut() and type(x) != st():
+ add(errors,PrintfArgNotGround(info(s)))
(s:Conditionally) :
- if type(pred(s)) != u() : add(errors,PredNotUInt(info(s)))
+ if type(pred(s)) != ut() : add(errors,PredNotUInt(info(s)))
(s:DefNode) :
if has-flip?(type(value(s))) : add(errors,NodeIllegalFlips(info(s)))
(s) : false
@@ -790,6 +850,9 @@ public defn check-genders (c:Circuit) -> Circuit :
(s:Connect) :
check-gender(info(s),genders,loc(s),FEMALE)
check-gender(info(s),genders,exp(s),MALE)
+ (s:PrintfStmt) :
+ for x in args(s) do :
+ check-gender(info(s),genders,x,MALE)
(s:BulkConnect) :
check-gender(info(s),genders,loc(s),FEMALE)
check-gender(info(s),genders,exp(s),MALE)
@@ -799,6 +862,7 @@ public defn check-genders (c:Circuit) -> Circuit :
(s:Conditionally) :
check-gender(info(s),genders,pred(s),MALE)
(s:EmptyStmt) : false
+ (s:StopStmt) : false
(s:Begin) : false
@@ -1030,7 +1094,7 @@ public defn check-low-form (c:Circuit) -> Circuit :
(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))
+ check-low-form-t(info(s),type(s),name(s))
add(mems,name(s))
(s:DefInstance) :
for f in fields(type(module(s)) as BundleType) do :
@@ -1038,6 +1102,9 @@ public defn check-low-form (c:Circuit) -> Circuit :
add(insts,name(s))
(s:DefNode) :
check-correct-exp(info(s),value(s))
+ (s:PrintfStmt) :
+ for x in args(s) do :
+ check-correct-exp(info(s),x)
(s:DefRegister) : false
(s:DefAccessor) : false
(s:Conditionally) :
@@ -1053,6 +1120,7 @@ public defn check-low-form (c:Circuit) -> Circuit :
else : assigned?[to-symbol $ to-string $ e] = true
(e) : check-correct-exp(info(s),e)
(s:EmptyStmt) : false
+ (s:StopStmt) : false
(s:Begin) : do(check-low-form-s,s)
match(m) :
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index b0db73b2..5bc1ea68 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -118,9 +118,10 @@ public defstruct DefInstance <: Stmt : ;LOW
public defstruct DefMemory <: Stmt : ;LOW
info: FileInfo with: (as-method => true)
name: Symbol
- type: VectorType
+ type: Type
seq?: True|False
clock: Expression
+ size: Int
public defstruct DefNode <: Stmt : ;LOW
info: FileInfo with: (as-method => true)
name: Symbol
@@ -154,6 +155,14 @@ public defstruct Connect <: Stmt : ;LOW
info: FileInfo with: (as-method => true)
loc: Expression
exp: Expression
+public defstruct StopStmt <: Stmt : ;LOW
+ info: FileInfo with: (as-method => true)
+ ret: Int
+public defstruct PrintfStmt <: Stmt : ;LOW
+ info: FileInfo with: (as-method => true)
+ string: String
+ args: List<Expression>
+
public defstruct EmptyStmt <: Stmt ;LOW
public definterface Type
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index f81777f5..a4ca89f7 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -236,8 +236,8 @@ defsyntax firrtl :
stmt = (skip) : EmptyStmt()
stmt = (wire ?name:#id! #:! ?t:#type!) : DefWire(first-info(form),name, t)
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 = (cmem ?name:#id! #:! ?t:#vectype! ?clk:#exp!) : DefMemory(first-info(form),name, type(t), false, clk, size(t))
+ stmt = (smem ?name:#id! #:! ?t:#vectype! ?clk:#exp!) : DefMemory(first-info(form),name, type(t), true, clk, size(t))
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)
@@ -246,6 +246,8 @@ defsyntax firrtl :
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 = (stop(?ret:#int)) : StopStmt(first-info(form),ret)
+ stmt = (printf(?str:#string ?es:#exp ...)) : PrintfStmt(first-info(form),str,es)
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 27acedb3..3fd96882 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -110,6 +110,11 @@ public defmethod print (o:OutputStream, p:Pass) :
;============== Various Useful Functions ==============
+public defn add-all (v1:Vector,v2:Vector) -> False :
+ for x in v2 do :
+ add(v1,x)
+
+
public defn ceil-log2 (i:Long) -> Long :
defn* loop (n:Long, l:Long) :
if n < i :
@@ -138,6 +143,17 @@ public defn req-num-bits (i: Int) -> Int :
else : i
ceil-log2(i* + 1) + 1
+defn escape (s:String) -> String :
+ val s* = Vector<String>()
+ add(s*,"\"");"
+ for c in s do :
+ if c == '\n' :
+ add(s*,"\\n")
+ else : add(s*,to-string(c))
+ add(s*,"\"");"
+ string-join(s*)
+ ;"
+
;============== PRINTERS ===================================
defmethod print (o:OutputStream, d:Flip) :
@@ -230,8 +246,8 @@ defmethod print (o:OutputStream, c:Stmt) :
(c:DefRegister) :
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) ", " clock(c)])
- else : print-all(o,["cmem " name(c) " : " type(c) ", " clock(c)])
+ if seq?(c) : print-all(o,["smem " name(c) " : " VectorType(type(c),size(c)) ", " clock(c)])
+ else : print-all(o,["cmem " name(c) " : " VectorType(type(c),size(c)) ", " clock(c)])
(c:DefInstance) :
print-all(o,["inst " name(c) " of " module(c)])
(c:DefNode) :
@@ -261,6 +277,13 @@ defmethod print (o:OutputStream, c:Stmt) :
print-all(o, ["onreset " loc(c) " := " exp(c)])
(c:EmptyStmt) :
print(o, "skip")
+ (c:StopStmt) :
+ print-all(o, ["stop(" ret(c) ")"])
+ (c:PrintfStmt) :
+ print-all(o, ["printf("]) ;"
+ print-all(o, join(List(escape(string(c)),args(c)), ", "))
+ print(o, ")")
+
if not c typeof Conditionally|Begin|EmptyStmt : print-debug(o,c)
defmethod print (o:OutputStream, t:Type) :
@@ -345,13 +368,14 @@ 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:DefMemory) : DefMemory(info(c),name(c), type(c), seq?(c), f(clock(c)), size(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))
(c:Connect) : Connect(info(c),f(loc(c)), f(exp(c)))
(c:BulkConnect) : BulkConnect(info(c),f(loc(c)), f(exp(c)))
(c:OnReset) : OnReset(info(c),f(loc(c)),f(exp(c)))
+ (c:PrintfStmt) : PrintfStmt(info(c),string(c),map(f,args(c)))
(c) : c
public defmulti map<?T> (f: Stmt -> Stmt, c:?T&Stmt) -> T
@@ -390,7 +414,7 @@ defmethod map (f: Type -> Type, c:Stmt) -> Stmt :
(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))
+ (c:DefMemory) : DefMemory(info(c),name(c),f(type(c)),seq?(c),clock(c),size(c))
(c) : c
public defmulti mapr<?T> (f: Width -> Width, t:?T&Type) -> T
@@ -524,94 +548,199 @@ public defn pow (x:Long,y:Long) -> Long :
;=================== VERILOG KEYWORDS =======================
public val v-keywords = HashTable<Symbol,True>(symbol-hash)
+v-keywords[`alias] = true
v-keywords[`always] = true
+v-keywords[`always_comb] = true
+v-keywords[`always_ff] = true
+v-keywords[`always_latch] = true
v-keywords[`and] = true
+v-keywords[`assert] = true
v-keywords[`assign] = true
+v-keywords[`assume] = true
v-keywords[`attribute] = true
+v-keywords[`automatic] = true
+v-keywords[`before] = true
v-keywords[`begin] = true
+v-keywords[`bind] = true
+v-keywords[`bins] = true
+v-keywords[`binsof] = true
+v-keywords[`bit] = true
+v-keywords[`break] = true
v-keywords[`buf] = true
v-keywords[`bufif0] = true
v-keywords[`bufif1] = true
+v-keywords[`byte] = true
v-keywords[`case] = true
v-keywords[`casex] = true
v-keywords[`casez] = true
+v-keywords[`cell] = true
+v-keywords[`chandle] = true
+v-keywords[`class] = true
+v-keywords[`clocking] = true
v-keywords[`cmos] = true
+v-keywords[`config] = true
+v-keywords[`const] = true
+v-keywords[`constraint] = true
+v-keywords[`context] = true
+v-keywords[`continue] = true
+v-keywords[`cover] = true
+v-keywords[`covergroup] = true
+v-keywords[`coverpoint] = true
+v-keywords[`cross] = true
v-keywords[`deassign] = true
v-keywords[`default] = true
v-keywords[`defparam] = true
+v-keywords[`design] = true
v-keywords[`disable] = true
+v-keywords[`dist] = true
+v-keywords[`do] = true
v-keywords[`edge] = true
v-keywords[`else] = true
v-keywords[`end] = true
v-keywords[`endattribute] = true
v-keywords[`endcase] = true
+v-keywords[`endclass] = true
+v-keywords[`endclocking] = true
+v-keywords[`endconfig] = true
v-keywords[`endfunction] = true
+v-keywords[`endgenerate] = true
+v-keywords[`endgroup] = true
+v-keywords[`endinterface] = true
v-keywords[`endmodule] = true
+v-keywords[`endpackage] = true
v-keywords[`endprimitive] = true
+v-keywords[`endprogram] = true
+v-keywords[`endproperty] = true
v-keywords[`endspecify] = true
+v-keywords[`endsequence] = true
v-keywords[`endtable] = true
v-keywords[`endtask] = true
+v-keywords[`enum] = true
v-keywords[`event] = true
+v-keywords[`expect] = true
+v-keywords[`export] = true
+v-keywords[`extends] = true
+v-keywords[`extern] = true
+v-keywords[`final] = true
+v-keywords[`first_match] = true
v-keywords[`for] = true
v-keywords[`force] = true
+v-keywords[`foreach] = true
v-keywords[`forever] = true
v-keywords[`fork] = true
+v-keywords[`forkjoin] = true
v-keywords[`function] = true
+v-keywords[`generate] = true
+v-keywords[`genvar] = true
v-keywords[`highz0] = true
v-keywords[`highz1] = true
v-keywords[`if] = true
+v-keywords[`iff] = true
v-keywords[`ifnone] = true
+v-keywords[`ignore_bins] = true
+v-keywords[`illegal_bins] = true
+v-keywords[`import] = true
+v-keywords[`incdir] = true
+v-keywords[`include] = true
v-keywords[`initial] = true
+v-keywords[`initvar] = true
v-keywords[`inout] = true
v-keywords[`input] = true
+v-keywords[`inside] = true
+v-keywords[`instance] = true
+v-keywords[`int] = true
v-keywords[`integer] = true
-v-keywords[`initvar] = true
+v-keywords[`interconnect] = true
+v-keywords[`interface] = true
+v-keywords[`intersect] = true
v-keywords[`join] = true
-v-keywords[`medium] = true
-v-keywords[`module] = true
+v-keywords[`join_any] = true
+v-keywords[`join_none] = true
v-keywords[`large] = true
+v-keywords[`liblist] = true
+v-keywords[`library] = true
+v-keywords[`local] = true
+v-keywords[`localparam] = true
+v-keywords[`logic] = true
+v-keywords[`longint] = true
v-keywords[`macromodule] = true
+v-keywords[`matches] = true
+v-keywords[`medium] = true
+v-keywords[`modport] = true
+v-keywords[`module] = true
v-keywords[`nand] = true
v-keywords[`negedge] = true
+v-keywords[`new] = true
v-keywords[`nmos] = true
v-keywords[`nor] = true
+v-keywords[`noshowcancelled] = true
v-keywords[`not] = true
v-keywords[`notif0] = true
v-keywords[`notif1] = true
+v-keywords[`null] = true
v-keywords[`or] = true
v-keywords[`output] = true
+v-keywords[`package] = true
+v-keywords[`packed] = true
v-keywords[`parameter] = true
v-keywords[`pmos] = true
v-keywords[`posedge] = true
v-keywords[`primitive] = true
+v-keywords[`priority] = true
+v-keywords[`program] = true
+v-keywords[`property] = true
+v-keywords[`protected] = true
v-keywords[`pull0] = true
v-keywords[`pull1] = true
v-keywords[`pulldown] = true
v-keywords[`pullup] = true
+v-keywords[`pulsestyle_onevent] = true
+v-keywords[`pulsestyle_ondetect] = true
+v-keywords[`pure] = true
+v-keywords[`rand] = true
+v-keywords[`randc] = true
+v-keywords[`randcase] = true
+v-keywords[`randsequence] = true
v-keywords[`rcmos] = true
v-keywords[`real] = true
v-keywords[`realtime] = true
+v-keywords[`ref] = true
v-keywords[`reg] = true
v-keywords[`release] = true
v-keywords[`repeat] = true
+v-keywords[`return] = true
v-keywords[`rnmos] = true
v-keywords[`rpmos] = true
v-keywords[`rtran] = true
v-keywords[`rtranif0] = true
v-keywords[`rtranif1] = true
v-keywords[`scalared] = true
+v-keywords[`sequence] = true
+v-keywords[`shortint] = true
+v-keywords[`shortreal] = true
+v-keywords[`showcancelled] = true
v-keywords[`signed] = true
v-keywords[`small] = true
+v-keywords[`solve] = true
v-keywords[`specify] = true
v-keywords[`specparam] = true
+v-keywords[`static] = true
v-keywords[`strength] = true
+v-keywords[`string] = true
v-keywords[`strong0] = true
v-keywords[`strong1] = true
+v-keywords[`struct] = true
+v-keywords[`super] = true
v-keywords[`supply0] = true
v-keywords[`supply1] = true
v-keywords[`table] = true
+v-keywords[`tagged] = true
v-keywords[`task] = true
+v-keywords[`this] = true
+v-keywords[`throughout] = true
v-keywords[`time] = true
+v-keywords[`timeprecision] = true
+v-keywords[`timeunit] = true
v-keywords[`tran] = true
v-keywords[`tranif0] = true
v-keywords[`tranif1] = true
@@ -621,14 +750,26 @@ v-keywords[`tri1] = true
v-keywords[`triand] = true
v-keywords[`trior] = true
v-keywords[`trireg] = true
+v-keywords[`type] = true
+v-keywords[`typedef] = true
+v-keywords[`union] = true
+v-keywords[`unique] = true
v-keywords[`unsigned] = true
+v-keywords[`use] = true
+v-keywords[`var] = true
v-keywords[`vectored] = true
+v-keywords[`virtual] = true
+v-keywords[`void] = true
v-keywords[`wait] = true
+v-keywords[`wait_order] = true
v-keywords[`wand] = true
v-keywords[`weak0] = true
v-keywords[`weak1] = true
v-keywords[`while] = true
+v-keywords[`wildcard] = true
v-keywords[`wire] = true
+v-keywords[`with] = true
+v-keywords[`within] = true
v-keywords[`wor] = true
v-keywords[`xnor] = true
v-keywords[`xor] = true
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 0c812535..f2931bc8 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -186,7 +186,7 @@ public var PRINT-GENDERS : True|False = false
public var PRINT-CIRCUITS : True|False = false
public var PRINT-DEBUG : True|False = false
public var PRINT-INFO : True|False = false
-;=== Printers ===
+;=== ThePrinters ===
public defn println-all-debug (l:?) -> False :
if PRINT-DEBUG : println-all(l)
@@ -349,7 +349,7 @@ defn remove-special-chars (c:Circuit) :
(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)))
+ (s:DefMemory) : DefMemory(info(s),rename(name(s)),rename-t(type(s)),seq?(s),rename-e(clock(s)),size(s))
(s:DefNode) : DefNode(info(s),rename(name(s)),rename-e(value(s)))
(s:DefAccessor) : DefAccessor(info(s),rename(name(s)),rename-e(source(s)),rename-e(index(s)),acc-dir(s))
(s:Conditionally) : Conditionally(info(s),rename-e(pred(s)),rename-s(conseq(s)),rename-s(alt(s)))
@@ -358,6 +358,8 @@ defn remove-special-chars (c:Circuit) :
(s:BulkConnect) : BulkConnect(info(s),rename-e(loc(s)),rename-e(exp(s)))
(s:Connect) : Connect(info(s),rename-e(loc(s)),rename-e(exp(s)))
(s:EmptyStmt) : s
+ (s:StopStmt) : s
+ (s:PrintfStmt) : PrintfStmt(info(s),string(s),map(rename-e,args(s)))
Circuit(info(c),modules*, rename(main(c))) where :
val modules* =
@@ -415,7 +417,7 @@ defn remove-scopes (c:Circuit) :
(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))
+ (s:DefMemory) : DefMemory(info(s),rename(name(s),env),type(s),seq?(s),clock(s),size(s))
(s:DefNode) : DefNode(info(s),rename(name(s),env),value(s))
(s:DefAccessor) : DefAccessor(info(s),rename(name(s),env),source(s),index(s),acc-dir(s))
(s:Conditionally) :
@@ -688,12 +690,12 @@ defn infer-types (s:Stmt, l:List<KeyValue<Symbol,Type>>) -> [Stmt List<KeyValue<
(s:DefMemory) : [s,List(name(s) => type(s),l)]
(s:DefInstance) : [s, List(name(s) => type(module(s)),l)]
(s:DefNode) : [s, List(name(s) => type(value(s)),l)]
- (s:DefAccessor) : [s, List(name(s) => get-vector-subtype(type(source(s))),l)]
+ (s:DefAccessor) : [s, List(name(s) => type(s),l)]
(s:Conditionally) :
val [s*,l*] = infer-types(conseq(s),l)
val [s**,l**] = infer-types(alt(s),l)
[Conditionally(info(s),pred(s),s*,s**),l]
- (s:Connect|BulkConnect|OnReset|EmptyStmt) : [s,l]
+ (s:Connect|BulkConnect|OnReset|EmptyStmt|StopStmt|PrintfStmt) : [s,l]
defn infer-types (m:Module, l:List<KeyValue<Symbol,Type>>) -> Module :
val ptypes =
@@ -812,6 +814,8 @@ defn resolve-genders (c:Circuit) :
val conseq* = resolve-stmt(conseq(s))
val alt* = resolve-stmt(alt(s))
Conditionally(info(s),pred*,conseq*,alt*)
+ (s:PrintfStmt) :
+ PrintfStmt(info(s),string(s),map(resolve-expr{_,MALE},args(s)))
(s) : map(resolve-stmt,s)
defn resolve-expr (e:Expression,desired:Gender) -> Expression :
@@ -1001,9 +1005,16 @@ defn lower-ports (ports:List<Port>) -> List<Port> :
for x in generate-entry(name(p),type(p)) map :
Port(info(p),name(x),direction(p) * flip(x),type(x))
-defn type (s:DefAccessor) -> Type : type(type(source(s)) as VectorType)
-defn size (s:DefMemory) -> Int : size(type(s))
-defn size (s:DefAccessor) -> Int : size(type(source(s)) as VectorType)
+defn get-kind (e:Expression) -> Kind :
+ match(e) :
+ (e:WRef) : kind(e)
+ (e:WSubfield) : get-kind(exp(e))
+ (e:WIndex) : get-kind(exp(e))
+
+defn type (s:DefAccessor) -> Type :
+ if get-kind(source(s)) == MemKind() : type(source(s))
+ else : type(type(source(s)) as VectorType)
+
defn base-name (e:Expression) -> Symbol :
match(e) :
(e:WRef) : name(e)
@@ -1041,15 +1052,15 @@ defn lower (body:Stmt) -> Stmt :
for x in expand-expr(value(s)) map :
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),clock(s))
+ for x in generate-entry(name(s),type(s)) map :
+ DefMemory(info(s),name(x),type(x),seq?(s),clock(s),size(s))
(s:DefAccessor) :
val ls = generate-entry(name(s),type(s))
val rs = generate-entry(name(source(s) as WRef),type(s))
val index* = exp(head $ expand-expr(index(s)))
Begin $ for (l in ls, r in rs) map:
if flip(r) == REVERSE : error("Shouldn't be here")
- val memref = WRef(name(r),VectorType(type(r),size(s)),MemKind(),gender(s))
+ val memref = WRef(name(r),type(r),MemKind(),gender(s))
DefAccessor(info(s),name(l),memref,index*,to-acc-dir(gender(s)))
(s:OnReset|Connect) : Begin $
for (l in expand-expr(loc(s)), r in expand-expr(exp(s))) map :
@@ -1115,7 +1126,10 @@ defn lower (body:Stmt) -> Stmt :
[MALE,FEMALE] : DecFromIndexer(info(s),index*,exps,name(ntf),type(ntf))
(s:Conditionally) :
Conditionally(info(s),exp(head $ expand-expr(pred(s))),lower-stmt(conseq(s)),lower-stmt(alt(s)))
- (s:Begin|EmptyStmt) : map(lower-stmt,s)
+ (s:PrintfStmt) :
+ val args* = for x in args(s) map : exp(head(expand-expr(x)))
+ PrintfStmt(info(s),string(s),args*)
+ (s:Begin|EmptyStmt|StopStmt) : map(lower-stmt,s)
lower-stmt(body)
@@ -1527,11 +1541,23 @@ defn merge-resets (assign:HashTable<Symbol,SymbolicValue>, resets:HashTable<Symb
(a:False,r:False) : error("Shouldn't be here")
table
+defn mark (vs:Vector<[Stmt,Expression]>,pred:Expression) -> False :
+ for i in 0 to length(vs) do :
+ val [s,e] = vs[i]
+ vs[i] = [s, AND(e,pred)]
+
+; ------ Print Debug Info ------
+defn print-table (t:HashTable<Symbol,SymbolicValue>,s:String) :
+ println-debug(s)
+ for x in t do : println-debug(x)
+
+
defn build-tables (s:Stmt,
assign:HashTable<Symbol,SymbolicValue>,
resets:HashTable<Symbol,SymbolicValue>,
flattn:HashTable<Symbol,True|False>,
rsignals:HashTable<Symbol,Expression>,
+ simuls:Vector<[Stmt,Expression]>,
) -> False :
match(s) :
(s:DefWire) :
@@ -1573,26 +1599,28 @@ 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,rsignals)
- build-tables(alt(s),assign-a,resets-a,flattn,rsignals)
+ val simuls-c = Vector<[Stmt,Expression]>()
+ val simuls-a = Vector<[Stmt,Expression]>()
+ build-tables(conseq(s),assign-c,resets-c,flattn,rsignals,simuls-c)
+ build-tables(alt(s),assign-a,resets-a,flattn,rsignals,simuls-a)
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)
match(r) :
(r:SymbolicValue) : resets[i] = r
(r) : false
- println-debug("TABLE-C")
- for x in assign-c do : println-debug(x)
- println-debug("TABLE-A")
- for x in assign-a do : println-debug(x)
- println-debug("TABLE")
- for x in assign do : println-debug(x)
- println-debug("RESET-C")
- for x in resets-c do : println-debug(x)
- println-debug("RESET-A")
- for x in resets-a do : println-debug(x)
- println-debug("RESET")
- for x in resets do : println-debug(x)
+
+ mark(simuls-c,pred(s))
+ mark(simuls-a,DoPrim(BIT-NOT-OP,list(pred(s)),list(),UIntType(LongWidth(1))))
+ add-all(simuls,simuls-c)
+ add-all(simuls,simuls-a)
+
+ print-table(assign-c,"TABLE-C")
+ print-table(assign-a,"TABLE-A")
+ print-table(assign,"TABLE")
+ print-table(resets-c,"RESET-C")
+ print-table(resets-a,"RESET-A")
+ print-table(resets,"RESET")
(s:Connect|OnReset) :
val key* = match(loc(s)) :
(e:WRef) : name(e)
@@ -1600,7 +1628,9 @@ 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,rsignals)
+ (s:Begin) : for s* in body(s) do: build-tables(s*,assign,resets,flattn,rsignals,simuls)
+ (s:StopStmt|PrintfStmt) :
+ add(simuls,[s one])
(s:DefMemory|DefPoison|DefNode|EmptyStmt) : false
@@ -1628,6 +1658,7 @@ defn is-referenced? (referenced?:HashTable<Symbol,True>, s:Stmt) -> True|False :
match(s) :
(s:DefPoison|DefWire|DefRegister|DefAccessor|DefMemory|DefNode) : key?(referenced?,name(s))
(s:DefInstance) : true
+ (s:PrintfStmt|StopStmt|Conditionally) : true
;--------------- Expand Whens Pass -------------------
@@ -1667,7 +1698,7 @@ public defn expand-whens (c:Circuit) -> Circuit :
(e:False) : false
(s:DefAccessor) :
add(decs,s)
- val t = type(type(source(s)) as VectorType)
+ val t = type(s)
val n = name(s)
if gender(s) == FEMALE :
val ref = WRef(n,t,WriteAccessorKind(),FEMALE)
@@ -1691,7 +1722,7 @@ public defn expand-whens (c:Circuit) -> Circuit :
val sref = WSubfield(ref,f,bundle-field-type(type(module(s)),f),FEMALE)
if not has-nul?(table[n]) :
add{cons,_} $ Connect(info(s),sref,to-exp(table[n]) as Expression)
- (s:Connect|Conditionally|OnReset|Begin|EmptyStmt) : false
+ (s:Connect|Conditionally|OnReset|Begin|EmptyStmt|StopStmt|PrintfStmt) : false
s
defn expand-whens (m:Module) -> Module :
@@ -1702,13 +1733,14 @@ public defn expand-whens (c:Circuit) -> Circuit :
val resets = HashTable<Symbol,SymbolicValue>(symbol-hash)
val flattn = HashTable<Symbol,True|False>(symbol-hash)
val rsignals = HashTable<Symbol,Expression>(symbol-hash)
+ val simuls = Vector<[Stmt,Expression]>()
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,rsignals)
+ build-tables(body(m),assign,resets,flattn,rsignals,simuls)
for x in assign do : assign[key(x)] = optimize(value(x))
for x in resets do : resets[key(x)] = optimize(value(x))
@@ -1729,6 +1761,11 @@ public defn expand-whens (c:Circuit) -> Circuit :
expand-whens(ports(m),table,cons)
expand-whens(body(m),table,decs,cons)
+ for se in simuls do :
+ val [s e] = se
+ if e == one : add(decs,s)
+ else : add(decs,Conditionally(info(s),e,s,EmptyStmt()))
+
val referenced? = HashTable<Symbol,True>(symbol-hash)
for x in table do :
mark-referenced(referenced?,value(x))
@@ -2034,7 +2071,7 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
(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),gen-constraints(clock(s)))
+ (s:DefMemory) : DefMemory(info(s),name(s),h[name(s)],seq?(s),gen-constraints(clock(s)),size(s))
(s:DefNode) :
val l = h[name(s)]
val r = gen-constraints(value(s))
@@ -2045,6 +2082,8 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod
val e = gen-constraints(exp(s))
add(v,WGeq(width!(type(l)),width!(type(e))))
Connect(info(s),l,e)
+ (s:PrintfStmt) :
+ PrintfStmt(info(s),string(s),map(gen-constraints,args(s)))
(s:Conditionally) :
val p = gen-constraints(pred(s))
add(v,WGeq(width!(type(p)),LongWidth(1)))
@@ -2089,7 +2128,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(s))
(s:DefNode) : h[name(s)] = remove-unknowns(type(value(s)))
(s) : false
do(build-environment,s)
@@ -2241,7 +2280,7 @@ defn inline-instances (c:Circuit) :
(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))
+ (s:DefMemory) : DefMemory(info(s),rename(name(s),n),type(s),seq?(s),clock(s),size(s))
(s:DefNode) : DefNode(info(s),rename(name(s),n),value(s))
(s) : s
for m in modules(c) do :
@@ -2319,14 +2358,26 @@ defn split-exp (c:Circuit) :
;Predicate
val pred* = map(split-exp-e{_,full-name(pred(s)),info(s)},pred(s))
- ;Connect
- val c = conseq(s) as Connect
- val exp* = map(split-exp-e{_,full-name(loc(c)),info(c)},exp(c))
- val conseq* = Connect(info(c),loc(c),exp*)
- add(v,Conditionally(info(s),pred*,conseq*,alt(s)))
+ ;Connect TODO Broken for stop/printf
+ match(conseq(s)) :
+ (c:Connect) :
+ val exp* = map(split-exp-e{_,full-name(loc(c)),info(c)},exp(c))
+ val conseq* = Connect(info(c),loc(c),exp*)
+ add(v,Conditionally(info(s),pred*,conseq*,alt(s)))
+ (c:PrintfStmt) :
+ val args* = for x in args(c) map :
+ map(split-exp-e{_,false,info(c)},x)
+ val conseq* = PrintfStmt(info(c),string(c),args*)
+ add(v,Conditionally(info(s),pred*,conseq*,alt(s)))
+ (c:StopStmt) :
+ add(v,Conditionally(info(s),pred*,c,alt(s)))
(s:Connect) :
val exp* = map(split-exp-e{_,full-name(loc(s)),info(s)},exp(s))
add(v,Connect(info(s),loc(s),exp*))
+ (s:PrintfStmt) :
+ val args* = for x in args(s) map :
+ map(split-exp-e{_,false,info(s)},x)
+ add(v,PrintfStmt(info(s),string(s),args*))
(s:DefNode) :
val exp* = map(split-exp-e{_,name(s),info(s)},value(s))
add(v,DefNode(info(s),name(s),exp*))
@@ -2395,7 +2446,7 @@ public defn special-rename (original-sym:Symbol,new-sym:Symbol,c:Circuit) :
(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))
+ (s:DefMemory) : DefMemory(info(s),rename(name(s)),type(s),seq?(s),clock(s),size(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)
@@ -2481,6 +2532,11 @@ defn pad-widths-s (s:Stmt) -> Stmt :
val loc* = pad-widths-e(i,loc(s))
val exp* = pad-widths-e(i,exp(s))
Connect(info(s),loc*,exp*)
+ (s:PrintfStmt) :
+ val args* = for x in args(s) map :
+ val i = int-width!(type(x))
+ pad-widths-e(i,x)
+ PrintfStmt(info(s),string(s),args*)
(s:DefNode) :
val i = int-width!(type(value(s)))
val exp* = pad-widths-e(i,value(s))
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
index 1a495835..5cf42323 100644
--- a/src/main/stanza/verilog.stanza
+++ b/src/main/stanza/verilog.stanza
@@ -54,6 +54,20 @@ defn get-name (e:Expression) -> Symbol :
(e:Subfield) : error("Shouldn't be here")
(e) : error("Shouldn't be here")
+defn escape (s:String) -> String :
+ val s* = Vector<String>()
+ add(s*,"\"");"
+ var percent = false
+ for c in s do :
+ if c == '\n' :
+ add(s*,"\\n")
+ else :
+ if c == 'x' and percent :
+ add(s*,"h")
+ else : add(s*,to-string(c))
+ percent = c == '%'
+ add(s*,"\"");"
+ string-join(s*)
;============ Verilog Backend =============
defn emit-as-type (e:Expression,t:Type) -> String :
@@ -168,15 +182,32 @@ defn emit-module (m:InModule) :
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
+ val simuls = Vector<Streamable>()
defn build-table (s:Stmt) -> False :
match(s) :
(s:DefWire|DefPoison|DefRegister|DefAccessor|DefMemory|DefNode|DefInstance) :
add(vdecs,name(s) => s)
decs[name(s)] = s
(s:Conditionally) :
- val n = get-name(loc(conseq(s) as Connect))
- ens[n] = pred(s)
- cons[n] = exp(conseq(s) as Connect)
+ match(conseq(s)) :
+ (c:Connect) :
+ val n = get-name(loc(c))
+ ens[n] = pred(s)
+ cons[n] = exp(conseq(s) as Connect)
+ (c:PrintfStmt) :
+ add(simuls,["if(" emit(pred(s)) ") begin"])
+ add(simuls,[" $fdisplay(32/'h80000002," string-join(List(escape(string(c)),map(emit,args(c))), ", ") ");"])
+ add(simuls,["end"])
+ (c:StopStmt) :
+ add(simuls,["if(" emit(pred(s)) ") begin"])
+ add(simuls,[" $fdisplay(32/'h80000002," ret(c) ");"])
+ add(simuls,[" $finish;"])
+ add(simuls,["end"])
+ (s:PrintfStmt) :
+ add(simuls,["$fdisplay(32/'h80000002," string-join(List(escape(string(s)),map(emit,args(s))), ", ") ");"])
+ (c:StopStmt) :
+ add(simuls,["$fdisplay(32/'h80000002," ret(c) ");"])
+ add(simuls,["$finish;"])
(s:Connect) :
val n = get-name(loc(s))
cons[n] = exp(s)
@@ -221,10 +252,9 @@ defn emit-module (m:InModule) :
val w = width!(type(s))
add(inits,[sym " = " rand-string(w)])
(s:DefMemory) :
- val vtype = type(s) as VectorType
- add(regs,["reg " get-width(type(vtype)) " " sym " [0:" size(vtype) - 1 "];"])
- add(inits,["for (initvar = 0; initvar < " size(vtype) "; initvar = initvar+1)"])
- add(inits,[" " sym "[initvar] = " rand-string(width!(type(vtype))) ])
+ add(regs,["reg " get-width(type(s)) " " sym " [0:" size(s) - 1 "];"])
+ add(inits,["for (initvar = 0; initvar < " size(s) "; initvar = initvar+1)"])
+ add(inits,[" " sym "[initvar] = " rand-string(width!(type(s))) ])
(s:DefNode) :
add(wires,["wire " get-width(type(value(s))) " " sym ";"])
add(assigns,["assign " sym " = " emit(value(s)) ";"])
@@ -252,11 +282,11 @@ defn emit-module (m:InModule) :
updates[get-name(clock(mem-declaration))] = my-clk-update
; emit read accessor
- add(wires,["wire " get-width(type(type(source(s)) as VectorType)) " " sym ";"])
+ add(wires,["wire " get-width(type(source(s))) " " sym ";"])
add(assigns,["assign " sym " = " emit(source(s)) "[" emit(index*) "];"])
else :
; emit read accessor
- add(wires,["wire " get-width(type(type(source(s)) as VectorType)) " " sym ";"])
+ add(wires,["wire " get-width(type(source(s))) " " 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>())
@@ -322,6 +352,15 @@ defn emit-module (m:InModule) :
print(" ")
println-all(u)
println(" end")
+
+ if length(simuls) != 0 :
+ println("`ifndef SYNTHESIS")
+ println(" always @(*) begin")
+ for x in simuls do :
+ print(" ")
+ println-all(x)
+ println(" end")
+ println("`endif")
println("endmodule")