Muxes and Decoders

Now, we will demonstrate how to use conditional statements through a series of small, related examples.

Multiplexer

Mux2 is a module which takes two inputs and selects between them.

mux2.vir
mod Mux2 {
    incoming a : Word[8]
    incoming b : Word[8]
    incoming select : Bit

    outgoing out : Word[8] {
        it := if select {
            a
        } else {
            b
        }
    }
}

Mux2 is a simple module which takes in two signals a and b and a control signal select. It outputs a if select is asserted and b otherwise.

If Expressions

We use if to select between two different values. The curly braces are always required.

If Statements

You may have felt it was a little weird to read if expressions. We’re used to hearing the phrase if statement. Virdant has both.

Here is an alternative version that showcases if expressions:

mux2_alt.vir
mod Mux2 {
    incoming a : Word[8]
    incoming b : Word[8]
    incoming select : Bit

    outgoing out : Word[8] {
        if select {
            it := a
        } else {
            it := b
        }
    }
}

Which do you find more natural?

Note

Verilog uses the syntax select ? a : b borrowed from C.

Virdant, on the other hand, prefers that the two variants look the same.

Decoder

Decoder4 takes a number as input and outputs the “one-hot encoding” of that number.

decoder4.vir
mod Decoder4 {
    incoming inp : Word[2]

    outgoing out : Word[4] {
        it := match inp {
            case 0 => 0b0001
            case 1 => 0b0010
            case 2 => 0b0100
            case 3 => 0b1000
        }
    }
}

Decoder4 takes a 2-bit number inp as input. It’s output, out, is a 4-bit number whose bits are all zero except for the position given by the inp.

Match Expressions

Because we are selecting between multiple alternatives, we use match.

A match expression is a fancy if statement. It looks at the value you give and tries to match it against all of the different cases. When it finds one that matches, the result becomes the value given on the right hand side of the =>.

One really nice thing about match statements is that they prevent you from “forgetting” to cover every case.

Literals

Since we are outputting a binary value, it felt like it would make a lot of sense to use Virdant’s syntax for binary numbers: 0b0001.

Match Statements

Just as there are both if expressions and if statements, Virdant has both match expressions and match statements.

decoder4_alt.vir
mod Decoder4 {
    incoming inp : Word[2]

    outgoing out : Word[4] {
        match inp {
            case 0 => {
                it := 0b0001
            }
            case 1 => {
                it := 0b0010
            }
            case 2 => {
                it := 0b0100
            }
            case 3 => {
                it := 0b1000
            }
        }
    }
}

I think in this case, I like the match expression version! However, it’s very common to use match statements in more complicated examples.