blob: 94cef65bfbcbd501e5ada1044f025688cf6c8fd1 (
plain)
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
|
// SPDX-License-Identifier: Apache-2.0
package firrtl
package transforms
import firrtl.ir._
import firrtl.Mappers._
import firrtl.options.Dependency
import firrtl.Utils.BoolType
object LegalizeAndReductionsTransform {
private def allOnesOfType(tpe: Type): Literal = tpe match {
case UIntType(width @ IntWidth(x)) => UIntLiteral((BigInt(1) << x.toInt) - 1, width)
case SIntType(width) => SIntLiteral(-1, width)
}
def onExpr(expr: Expression): Expression = expr.map(onExpr) match {
case DoPrim(PrimOps.Andr, Seq(arg), _, _) if bitWidth(arg.tpe) > 64 =>
DoPrim(PrimOps.Eq, Seq(arg, allOnesOfType(arg.tpe)), Seq(), BoolType)
case other => other
}
def onStmt(stmt: Statement): Statement = stmt.map(onStmt).map(onExpr)
def onMod(mod: DefModule): DefModule = mod.map(onStmt)
}
/** Turns andr for expression > 64-bit into equality check with all ones
*
* Workaround a bug in Verilator v4.026 - v4.032 (inclusive).
* For context, see https://github.com/verilator/verilator/issues/2300
*/
class LegalizeAndReductionsTransform extends Transform with DependencyAPIMigration {
override def prerequisites =
firrtl.stage.Forms.MinimalHighForm ++
Seq(Dependency(passes.CheckTypes), Dependency(passes.CheckWidths))
override def optionalPrerequisites = Nil
override def optionalPrerequisiteOf = Nil
override def invalidates(a: Transform) = false
def execute(state: CircuitState): CircuitState = {
val modulesx = state.circuit.modules.map(LegalizeAndReductionsTransform.onMod(_))
state.copy(circuit = state.circuit.copy(modules = modulesx))
}
}
|