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
107
108
109
110
111
112
113
114
115
116
117
118
|
defpackage firrtl/chirrtl :
import core
import verse
import firrtl/ir2
import firrtl/ir-utils
public defstruct ToIR <: Pass
public defmethod pass (b:ToIR) -> (Circuit -> Circuit) : to-ir
public defmethod name (b:ToIR) -> String : "To IR"
public defmethod short-name (b:ToIR) -> String : "to-ir"
defstruct MPort :
name : Symbol
clk : Expression
defstruct MPorts :
readers : Vector<MPort>
writers : Vector<MPort>
readwriters : Vector<MPort>
defstruct DataRef :
exp : Expression
male : Symbol
female : Symbol
public definterface Gender
public val MALE = new Gender
public val FEMALE = new Gender
defn to-ir (c:Circuit) :
defn to-ir-m (m:InModule) -> InModule :
val hash = HashTable<Symbol,MPorts>(symbol-hash)
val sh = get-sym-hash(m,keys(v-keywords))
val repl = HashTable<Symbol,DataRef>(symbol-hash)
val ut = UnknownType()
defn EMPs () -> MPorts :
MPorts(Vector<MPort>(),Vector<MPort>(),Vector<MPort>())
defn collect-mports (s:Stmt) -> Stmt :
match(s) :
(s:CDefMPort) :
val mports = get?(hash,mem(s),EMPs())
switch { _ == direction(s) } :
MRead : add(readers(mports),MPort(name(s),exps(s)[1]))
MWrite : add(writers(mports),MPort(name(s),exps(s)[1]))
MReadWrite : add(readwriters(mports),MPort(name(s),exps(s)[1]))
hash[mem(s)] = mports
s
(s) : map(collect-mports,s)
defn collect-refs (s:Stmt) -> Stmt :
match(s) :
(s:CDefMemory) :
val stmts = Vector<Stmt>()
val n = firrtl-gensym(`GEN,sh)
val t = UIntType(IntWidth(ceil-log2(size(s))))
add(stmts,DefPoison(info(s),n,t))
defn set-poison (vec:List<MPort>,addr:Symbol) -> False :
for r in vec do :
add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),addr,t),Ref(n,t)))
add(stmts,Connect(info(s),SubField(SubField(Ref(name(s),ut),name(r),ut),`clk,t),clk(r)))
val rds = to-list $ readers $ get?(hash,name(s),EMPs())
set-poison(rds,`addr)
val wrs = to-list $ writers $ get?(hash,name(s),EMPs())
set-poison(wrs,`addr)
val rws = to-list $ readwriters $ get?(hash,name(s),EMPs())
set-poison(rws,`waddr)
set-poison(rws,`raddr)
val read-l =
if seq?(s) : 1
else : 0
val mem = DefMemory(info(s),name(s),type(s),size(s),1,read-l,map(name,rds),map(name,wrs),map(name,rws))
Begin $ List(mem,to-list(stmts))
(s:CDefMPort) :
val addrs = Vector<Symbol>()
val ens = Vector<Symbol>()
val masks = Vector<Symbol>()
switch { _ == direction(s) } :
MReadWrite :
repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`wdata,`rdata)
add(addrs,`addr)
add(ens,`wen)
add(ens,`ren)
else : ; TODO add MWrite for mask
repl[name(s)] = DataRef(SubField(Ref(mem(s),ut),name(s),ut),`data,`data)
add(addrs,`addr)
add(ens,`en)
val stmts = Vector<Stmt>()
for x in addrs do :
add(stmts,Connect(info(s),SubField(SubField(Ref(mem(s),ut),name(s),ut),x,ut),exps(s)[0]))
for x in ens do :
add(stmts,Connect(info(s),SubField(SubField(Ref(mem(s),ut),name(s),ut),x,ut),one))
Begin $ to-list $ stmts
(s) : map(collect-refs,s)
defn to-ir-e (e:Expression,g:Gender) -> Expression :
match(map(to-ir-e{_,g},e)) :
(e:Ref) :
if key?(repl,name(e)) :
val vt = repl[name(e)]
switch {g == _ }:
MALE : SubField(exp(vt),male(vt),ut)
FEMALE : SubField(exp(vt),female(vt),ut)
else : e
(e) : e
defn to-ir-s (s:Stmt) -> Stmt :
match(s) :
(s:Connect|BulkConnect) :
val loc* = to-ir-e(loc(s),FEMALE)
val roc* = to-ir-e(exp(s),MALE)
Connect(info(s),loc*,roc*)
(s) : map(to-ir-e{_,MALE}, map(to-ir-s,s))
collect-mports(body(m))
val s* = collect-refs(body(m))
InModule(info(m),name(m), ports(m), to-ir-s(s*))
Circuit(info(c),modules*, main(c)) where :
val modules* =
for m in modules(c) map :
match(m) :
(m:InModule) : to-ir-m(m)
(m:ExModule) : m
|