Skip to content

Commit

Permalink
implement espressoMinimizer
Browse files Browse the repository at this point in the history
  • Loading branch information
sequencer committed May 15, 2021
1 parent 62f1029 commit 6546042
Showing 1 changed file with 59 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,71 @@ package chisel3.util.experimental.decode
import chisel3.util.BitPat
import logger.LazyLogging

class EspressoMinimizer extends Minimizer with LazyLogging {
def minimize(table: TruthTable): TruthTable = ???
object EspressoMinimizer extends Minimizer with LazyLogging {
def minimize(table: TruthTable): TruthTable = {
val (on, off, dontCare) = TruthTable.split(table)
TruthTable.merge(
(espresso(on._1), on._2),
(espresso(off._1), off._2),
(espresso(dontCare._1), dontCare._2)
)
}

def espresso(table: TruthTable): TruthTable = {
import scala.sys.process._
require(true, "todo, require table.default has same types.")
// @todo match decodeType here.
val decodeType: String = ???
val espressoTempFile = java.io.File.createTempFile("pla", "txt")
espressoTempFile.deleteOnExit()
new java.io.PrintWriter(espressoTempFile) {
try {
write(table.pla)
} finally {
close()
def writeTable(table: TruthTable): String = {
def invert(string: String) = string
.replace('0', 't')
.replace('1', '0')
.replace('t', '1')
val defaultType: Char = {
val t = table.default.toString.drop(7).dropRight(1).toCharArray.distinct
require(t.length == 1, "Internal Error: espresso only accept unified default type.")
t.head
}
val tableType: String = defaultType match {
case '?' => "fr"
case _ => "fd"
}
val rawTable = table
.toString
.split("\n")
.dropRight(1)
.mkString("\n")
.replace("->", " ")
.replace('?', '-')
// invert all output, since espresso cannot handle default is on.
val invertRawTable = rawTable
.split("\n")
.map(_.split(" "))
.map(row => s"${row(0)} ${invert(row(1))}")
.mkString("\n")
s""".i ${table.inputWidth}
|.o ${table.outputWidth}
|.type ${tableType}
|""".stripMargin ++ (if (defaultType == '1') invertRawTable else rawTable)
}
logger.trace(s"espresso input:\n${scala.io.Source.fromFile(espressoTempFile)}")
Seq("espresso", espressoTempFile.getPath).!!.toTruthTable(decodeType)
}

private implicit class EspressoTruthTable(table: TruthTable) {
def pla: String =
s""".i ${table.table.head._1.getWidth}
|.o ${table.table.head._2.getWidth}
|.type ${// match table.default here
???}
|""".stripMargin +
table.table.map((row: (BitPat, BitPat)) => s"${???}").mkString("\n")
}
def readTable(espressoTable: String): Map[BitPat, BitPat] = {
def bitPat(espresso: String): BitPat = BitPat("b" + espresso.replace('-', '?'))

private implicit class PLAToTruthTable(string: String) {
def toTruthTable(decodeType: String): TruthTable = {
// @todo: @yhr fix me
???
espressoTable
.split("\n")
.filterNot(_.startsWith("."))
.map(_.split(' '))
.map(row => bitPat(row(0)) -> bitPat(row(1)))
.toMap
}
}

private def split(table: TruthTable): (TruthTable, TruthTable, TruthTable) = ???

private def merge(
onTable: TruthTable,
offTable: TruthTable,
dontCareTable: TruthTable
): TruthTable = ???
// Since Espresso don't implements pipe, we use a temp file to do so.
val input = writeTable(table)
logger.trace(s"""espresso input table:
|$input
|""".stripMargin)
val f = os.temp(input)
val o = os.proc("espresso", f).call().out.chunks.mkString
logger.trace(s"""espresso output table:
|$o
|""".stripMargin)
TruthTable(readTable(o), table.default)
}
}

0 comments on commit 6546042

Please sign in to comment.