From 2b6185b063dbea8f309369966f2cfdade06d8570 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Sun, 25 Feb 2018 08:57:28 +0100 Subject: [PATCH] Decoding logic : Add primes duplication removal --- .../vexriscv/demo/VexRiscvAvalonForSim.scala | 87 ++++++++++--------- .../vexriscv/plugin/DecoderSimplePlugin.scala | 81 ++++++++++++----- 2 files changed, 104 insertions(+), 64 deletions(-) diff --git a/src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala b/src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala index 6bea5f8..cf98c60 100644 --- a/src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala +++ b/src/main/scala/vexriscv/demo/VexRiscvAvalonForSim.scala @@ -17,6 +17,7 @@ import spinal.lib.eda.altera.{ResetEmitterTag, InterruptReceiverTag, QSysify} // //} +//make clean run DBUS=CACHED_AVALON IBUS=CACHED_AVALON MMU=no CSR=no DEBUG_PLUGIN=AVALON object VexRiscvAvalonForSim{ def main(args: Array[String]) { @@ -26,51 +27,51 @@ object VexRiscvAvalonForSim{ val cpuConfig = VexRiscvConfig( plugins = List( new PcManagerSimplePlugin(0x00000000l, false), -// new IBusSimplePlugin( -// interfaceKeepData = false, -// catchAccessFault = false -// ), -// new DBusSimplePlugin( -// catchAddressMisaligned = false, -// catchAccessFault = false -// ), - new IBusCachedPlugin( - config = InstructionCacheConfig( - cacheSize = 4096, - bytePerLine =32, - wayCount = 1, - addressWidth = 32, - cpuDataWidth = 32, - memDataWidth = 32, - catchIllegalAccess = true, - catchAccessFault = true, - catchMemoryTranslationMiss = true, - asyncTagMemory = false, - twoCycleRam = true - ) - // askMemoryTranslation = true, - // memoryTranslatorPortConfig = MemoryTranslatorPortConfig( - // portTlbSize = 4 - // ) + new IBusSimplePlugin( + interfaceKeepData = false, + catchAccessFault = false ), - new DBusCachedPlugin( - config = new DataCacheConfig( - cacheSize = 4096, - bytePerLine = 32, - wayCount = 1, - addressWidth = 32, - cpuDataWidth = 32, - memDataWidth = 32, - catchAccessError = true, - catchIllegal = true, - catchUnaligned = true, - catchMemoryTranslationMiss = true - ), - memoryTranslatorPortConfig = null - // memoryTranslatorPortConfig = MemoryTranslatorPortConfig( - // portTlbSize = 6 - // ) + new DBusSimplePlugin( + catchAddressMisaligned = false, + catchAccessFault = false ), +// new IBusCachedPlugin( +// config = InstructionCacheConfig( +// cacheSize = 4096, +// bytePerLine =32, +// wayCount = 1, +// addressWidth = 32, +// cpuDataWidth = 32, +// memDataWidth = 32, +// catchIllegalAccess = true, +// catchAccessFault = true, +// catchMemoryTranslationMiss = true, +// asyncTagMemory = false, +// twoCycleRam = true +// ) +// // askMemoryTranslation = true, +// // memoryTranslatorPortConfig = MemoryTranslatorPortConfig( +// // portTlbSize = 4 +// // ) +// ), +// new DBusCachedPlugin( +// config = new DataCacheConfig( +// cacheSize = 4096, +// bytePerLine = 32, +// wayCount = 1, +// addressWidth = 32, +// cpuDataWidth = 32, +// memDataWidth = 32, +// catchAccessError = true, +// catchIllegal = true, +// catchUnaligned = true, +// catchMemoryTranslationMiss = true +// ), +// memoryTranslatorPortConfig = null +// // memoryTranslatorPortConfig = MemoryTranslatorPortConfig( +// // portTlbSize = 6 +// // ) +// ), new StaticMemoryTranslatorPlugin( ioRange = _(31 downto 28) === 0xF ), diff --git a/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala b/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala index a3a7ed7..98b62ff 100644 --- a/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala +++ b/src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala @@ -204,15 +204,17 @@ object SymplifyBit{ if (term.value.testBit(i)) t = Masked(term.value.clearBit(i), term.care) } - if (t != null && !falseTerms.exists(_.intersects(t))) + if (t != null && !falseTerms.exists(_.intersects(t))) { + t.isPrime = false return t + } } null } //Return primes implicants for the trueTerms, falseTerms spec. Default value is don't care def getPrimeImplicantsByTrueAndFalse(trueTerms: Seq[Masked], falseTerms: Seq[Masked], inputWidth : Int): Seq[Masked] = { - val primes = ArrayBuffer[Masked]() + val primes = mutable.LinkedHashSet[Masked]() trueTerms.foreach(_.isPrime = true) falseTerms.foreach(_.isPrime = true) val trueTermByCareCount = (inputWidth to 0 by -1).map(b => trueTerms.filter(b == _.care.bitCount)) @@ -243,29 +245,44 @@ object SymplifyBit{ primes += p } - verify(primes, trueTerms, falseTerms) - for(prime <- primes){ - try{ - verify(primes.filterNot(_ == prime), trueTerms, falseTerms) - assert(false) - } catch { - case _ : Throwable => + def optimise() { + val duplicateds = primes.filter(prime => verifyTrueFalse(primes.filterNot(_ == prime), trueTerms, falseTerms)) + if(duplicateds.nonEmpty) { + primes -= duplicateds.maxBy(_.care.bitCount) + optimise() } } - primes + + optimise() + + verifyTrueFalse(primes, trueTerms, falseTerms) + var duplication = 0 + for(prime <- primes){ + if(verifyTrueFalse(primes.filterNot(_ == prime), trueTerms, falseTerms)){ + duplication += 1 + } + } + if(duplication != 0){ + PendingError(s"Duplicated primes : $duplication") + } + primes.toSeq } //Verify that the 'terms' doesn't violate the trueTerms ++ falseTerms spec - def verify(terms : Seq[Masked], trueTerms : Seq[Masked], falseTerms : Seq[Masked]): Unit ={ - require(trueTerms.forall(trueTerm => terms.exists(_ covers trueTerm))) - require(falseTerms.forall(falseTerm => !terms.exists(_ covers falseTerm))) + def verifyTrueFalse(terms : Iterable[Masked], trueTerms : Seq[Masked], falseTerms : Seq[Masked]): Boolean ={ + return (trueTerms.forall(trueTerm => terms.exists(_ covers trueTerm))) && (falseTerms.forall(falseTerm => !terms.exists(_ covers falseTerm))) } + def checkTrue(terms : Iterable[Masked], trueTerms : Seq[Masked]): Boolean ={ + return trueTerms.forall(trueTerm => terms.exists(_ covers trueTerm)) + } + + // Return primes implicants for the trueTerms, default value is False. // You can insert don't care values by adding non-prime implicants in the trueTerms // Will simplify the trueTerms from the most constrained ones to the least constrained ones def getPrimeImplicantsByTrueAndDontCare(trueTerms: Seq[Masked],dontCareTerms: Seq[Masked], inputWidth : Int): Seq[Masked] = { - val primes = ArrayBuffer[Masked]() + val primes = mutable.LinkedHashSet[Masked]() trueTerms.foreach(_.isPrime = true) dontCareTerms.foreach(_.isPrime = false) val termsByCareCount = (inputWidth to 0 by -1).map(b => (trueTerms ++ dontCareTerms).filter(b == _.care.bitCount)) @@ -281,7 +298,29 @@ object SymplifyBit{ for (p <- r; if p.isPrime) primes += p } - primes + + + def optimise() { + val duplicateds = primes.filter(prime => checkTrue(primes.filterNot(_ == prime), trueTerms)) + if(duplicateds.nonEmpty) { + primes -= duplicateds.maxBy(_.care.bitCount) + optimise() + } + } + + optimise() + + + var duplication = 0 + for(prime <- primes){ + if(checkTrue(primes.filterNot(_ == prime), trueTerms)){ + duplication += 1 + } + } + if(duplication != 0){ + PendingError(s"Duplicated primes : $duplication") + } + primes.toSeq } def main(args: Array[String]) { @@ -303,11 +342,11 @@ object SymplifyBit{ println("UUT") println(reducedPrimeImplicants.map(_.toString(4)).mkString("\n")) } -// { -// val trueTerms = List(0, 15).map(v => Masked(v, 0xF)) -// val falseTerms = List(3).map(v => Masked(v, 0xF)) -// val primes = getPrimeImplicants(trueTerms, falseTerms, 4) -// println(primes.map(_.toString(4)).mkString("\n")) -// } + { + val trueTerms = List(0, 15).map(v => Masked(v, 0xF)) + val falseTerms = List(3).map(v => Masked(v, 0xF)) + val primes = getPrimeImplicantsByTrueAndFalse(trueTerms, falseTerms, 4) + println(primes.map(_.toString(4)).mkString("\n")) + } } } \ No newline at end of file