Make DecodeLogic interface more flexible
This commit is contained in:
		| @@ -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); | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user