make DecodeLogic deterministic (hopefully)
This commit is contained in:
		@@ -13,7 +13,7 @@ object DecodeLogic
 | 
			
		||||
      new Term(b.value)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  def logic(addr: Bits, cache: scala.collection.mutable.Map[Term,Bits], terms: Set[Term]) = {
 | 
			
		||||
  def logic(addr: Bits, cache: scala.collection.mutable.Map[Term,Bits], terms: Seq[Term]) = {
 | 
			
		||||
    terms.map { t =>
 | 
			
		||||
      if (!cache.contains(t))
 | 
			
		||||
        cache += t -> ((if (t.mask == 0) addr else addr & Lit(BigInt(2).pow(addr.width)-(t.mask+1), addr.width){Bits()}) === Lit(t.value, addr.width){Bits()})
 | 
			
		||||
@@ -31,13 +31,13 @@ object DecodeLogic
 | 
			
		||||
 | 
			
		||||
      val result = (0 until math.max(dlit.width, values.map(_.head.litOf.width).max)).map({ case (i: Int) =>
 | 
			
		||||
        if (((dterm.mask >> i) & 1) != 0) {
 | 
			
		||||
          var mint = keysterms.filter { case (k,t) => ((t.mask >> i) & 1) == 0 && ((t.value >> i) & 1) == 1 }.map(_._1).toSet
 | 
			
		||||
          var maxt = keysterms.filter { case (k,t) => ((t.mask >> i) & 1) == 0 && ((t.value >> i) & 1) == 0 }.map(_._1).toSet
 | 
			
		||||
          var mint = keysterms.filter { case (k,t) => ((t.mask >> i) & 1) == 0 && ((t.value >> i) & 1) == 1 }.map(_._1)
 | 
			
		||||
          var maxt = keysterms.filter { case (k,t) => ((t.mask >> i) & 1) == 0 && ((t.value >> i) & 1) == 0 }.map(_._1)
 | 
			
		||||
          logic(addr, cache, SimplifyDC(mint, maxt, addr.width)).toBits
 | 
			
		||||
        } else {
 | 
			
		||||
          val want = 1 - ((dterm.value.toInt >> i) & 1)
 | 
			
		||||
          val mint = keysterms.filter { case (k,t) => ((t.mask >> i) & 1) == 0 && ((t.value >> i) & 1) == want }.map(_._1).toSet
 | 
			
		||||
          val dc = keysterms.filter { case (k,t) => ((t.mask >> i) & 1) == 1 }.map(_._1).toSet
 | 
			
		||||
          val mint = keysterms.filter { case (k,t) => ((t.mask >> i) & 1) == 0 && ((t.value >> i) & 1) == want }.map(_._1)
 | 
			
		||||
          val dc = keysterms.filter { case (k,t) => ((t.mask >> i) & 1) == 1 }.map(_._1)
 | 
			
		||||
          val bit = logic(addr, cache, Simplify(mint, dc, addr.width)).toBits
 | 
			
		||||
          if (want == 1) bit else ~bit
 | 
			
		||||
        }
 | 
			
		||||
@@ -59,6 +59,7 @@ class Term(val value: BigInt, val mask: BigInt = 0)
 | 
			
		||||
    case _ => false
 | 
			
		||||
  }
 | 
			
		||||
  override def hashCode = value.toInt
 | 
			
		||||
  def < (that: Term) = value < that.value || value == that.value && mask < that.mask
 | 
			
		||||
  def similar(x: Term) = {
 | 
			
		||||
    val diff = value - x.value
 | 
			
		||||
    mask == x.mask && value > x.value && (diff & diff-1) == 0
 | 
			
		||||
@@ -75,32 +76,33 @@ class Term(val value: BigInt, val mask: BigInt = 0)
 | 
			
		||||
 | 
			
		||||
object Simplify
 | 
			
		||||
{
 | 
			
		||||
  def getPrimeImplicants(implicants: Set[Term], bits: Int) = {
 | 
			
		||||
    var prime = Set[Term]()
 | 
			
		||||
  def getPrimeImplicants(implicants: Seq[Term], bits: Int) = {
 | 
			
		||||
    var prime = List[Term]()
 | 
			
		||||
    implicants.foreach(_.prime = true)
 | 
			
		||||
    val cols = (0 to bits).map(b => implicants.filter(b == _.mask.bitCount))
 | 
			
		||||
    val table = cols.map(c => (0 to bits).map(b => collection.mutable.Set() ++ c.filter(b == _.value.bitCount)))
 | 
			
		||||
    val table = cols.map(c => (0 to bits).map(b => collection.mutable.Set(c.filter(b == _.value.bitCount):_*)))
 | 
			
		||||
    for (i <- 0 to bits) {
 | 
			
		||||
      for (j <- 0 until bits-i)
 | 
			
		||||
        table(i)(j).foreach(a => table(i+1)(j) ++= table(i)(j+1).filter(_.similar(a)).map(_.merge(a)))
 | 
			
		||||
      prime ++= table(i).map(_.filter(_.prime)).reduceLeft(_++_)
 | 
			
		||||
      for (r <- table(i))
 | 
			
		||||
        for (p <- r; if p.prime)
 | 
			
		||||
          prime = p :: prime
 | 
			
		||||
    }
 | 
			
		||||
    prime
 | 
			
		||||
    prime.sort(_<_)
 | 
			
		||||
  }
 | 
			
		||||
  def getEssentialPrimeImplicants(prime: Set[Term], minterms: Set[Term]): Tuple3[Set[Term],Set[Term],Set[Term]] = {
 | 
			
		||||
    val useful1 = prime.toSeq
 | 
			
		||||
    for (i <- 0 until useful1.size) {
 | 
			
		||||
      val icover = minterms.filter(useful1(i) covers _)
 | 
			
		||||
      for (j <- 0 until useful1.size) {
 | 
			
		||||
        val jcover = minterms.filter(useful1(j) covers _)
 | 
			
		||||
        if (icover.size > jcover.size && jcover.forall(useful1(i) covers _))
 | 
			
		||||
          return getEssentialPrimeImplicants(prime - useful1(j), minterms)
 | 
			
		||||
  def getEssentialPrimeImplicants(prime: Seq[Term], minterms: Seq[Term]): (Seq[Term],Seq[Term],Seq[Term]) = {
 | 
			
		||||
    for (i <- 0 until prime.size) {
 | 
			
		||||
      val icover = minterms.filter(prime(i) covers _)
 | 
			
		||||
      for (j <- 0 until prime.size) {
 | 
			
		||||
        val jcover = minterms.filter(prime(j) covers _)
 | 
			
		||||
        if (icover.size > jcover.size && jcover.forall(prime(i) covers _))
 | 
			
		||||
          return getEssentialPrimeImplicants(prime.filter(_ != prime(j)), minterms)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    val essentiallyCovered = minterms.filter(t => prime.count(_ covers t) == 1)
 | 
			
		||||
    val essential = prime.filter(p => essentiallyCovered.exists(p covers _))
 | 
			
		||||
    val nonessential = prime -- essential
 | 
			
		||||
    val nonessential = prime.filterNot(essential contains _)
 | 
			
		||||
    val uncovered = minterms.filterNot(t => essential.exists(_ covers t))
 | 
			
		||||
    if (essential.isEmpty || uncovered.isEmpty)
 | 
			
		||||
      (essential, nonessential, uncovered)
 | 
			
		||||
@@ -109,19 +111,24 @@ object Simplify
 | 
			
		||||
      (essential ++ a, b, c)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  def getCost(cover: Set[Term], bits: Int) = cover.map(bits - _.mask.bitCount).sum
 | 
			
		||||
  def getCover(implicants: Set[Term], minterms: Set[Term], bits: Int) = {
 | 
			
		||||
    var cover = minterms.map(m => implicants.filter(_.covers(m)).map(i => Set(i))).toList
 | 
			
		||||
    while (cover.size > 1)
 | 
			
		||||
      cover = cover(0).map(a => cover(1).map(_ ++ a)).reduceLeft(_++_) :: cover.tail.tail
 | 
			
		||||
    if (cover.isEmpty)
 | 
			
		||||
      Set[Term]()
 | 
			
		||||
    else
 | 
			
		||||
      cover(0).reduceLeft((a, b) => if (getCost(a, bits) < getCost(b, bits)) a else b)
 | 
			
		||||
  def getCost(cover: Seq[Term], bits: Int) = cover.map(bits - _.mask.bitCount).sum
 | 
			
		||||
  def cheaper(a: List[Term], b: List[Term], bits: Int) = {
 | 
			
		||||
    val ca = getCost(a, bits)
 | 
			
		||||
    val cb = getCost(b, bits)
 | 
			
		||||
    def listLess(a: List[Term], b: List[Term]): Boolean = !b.isEmpty && (a.isEmpty || a.head < b.head || a.head == b.head && listLess(a.tail, b.tail))
 | 
			
		||||
    ca < cb || ca == cb && listLess(a.sort(_<_), b.sort(_<_))
 | 
			
		||||
  }
 | 
			
		||||
  def stringify(s: Set[Term], bits: Int) = s.map(t => (0 until bits).map(i => if ((t.mask & (1 << i)) != 0) "x" else ((t.value >> i) & 1).toString).reduceLeft(_+_).reverse).reduceLeft(_+" + "+_)
 | 
			
		||||
  def getCover(implicants: Seq[Term], minterms: Seq[Term], bits: Int) = {
 | 
			
		||||
    if (minterms.nonEmpty) {
 | 
			
		||||
      val cover = minterms.map(m => implicants.filter(_.covers(m)).map(i => collection.mutable.Set(i)))
 | 
			
		||||
      val all = cover.reduceLeft((c0, c1) => c0.map(a => c1.map(_ ++ a)).reduceLeft(_++_))
 | 
			
		||||
      all.map(_.toList).reduceLeft((a, b) => if (cheaper(a, b, bits)) a else b)
 | 
			
		||||
    } else
 | 
			
		||||
      Seq[Term]()
 | 
			
		||||
  }
 | 
			
		||||
  def stringify(s: Seq[Term], bits: Int) = s.map(t => (0 until bits).map(i => if ((t.mask & (1 << i)) != 0) "x" else ((t.value >> i) & 1).toString).reduceLeft(_+_).reverse).reduceLeft(_+" + "+_)
 | 
			
		||||
 | 
			
		||||
  def apply(minterms: Set[Term], dontcares: Set[Term], bits: Int) = {
 | 
			
		||||
  def apply(minterms: Seq[Term], dontcares: Seq[Term], bits: Int) = {
 | 
			
		||||
    val prime = getPrimeImplicants(minterms ++ dontcares, bits)
 | 
			
		||||
    minterms.foreach(t => assert(prime.exists(_.covers(t))))
 | 
			
		||||
    val (eprime, prime2, uncovered) = getEssentialPrimeImplicants(prime, minterms)
 | 
			
		||||
@@ -133,7 +140,7 @@ object Simplify
 | 
			
		||||
 | 
			
		||||
object SimplifyDC
 | 
			
		||||
{
 | 
			
		||||
  def getImplicitDC(maxterms: Set[Term], term: Term, bits: Int, above: Boolean): Term = {
 | 
			
		||||
  def getImplicitDC(maxterms: Seq[Term], term: Term, bits: Int, above: Boolean): Term = {
 | 
			
		||||
    for (i <- 0 until bits) {
 | 
			
		||||
      var t: Term = null
 | 
			
		||||
      if (above && ((term.value | term.mask) & (1L << i)) == 0)
 | 
			
		||||
@@ -145,12 +152,12 @@ object SimplifyDC
 | 
			
		||||
    }
 | 
			
		||||
    null
 | 
			
		||||
  }
 | 
			
		||||
  def getPrimeImplicants(minterms: Set[Term], maxterms: Set[Term], bits: Int) = {
 | 
			
		||||
    var prime = Set[Term]()
 | 
			
		||||
  def getPrimeImplicants(minterms: Seq[Term], maxterms: Seq[Term], bits: Int) = {
 | 
			
		||||
    var prime = List[Term]()
 | 
			
		||||
    minterms.foreach(_.prime = true)
 | 
			
		||||
    var mint = minterms.map(t => new Term(t.value, t.mask))
 | 
			
		||||
    val cols = (0 to bits).map(b => mint.filter(b == _.mask.bitCount))
 | 
			
		||||
    val table = cols.map(c => (0 to bits).map(b => collection.mutable.Set() ++ c.filter(b == _.value.bitCount)))
 | 
			
		||||
    val table = cols.map(c => (0 to bits).map(b => collection.mutable.Set(c.filter(b == _.value.bitCount):_*)))
 | 
			
		||||
 | 
			
		||||
    for (i <- 0 to bits) {
 | 
			
		||||
      for (j <- 0 until bits-i) {
 | 
			
		||||
@@ -168,12 +175,14 @@ object SimplifyDC
 | 
			
		||||
            table(i+1)(j) += a merge dc
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      prime ++= table(i).map(_.filter(_.prime)).reduceLeft(_++_)
 | 
			
		||||
      for (r <- table(i))
 | 
			
		||||
        for (p <- r; if p.prime)
 | 
			
		||||
          prime = p :: prime
 | 
			
		||||
    }
 | 
			
		||||
    prime
 | 
			
		||||
    prime.sort(_<_)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  def apply(minterms: Set[Term], maxterms: Set[Term], bits: Int) = {
 | 
			
		||||
  def apply(minterms: Seq[Term], maxterms: Seq[Term], bits: Int) = {
 | 
			
		||||
    val prime = getPrimeImplicants(minterms, maxterms, bits)
 | 
			
		||||
    assert(minterms.forall(t => prime.exists(_ covers t)))
 | 
			
		||||
    val (eprime, prime2, uncovered) = Simplify.getEssentialPrimeImplicants(prime, minterms)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user