# 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))
}

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)))
{"ft_lang_label":"__label__en","ft_lang_prob":0.57967603,"math_prob":0.9102823,"size":2578,"snap":"2023-14-2023-23","text_gpt3_token_len":609,"char_repetition_ratio":0.14724165,"word_repetition_ratio":0.0,"special_character_ratio":0.23041117,"punctuation_ratio":0.14123006,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9501686,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2023-06-03T05:54:49Z\",\"WARC-Record-ID\":\"<urn:uuid:b9938f88-129c-424f-88e5-c6e99ad022a1>\",\"Content-Length\":\"23395\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:cafc9688-be04-4375-a2fc-f8ed8a78c8a5>\",\"WARC-Concurrent-To\":\"<urn:uuid:2dccf2c7-e535-425d-9322-429faee6e773>\",\"WARC-IP-Address\":\"185.199.110.153\",\"WARC-Target-URI\":\"http://www.chisel-lang.org/chisel3/docs/explanations/decoder.html\",\"WARC-Payload-Digest\":\"sha1:UIMVRFDBOY3ZRN3RZOYQQPZN3OT54URW\",\"WARC-Block-Digest\":\"sha1:RUMDLFP4LJBJTWHJLEICFOYS4GM5HEM7\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2023/CC-MAIN-2023-23/CC-MAIN-2023-23_segments_1685224649105.40_warc_CC-MAIN-20230603032950-20230603062950-00740.warc.gz\"}"}