diff --git a/rocket/src/main/scala/consts.scala b/rocket/src/main/scala/consts.scala index e0f29f1f..7d13ca21 100644 --- a/rocket/src/main/scala/consts.scala +++ b/rocket/src/main/scala/consts.scala @@ -40,9 +40,9 @@ trait ScalarOpConstants { val A2_ZERO = UInt(2, 3) val A2_FOUR = UInt(3, 3) - val X = Bits("b?", 1) - val N = Bits(0, 1) - val Y = Bits(1, 1) + val X = Bool.DC + val N = Bool(false) + val Y = Bool(true) val WB_X = UInt("b??", 2) val WB_ALU = UInt(0, 3); diff --git a/rocket/src/main/scala/decode.scala b/rocket/src/main/scala/decode.scala index 6c8432d8..5ce768b0 100644 --- a/rocket/src/main/scala/decode.scala +++ b/rocket/src/main/scala/decode.scala @@ -14,45 +14,51 @@ object DecodeLogic new Term(lit.value) } } - def logic(addr: Bits, addrWidth: Int, cache: scala.collection.mutable.Map[Term,Bits], terms: Seq[Term]) = { + def logic(addr: UInt, addrWidth: Int, cache: scala.collection.mutable.Map[Term,Bool], terms: Seq[Term]) = { terms.map { t => - if (!cache.contains(t)) - cache += t -> ((if (t.mask == 0) addr else addr & Lit(BigInt(2).pow(addrWidth)-(t.mask+1), addrWidth){Bits()}) === Lit(t.value, addrWidth){Bits()}) - cache(t).toBool + cache.getOrElseUpdate(t, (if (t.mask == 0) addr else addr & Lit(BigInt(2).pow(addrWidth)-(t.mask+1), addrWidth){Bits()}) === Lit(t.value, addrWidth){Bits()}) }.foldLeft(Bool(false))(_||_) } - def apply(addr: Bits, default: Iterable[Bits], mapping: Iterable[(Bits, Iterable[Bits])]) = { - var map = mapping - var cache = scala.collection.mutable.Map[Term,Bits]() - default map { d => - val dterm = term(d) - val (keys, values) = map.unzip - val addrWidth = keys.map(_.getWidth).max - val terms = keys.toList.map(k => term(k)) - val termvalues = terms zip values.toList.map(v => term(v.head)) + def apply[T <: Bits](addr: UInt, default: T, mapping: Iterable[(UInt, T)]): T = { + val cache = caches.getOrElseUpdate(Module.current, collection.mutable.Map[Term,Bool]()) + val dterm = term(default) + val (keys, values) = mapping.unzip + val addrWidth = keys.map(_.getWidth).max + val terms = keys.toList.map(k => term(k)) + val termvalues = terms zip values.toList.map(term(_)) - for (t <- keys.zip(terms).tails; if !t.isEmpty) - for (u <- t.tail) - assert(!t.head._2.intersects(u._2), "DecodeLogic: keys " + t.head + " and " + u + " overlap") + for (t <- keys.zip(terms).tails; if !t.isEmpty) + for (u <- t.tail) + assert(!t.head._2.intersects(u._2), "DecodeLogic: keys " + t.head + " and " + u + " overlap") - val result = (0 until math.max(d.litOf.width, values.map(_.head.litOf.width).max)).map({ case (i: Int) => - val mint = termvalues.filter { case (k,t) => ((t.mask >> i) & 1) == 0 && ((t.value >> i) & 1) == 1 }.map(_._1) - val maxt = termvalues.filter { case (k,t) => ((t.mask >> i) & 1) == 0 && ((t.value >> i) & 1) == 0 }.map(_._1) - val dc = termvalues.filter { case (k,t) => ((t.mask >> i) & 1) == 1 }.map(_._1) + val result = (0 until default.litOf.width.max(values.map(_.litOf.width).max)).map({ case (i: Int) => + val mint = termvalues.filter { case (k,t) => ((t.mask >> i) & 1) == 0 && ((t.value >> i) & 1) == 1 }.map(_._1) + val maxt = termvalues.filter { case (k,t) => ((t.mask >> i) & 1) == 0 && ((t.value >> i) & 1) == 0 }.map(_._1) + val dc = termvalues.filter { case (k,t) => ((t.mask >> i) & 1) == 1 }.map(_._1) - if (((dterm.mask >> i) & 1) != 0) { - logic(addr, addrWidth, cache, SimplifyDC(mint, maxt, addrWidth)).toBits - } else { - val defbit = (dterm.value.toInt >> i) & 1 - val t = if (defbit == 0) mint else maxt - val bit = logic(addr, addrWidth, cache, Simplify(t, dc, addrWidth)).toBits - if (defbit == 0) bit else ~bit - } - }).reverse.reduceRight(Cat(_,_)) - map = map map { case (x,y) => (x, y.tail) } - result + if (((dterm.mask >> i) & 1) != 0) { + logic(addr, addrWidth, cache, SimplifyDC(mint, maxt, addrWidth)).toBits + } else { + val defbit = (dterm.value.toInt >> i) & 1 + val t = if (defbit == 0) mint else maxt + val bit = logic(addr, addrWidth, cache, Simplify(t, dc, addrWidth)).toBits + if (defbit == 0) bit else ~bit + } + }).reverse.reduceRight(Cat(_,_)) + default.fromBits(result) + } + def apply[T <: Bits](addr: UInt, default: Iterable[T], mappingIn: Iterable[(UInt, Iterable[T])]): Iterable[T] = { + var mapping = mappingIn + default map { thisDefault => + val thisMapping = for ((key, values) <- mapping) yield key -> values.head + val res = apply(addr, thisDefault, thisMapping) + mapping = for ((key, values) <- mapping) yield key -> values.tail + res } } + def apply(addr: UInt, trues: Iterable[UInt], falses: Iterable[UInt]): Bool = + apply(addr, Bool.DC, trues.map(_ -> Bool(true)) ++ falses.map(_ -> Bool(false))) + private val caches = collection.mutable.Map[Module,collection.mutable.Map[Term,Bool]]() } class Term(val value: BigInt, val mask: BigInt = 0)