diff options
Diffstat (limited to 'src/main/scala/firrtl/constraint/IsAdd.scala')
| -rw-r--r-- | src/main/scala/firrtl/constraint/IsAdd.scala | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/constraint/IsAdd.scala b/src/main/scala/firrtl/constraint/IsAdd.scala new file mode 100644 index 00000000..e177a8b9 --- /dev/null +++ b/src/main/scala/firrtl/constraint/IsAdd.scala @@ -0,0 +1,52 @@ +// See LICENSE for license details. + + +package firrtl.constraint + +// Is case class because writing tests is easier due to equality is not object equality +case class IsAdd private (known: Option[IsKnown], + maxs: Vector[IsMax], + mins: Vector[IsMin], + others: Vector[Constraint]) extends Constraint with MultiAry { + + def op(b1: IsKnown, b2: IsKnown): IsKnown = b1 + b2 + + lazy val children: Vector[Constraint] = { + if(known.nonEmpty) known.get +: (maxs ++ mins ++ others) else maxs ++ mins ++ others + } + + def addChild(x: Constraint): IsAdd = x match { + case k: IsKnown => new IsAdd(merge(Some(k), known), maxs, mins, others) + case add: IsAdd => new IsAdd(merge(known, add.known), maxs ++ add.maxs, mins ++ add.mins, others ++ add.others) + case max: IsMax => new IsAdd(known, maxs :+ max, mins, others) + case min: IsMin => new IsAdd(known, maxs, mins :+ min, others) + case other => new IsAdd(known, maxs, mins, others :+ other) + } + + override def serialize: String = "(" + children.map(_.serialize).mkString(" + ") + ")" + + override def map(f: Constraint=>Constraint): Constraint = IsAdd(children.map(f)) + + def reduce(): Constraint = { + if(children.size == 1) children.head else { + (known, maxs, mins, others) match { + case (Some(k), _, _, _) if k.value == 0 => new IsAdd(None, maxs, mins, others).reduce() + case (Some(k), Vector(max), Vector(), Vector()) => max.map { o => IsAdd(k, o) }.reduce() + case (Some(k), Vector(), Vector(min), Vector()) => min.map { o => IsAdd(k, o) }.reduce() + case _ => this + } + } + } +} + +object IsAdd { + def apply(left: Constraint, right: Constraint): Constraint = (left, right) match { + case (l: IsKnown, r: IsKnown) => l + r + case _ => apply(Seq(left, right)) + } + def apply(children: Seq[Constraint]): Constraint = { + children.foldLeft(new IsAdd(None, Vector(), Vector(), Vector())) { (add, c) => + add.addChild(c) + }.reduce() + } +}
\ No newline at end of file |
