LANGUAGE GUIDE07 / 10

Built-in Functions and Operations

Yodl provides several built-in functions and operations to facilitate hardware design.

Type Conversion Functions

uint!(x)

Reinterprets a value as an unsigned integer.

Yodl / uint x
let a: s8 = -7'd11
let b: u8 = uint!(a) // 8'd11

When applied to a vector of bits, it concatenates them into a single unsigned integer.

Note that the first element of the vector becomes the least significant bit (LSB) of the resulting integer. If you would like the order to be preserved, use the cat! built-in.

Yodl / uint x 2
let bits = [true, false, true, true]
assert!(uint!(bits) == 4'b1101)

sint!(x)

Reinterprets a value as a signed integer.

Yodl / sint x
let a: s8 = sint!(8'b10101010)

clock!(x)

Converts a boolean signal to a clock signal.

Yodl / clock x
let counter = Reg[u24](clk)
counter.d = counter.q + 1
let slow_clk = clock!(counter.q[23]) // Divide the clock by 2^23

Mathematical Functions

clog2!(n)

Computes the ceiling of the base-2 logarithm of n.

Often used to determine the minimum number of bits required to represent a value.

Yodl / clog2 n
const AddrWidth = clog2!(1024)
let addr: uint[AddrWidth] = 10'd0
assert!(AddrWidth == 10)

pow!(base, exp)

Computes the power of base raised to exp.

Yodl / pow base exp
const kilobyte = pow!(2, 10)
assert!(kilobyte == 1024)

cdiv!(a, b)

Computes the ceiling of the division of a by b.

Yodl / cdiv a b
const data_size = 1024
const block_size = 100
const blocks_needed = cdiv!(data_size, block_size)
assert!(blocks_needed == 11)

Bit Manipulation

flip!(x)

Reverses the bit order of x.

Yodl / flip x
const flipped = flip!(5'b11100)
assert!(flipped == 5'b00111)

Vector Functions

cat!(args...)

Concatenates one or more integers (or integer vectors) into a single integer. The width of the result is the sum of the widths of the arguments. Vectors of integers are flattened recursively.

If any argument is a signed integer (sint), every argument must be signed.

Yodl / cat args
let upper_nibble = 8'hAB
let lower_nibble = 8'hCD
let word = cat!(upper_nibble, lower_nibble)
assert!(word == 16'hABCD)

// Vectors are flattened
let from_vec = cat!([16'hBABA, 16'hFABE])
assert!(from_vec == 32'hBABAFABE)

fill!(n, x)

Produces a vector [n]T containing n copies of x. For bit-replication (SystemVerilog {n{x}}), combine with cat!:

Yodl / fill n x
let zeros: [4]u1 = fill!(4, 1'b0)
let mask:  u4 = cat!(fill!(4, 1'b1))   // 4'b1111
assert!(uint!(zeros) == 4'd0)
assert!(mask == 4'b1111)

rev!(vec)

Reverses the order of elements in a vector.

Particularly useful when constructing a bit vector from a list of bits from most to least significant since vectors are indexed from least to most significant, i.e. vec[0] is the first element.

Yodl / rev vec
let reversed = rev!([1'1, 1'0, 1'0, 1'0])
assert!(reversed[0] == 1'0)
assert!(reversed[1] == 1'0)
assert!(reversed[2] == 1'0)
assert!(reversed[3] == 1'1)

pad!(x, width)

Extends the bit-width of an integer x to width bits. If x is signed, it performs sign-extension; if x is unsigned, it performs zero-extension:

type of xpad!(x, width)
sint[W]sign-extend
uint[W]zero-extend
Yodl / pad x width
let a = -4'd3 // 5'b1101
let b: s8 = pad!(a, 8) // 8'b11111101 (sign-extended)
assert!(uint!(b) == 8'b11111101)
let c: u4 = 4'd3 // 4'b0011
let d: u8 = pad!(c, 8) // 8'b00000011 (zero-extended)
assert!(d == 8'b00000011)

Memory Functions

Yodl provides familiar $readmemb and $readmemh functions to initialize Memory instances from files.

readmemb!(file, memory)

Initializes a memory from a binary format file.

Yodl / readmemb file memory
let rom = Memory[
    T: u8,
    Depth: 256,
    ReadPorts: 1,
    WritePorts: 0,
](
    read: [(clk: clk, en: true, addr: addr)],
)

// Initialize memory from binary file
readmemb!("rom_data.bin", rom)

let data = rom.q[0]

readmemh!(file, memory)

Initializes a memory from a hexadecimal format file.

Yodl / readmemh file memory
let rom = Memory[
    T: u8,
    Depth: 256,
    ReadPorts: 1,
    WritePorts: 0,
](
    read: [(clk: clk, en: true, addr: addr)],
)

// Initialize memory from hex file
readmemh!("rom_data.hex", rom)

let data = rom.q[0]

Debug Functions

printf!(format_string, args..)

Prints formatted text during simulation. Similar to C's printf.

Yodl / printf format string args
printf!("Value of data: %d", data)

assert!(predicate, [format_string, args..])

Asserts that the predicate is true. If the predicate is false, the simulation stops and prints an optional error message.

Yodl / assert predicate format string args
assert!(true == 1'b1)
const two_plus_two = 2 + 2
assert!(two_plus_two == 4, "Math is broken, expected 4, got %d", two_plus_two)

stop!([exit_code])

Stops the simulation with an optional exit code.

Yodl / stop exit code
if error_condition {
    stop!(1)
}

Type to search all chapters.

Reset this example?

Your local edits will be replaced by the original source.

Share this example

The link includes your edits and selected compiler stage. It uses the deployed compiler version.