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
119
120
121
122
123
124
|
// See LICENSE for license details.
package firrtl.passes
import firrtl._
import firrtl.ir._
import firrtl.Utils._
import firrtl.traversals.Foreachers._
object CheckChirrtl extends Pass {
type NameSet = collection.mutable.HashSet[String]
class NotUniqueException(info: Info, mname: String, name: String) extends PassException(
s"$info: [module $mname] Reference $name does not have a unique name.")
class InvalidLOCException(info: Info, mname: String) extends PassException(
s"$info: [module $mname] Invalid connect to an expression that is not a reference or a WritePort.")
class UndeclaredReferenceException(info: Info, mname: String, name: String) extends PassException(
s"$info: [module $mname] Reference $name is not declared.")
class MemWithFlipException(info: Info, mname: String, name: String) extends PassException(
s"$info: [module $mname] Memory $name cannot be a bundle type with flips.")
class InvalidAccessException(info: Info, mname: String) extends PassException(
s"$info: [module $mname] Invalid access to non-reference.")
class ModuleNotDefinedException(info: Info, mname: String, name: String) extends PassException(
s"$info: Module $name is not defined.")
class NegWidthException(info: Info, mname: String) extends PassException(
s"$info: [module $mname] Width cannot be negative or zero.")
class NegVecSizeException(info: Info, mname: String) extends PassException(
s"$info: [module $mname] Vector type size cannot be negative.")
class NegMemSizeException(info: Info, mname: String) extends PassException(
s"$info: [module $mname] Memory size cannot be negative or zero.")
class NoTopModuleException(info: Info, name: String) extends PassException(
s"$info: A single module must be named $name.")
def run (c: Circuit): Circuit = {
val errors = new Errors()
val moduleNames = (c.modules map (_.name)).toSet
def checkValidLoc(info: Info, mname: String, e: Expression) = e match {
case _: UIntLiteral | _: SIntLiteral | _: DoPrim =>
errors append new InvalidLOCException(info, mname)
case _ => // Do Nothing
}
def checkChirrtlW(info: Info, mname: String)(w: Width): Unit = w match {
case w: IntWidth if (w.width < BigInt(0)) => errors.append(new NegWidthException(info, mname))
case _ =>
}
def checkChirrtlT(info: Info, mname: String)(t: Type): Unit = {
t.foreach(checkChirrtlT(info, mname))
t match {
case t: VectorType if t.size < 0 =>
errors append new NegVecSizeException(info, mname)
t.foreach(checkChirrtlW(info, mname))
//case FixedType(width, point) => FixedType(checkChirrtlW(width), point)
case _ => t.foreach(checkChirrtlW(info, mname))
}
}
def validSubexp(info: Info, mname: String)(e: Expression): Unit = e match {
case _: Reference | _: SubField | _: SubIndex | _: SubAccess |
_: Mux | _: ValidIf => // No error
case _ => errors append new InvalidAccessException(info, mname)
}
def checkChirrtlE(info: Info, mname: String, names: NameSet)(e: Expression): Unit = {
e match {
case _: DoPrim | _:Mux | _:ValidIf | _: UIntLiteral =>
case ex: Reference if !names(ex.name) =>
errors append new UndeclaredReferenceException(info, mname, ex.name)
case ex: SubAccess => validSubexp(info, mname)(ex.expr)
case ex => ex.foreach(validSubexp(info, mname))
}
e.foreach(checkChirrtlW(info, mname))
e.foreach(checkChirrtlT(info, mname))
e.foreach(checkChirrtlE(info, mname, names))
}
def checkName(info: Info, mname: String, names: NameSet)(name: String): Unit = {
if (names(name))
errors append new NotUniqueException(info, mname, name)
names += name
}
def checkChirrtlS(minfo: Info, mname: String, names: NameSet)(s: Statement): Unit = {
val info = get_info(s) match {case NoInfo => minfo case x => x}
s.foreach(checkName(info, mname, names))
s match {
case sx: DefMemory =>
if (hasFlip(sx.dataType)) errors append new MemWithFlipException(info, mname, sx.name)
if (sx.depth <= 0) errors append new NegMemSizeException(info, mname)
case sx: DefInstance if !moduleNames(sx.module) =>
errors append new ModuleNotDefinedException(info, mname, sx.module)
case sx: Connect => checkValidLoc(info, mname, sx.loc)
case sx: PartialConnect => checkValidLoc(info, mname, sx.loc)
case _ => // Do Nothing
}
s.foreach(checkChirrtlT(info, mname))
s.foreach(checkChirrtlE(info, mname, names))
s.foreach(checkChirrtlS(info, mname, names))
}
def checkChirrtlP(mname: String, names: NameSet)(p: Port): Unit = {
if (names(p.name))
errors append new NotUniqueException(NoInfo, mname, p.name)
names += p.name
p.tpe.foreach(checkChirrtlT(p.info, mname))
p.tpe.foreach(checkChirrtlW(p.info, mname))
}
def checkChirrtlM(m: DefModule) {
val names = new NameSet
m.foreach(checkChirrtlP(m.name, names))
m.foreach(checkChirrtlS(m.info, m.name, names))
}
c.modules.foreach(checkChirrtlM)
c.modules count (_.name == c.main) match {
case 1 =>
case _ => errors append new NoTopModuleException(c.info, c.main)
}
errors.trigger()
c
}
}
|