Skip to main content

# Decoders

It is common in a complex design to recognize certain patterns from a big `UInt` coming from a data bus and dispatch actions to next pipeline stage based on such observation. The circuit doing so can be called as 'decoders' such as address decoders in a bus crossbar or instruction decoders in a CPU frontend. Chisel provides some utility class to generate them in `util.exprimental.decode` package.

## Basic Decoders​

The simplest API provided by `decoder` is essentially just a `TruthTable` encoding your desired input and output.

    import chisel3._
    import chisel3.util.BitPat
    import chisel3.util.experimental.decode._

    class SimpleDecoder extends Module {
      val table = TruthTable(
        Map(
          BitPat("b001") -> BitPat("b?"),
          BitPat("b010") -> BitPat("b?"),
          BitPat("b100") -> BitPat("b1"),
          BitPat("b101") -> BitPat("b1"),
          BitPat("b111") -> BitPat("b1")
        ),
        BitPat("b0"))
      val input = IO(Input(UInt(3.W)))
      val output = IO(Output(UInt(1.W)))
      output := decoder(input, table)
    }

## DecoderTable​

When the decoded result involves multiple fields, each with its own semantics, the `TruthTable` can quickly be become hard to maintain. The `DecoderTable` API is designed to generate decoder table from structured definitions.

The bridge from structured information to its encoding is `DecodePattern` trait. The `bitPat` member defines the input `BitPat` in the decode truth table, and other members can be defined to contain structured information.

To generate output side of the decode truth table, the trait to use is `DecodeField`. Given an instance implementing the `DecodePattern` object, the `genTable` method should return desired output.

    import chisel3.util.BitPat
    import chisel3.util.experimental.decode._

    case class Pattern(val name: String, val code: BigInt) extends DecodePattern {
      def bitPat: BitPat = BitPat("b" + code.toString(2))
    }

    object NameContainsAdd extends BoolDecodeField[Pattern] {
      def name = "name contains 'add'"
      def genTable(i: Pattern) = if (i.name.contains("add")) y else n
    }

Then all `DecodePattern` cases can be generated or read from external sources. And with all `DecodeField` objects, the decoder can be easily generated and output can be read by corresponding `DecodeField`s.

    import chisel3._
    import chisel3.util.experimental.decode._

    class SimpleDecodeTable extends Module {
      val allPossibleInputs = Seq(Pattern("addi", BigInt("0x2")) /* can be generated */)
      val decodeTable = new DecodeTable(allPossibleInputs, Seq(NameContainsAdd))

      val input = IO(Input(UInt(4.W)))
      val isAddType = IO(Output(Bool()))
      val decodeResult = decodeTable.decode(input)
      isAddType := decodeResult(NameContainsAdd)
    }