{josuah.net} | {panoramix-labs.fr}
 (DIR)  • {josuah.net}
 (DIR)  • {panoramix-labs.fr}
       
        {git} | {cv} | {links} | {quotes} | {ascii} | {tgtimes} | {gopher} | {mail}
 (DIR)  • {git}
 (BIN)  • {cv}
 (DIR)  • {links}
 (DIR)  • {quotes}
 (DIR)  • {ascii}
 (HTM)  • {tgtimes}
 (DIR)  • {gopher}
       
       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
       Address decoding and multiplexer
       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
        When dealing with hardware there is often the need to convert input number to a
        binary flag output like so:
       
        ┊ sel     en
        ┊  0 => 0b1110
        ┊  1 => 0b1101
        ┊  2 => 0b1011
        ┊ ...
       
        For instance, if there are modules plugged like so:
       
        ┊                          ┌─────┐
        ┊                          │ t0  │
        ┊                  ┌───────en0   │
        ┊                  │   ┌───data  │
        ┊  ┌───────────┐   │   │   └─────┘
        ┊  │ decoder   │   │   │   ┌─────┐
        ┊  │         en0───┘   │   │ t1  │
        ┊ ─sel       en1───────────en1   │
        ┊ ─data      en2───┐   ├───data  │
        ┊  │           │   │   │   └─────┘
        ┊  │        data───│───┤   ┌─────┐
        ┊  └───────────┘   │   │   │ t2  │
        ┊                  └───────en2   │
        ┊                      └───data  │
        ┊                          └─────┘
        ┊       
       
        Above, there are two inputs: `sel` and `data`. The `sel` signal would be
        turning only one of the `enX` signal on at a time:
       
        • `en0` if it is 0,
       
        • `en1` if it is 1,
       
        • `en2` if it is 2.
       
       Frequent on PCB design
       ──────────────────────
        It is frequent to have an "enable" signal, (SPI, memories...). This construct
        is ubiquitous, as you would have noticed there is only one `data` signal shared
        with every other chip.
       
        Then the selection signal `sel` permits to choose which of the 3 targets (`t0`,
        `t1`, `t2`) to communicate with with the shared `data` bus. by telling each
        target:
       
        • "high": ignore my messages on 'data' line,
       
        • "low": listen to my message on 'data' line.
       
        Which of high or low means listen or ignore is a matter of convention.
       
        I/O are scarce resources on a chip, and this is a very frequently encountered
        problem. There are actually a lot of small ASICs doing exactly this:
       
 (HTM)  ┊ {https://octopart.com/search?category_id=4287} ASICs on octopart, going as
        ┊ low as 10 cents for 8 outputs
       
       Frequent on HDL design
       ──────────────────────
        It is also encountered while in hardware description languages (HDL) designs
        every time there is a bus with an address field: multiple targets (`t0`, `t1`,
        `t2`) would read an address port (like `sel` above).
       
        Addresses are written at the same time as data and if the address matches, then
        the data is used, otherwise, it is ignored.
       
        It looks like each target instance is monitoring the `sel` address port itself,
        but when pulling all this monitoring logic and putting it in common, the same
        construct as above is reproduced: just a matter of point of view.
       
        Here is what happen if we let each device decode its own address:
       
        ┊              ┌─────┐
        ┊              │ t0  │
        ┊       ┌──────addr  │
        ┊       │  ┌───data  │
        ┊       │  │   └─────┘
        ┊       │  │   ┌─────┐
        ┊       │  │   │ t1  │
        ┊       ├──────addr  │
        ┊       │  ├───data  │
        ┊       │  │   └─────┘
        ┊ data──│──┤   ┌─────┐
        ┊ addr──┤  │   │ t2  │
        ┊       └──────addr  │
        ┊          └───data  │
        ┊              └─────┘
       
       Implementation
       ──────────────
 (HTM)  The principle behind this is a {demultiplexer}, and has a reverse operation: a
        multiplexer.
       
        Depending on a two-bits address (1 and 2), a multiplexer would select which of
        A, B, C or D transmit to the output Z:
       
        ┊     12
        ┊     ||
        ┊    │`.
        ┊  A─┤  │
        ┊  B─┤  │_Z
        ┊  C─┤  │
        ┊  D─┤  │
        ┊    │,'
       
        I would like to implement the opposite: based on the address, I want to select
        the output.
       
        There might be much to read about this on the Internet, I will see what
        solution I come-up with for my various use-cases. If you want me to write about
        it, ping me at `me@josuah.net`, I might have tried a few things by then.
       
       Update
       ──────
 (HTM)  {https://www.eevblog.com/forum/fpga/address-decoder/}
       
        In verilog, using a `generate` macro is an easy way to implement it, looping 3
        times (in this example) over a variable such as `i`, and have `addr == i` for
        matching the slave device to use.
       
        An alternate way is to use the shift operator, that is peforming the decoder
        function on its own. FPGA work with gates, not assembly statements, so the
        compiler (such as yosys) will be the one to pick a mesh of gates that solves
        it.