1
0

Make DecodeLogic interface more flexible

This commit is contained in:
Andrew Waterman 2013-12-05 04:16:48 -08:00
parent 924261e2b2
commit 5814a90472
2 changed files with 40 additions and 34 deletions

View File

@ -40,9 +40,9 @@ trait ScalarOpConstants {
val A2_ZERO = UInt(2, 3) val A2_ZERO = UInt(2, 3)
val A2_FOUR = UInt(3, 3) val A2_FOUR = UInt(3, 3)
val X = Bits("b?", 1) val X = Bool.DC
val N = Bits(0, 1) val N = Bool(false)
val Y = Bits(1, 1) val Y = Bool(true)
val WB_X = UInt("b??", 2) val WB_X = UInt("b??", 2)
val WB_ALU = UInt(0, 3); val WB_ALU = UInt(0, 3);

View File

@ -14,28 +14,24 @@ object DecodeLogic
new Term(lit.value) 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 => terms.map { t =>
if (!cache.contains(t)) 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()})
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
}.foldLeft(Bool(false))(_||_) }.foldLeft(Bool(false))(_||_)
} }
def apply(addr: Bits, default: Iterable[Bits], mapping: Iterable[(Bits, Iterable[Bits])]) = { def apply[T <: Bits](addr: UInt, default: T, mapping: Iterable[(UInt, T)]): T = {
var map = mapping val cache = caches.getOrElseUpdate(Module.current, collection.mutable.Map[Term,Bool]())
var cache = scala.collection.mutable.Map[Term,Bits]() val dterm = term(default)
default map { d => val (keys, values) = mapping.unzip
val dterm = term(d)
val (keys, values) = map.unzip
val addrWidth = keys.map(_.getWidth).max val addrWidth = keys.map(_.getWidth).max
val terms = keys.toList.map(k => term(k)) val terms = keys.toList.map(k => term(k))
val termvalues = terms zip values.toList.map(v => term(v.head)) val termvalues = terms zip values.toList.map(term(_))
for (t <- keys.zip(terms).tails; if !t.isEmpty) for (t <- keys.zip(terms).tails; if !t.isEmpty)
for (u <- t.tail) for (u <- t.tail)
assert(!t.head._2.intersects(u._2), "DecodeLogic: keys " + t.head + " and " + u + " overlap") 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 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 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 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 dc = termvalues.filter { case (k,t) => ((t.mask >> i) & 1) == 1 }.map(_._1)
@ -49,10 +45,20 @@ object DecodeLogic
if (defbit == 0) bit else ~bit if (defbit == 0) bit else ~bit
} }
}).reverse.reduceRight(Cat(_,_)) }).reverse.reduceRight(Cat(_,_))
map = map map { case (x,y) => (x, y.tail) } default.fromBits(result)
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) class Term(val value: BigInt, val mask: BigInt = 0)