1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
defpackage firrtl/custom-passes :
import core
import verse
import firrtl/ir-utils
import firrtl/ir2
public defstruct WhenCoverage <: Pass :
port-name : String
reg-name : String
public defmethod pass (b:WhenCoverage) -> (Circuit -> Circuit) : when-coverage{port-name(b),reg-name(b),_}
public defmethod name (b:WhenCoverage) -> String : "When Coverage"
public defmethod short-name (b:WhenCoverage) -> String : "when-coverage"
;============ Utilz =============
defn concat-all (ls:List<Expression>) -> Expression :
if length(ls) == 0 : error("Shouldn't be here")
if length(ls) == 1 : head(ls)
else : DoPrim( CONCAT-OP,
list(head(ls),concat-all(tail(ls))),
list(),
UIntType(UnknownWidth()))
;============ When Coverage Pass =============
;port width = 1 bit per scope + portwidths of all instances
defn needs-instrumentation (m:Module,ms:List<Module>,instrument?:HashTable<Symbol,True|False>) -> False :
defn needs-instrumentation-s (s:Stmt) -> False :
match(s) :
(s:Conditionally) :instrument?[name(m)] = true
(s:DefInstance) :
val module-of-inst = for x in ms find : name(x) == name(module(s) as Ref)
if module-of-inst != false :
needs-instrumentation(module-of-inst as Module,ms,instrument?)
instrument?[name(m)] = instrument?[name(module-of-inst as Module)]
(s) : false
do(needs-instrumentation-s,s)
match(m) :
(m:InModule) : do(needs-instrumentation-s,body(m))
(m:ExModule) : false
defn when-coverage (port-name:Symbol, reg-name:Symbol, instrument?:HashTable<Symbol,True|False>, m:InModule) -> InModule :
val when-bits = Vector<Ref>()
val inst-bits = Vector<Ref>()
val sym = HashTable<Symbol,Int>(symbol-hash)
val w1 = IntWidth(1)
val t1 = UIntType(w1)
val u1 = UIntValue(to-long $ 1,w1)
defn when-coverage (s:Stmt) -> Stmt :
match(s) :
(s:Conditionally) :
val ref = Ref(firrtl-gensym(reg-name,sym),t1)
add(when-bits,ref)
val conseq* = Begin(list(Connect(FileInfo()ref,u1),conseq(s)))
map(when-coverage,Conditionally(info(s),pred(s),conseq*,alt(s)))
(s:DefInstance) :
if instrument?[name(module(s) as Ref)] :
val ref = Ref(firrtl-gensym(port-name,sym),UIntType(UnknownWidth()))
add(inst-bits,ref)
val sfld = Subfield(Ref(name(s),UnknownType()),port-name,UnknownType())
Begin(list(s,Connect(FileInfo(),ref,sfld)))
else : s
(s) : map(when-coverage,s)
val body* = when-coverage(body(m))
val logic = Vector<Stmt>()
val port-ref = Ref(port-name,UIntType(UnknownWidth()))
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,_} $ 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))
add{logic,_} $ Connect(FileInfo(),x,DoPrim(BIT-SELECT-OP,list(reg-ref),list(i),UIntType(w1)))
add{logic,_} $ Connect(FileInfo(),reg-ref,concat-all(w-ls))
val i-ls = to-list $ inst-bits
if length(i-ls) != 0 :
for (x in i-ls, i in 0 to false) do :
add{logic,_} $ DefWire(FileInfo(),name(x),type(x))
add{logic,_} $ Connect(FileInfo(),x,UIntValue(to-long $ 0,UnknownWidth()))
if instrument?[name(m)] : add{logic,_} $ Connect(FileInfo(),port-ref,concat-all(append(w-ls,i-ls)))
if length(logic) != 0 :
val ports* = List(Port(FileInfo(),port-name,OUTPUT,UIntType(UnknownWidth())),ports(m))
val body** = Begin(list(Begin(to-list $ logic),body*))
InModule(info(m),name(m),ports*,body**)
else : m
public defn when-coverage (port-name:String, reg-name:String, c:Circuit) :
val instrument? = HashTable<Symbol,True|False>(symbol-hash)
for m in modules(c) do :
instrument?[name(m)] = false
val top = for m in modules(c) find : name(m) == main(c)
if top != false : needs-instrumentation(top as Module,modules(c),instrument?)
val modules* = for m in modules(c) map :
match(m) :
(m:InModule) :
when-coverage(to-symbol $ port-name,to-symbol $ reg-name,instrument?,m)
(m:ExModule) : m
Circuit(info(c),modules*,main(c))
|