LANGUAGE GUIDE02 / 10

Getting started

To try Yodl directly in your browser, visit the playground.

Installation

The simplest way to get yodl is to install the bundled npm package:

$ npm install --global yodl
$ yodl examples/Hello.yodl "write_firrtl Hello.fir"

.fir files can then be converted to SystemVerilog using firtool (tested with version 1.111.1).

Feature support for SystemVerilog/Verilog differs from tool to tool, check this page to customise the output. When using Yosys for instance, specify --lowering-options=disallowPackedArrays,disallowLocalVariables,emitBindComments.

firtool --format=fir --verilog Hello.fir -o Hello.sv

The project can also be compiled to wasm or wasm-gc by installing Moonbit and running:

$ git clone https://github.com/nathsou/yodl
$ cd yodl
$ moon build --target wasm-gc
$ moon run src/main examples/Hello.yodl "write_firrtl Hello.fir"

Editor support

Visual Studio Code

A syntax-highlighting extension is embedded in the repository, to install it, do:

  1. Open the command palette (Ctrl | Cmd + Shift + P)
  2. Select 'Developer: Install Extension from Location'
  3. Open 'extensions/yodl-vscode-syntax'

Your first Yodl design

Create a file called Blink.yodl and insert the following text:

Yodl / your first yodl design
module Top(
  // inputs
  clk: clock,
  rst: bool,
) -> (
  // outputs
  leds: u8,
) {
  let counter = Reg[u24](clk, rst)
  counter.d = counter.q + 1'd1
  leds = counter.q[23:16]
}

This simple design creates a 24-bit counter and displays the 8 most-significant bits to the output leds port.

Key Features

Yodl provides several key features for hardware design:

  • Type-safe hardware description: Strong typing prevents many common hardware design errors
  • Primitive modules: Built-in registers, memories, and other essential building blocks
  • External module integration: Seamlessly integrate existing Verilog modules (see External Modules)

Compilation Process

To convert this Yodl design to FIRRTL:

yodl Blink.yodl "write_firrtl Blink.fir"

Which should output:

FIRRTL version 4.1.0
circuit Top:
  public module Top:
    input clk: Clock
    input rst: UInt<1>
    output leds: UInt<8>

    wire counter: { flip d: UInt<24>, q: UInt<24> }
    regreset reg_0: UInt<24>, clk, rst, UInt<24>(0)
    connect counter.q, reg_0
    connect reg_0, counter.d
    connect counter.d, counter.q
    node temp_1 = bits(add(counter.q, UInt<1>(1)), 24, 0)
    connect counter.d, temp_1
    node temp_2 = bits(counter.q, 23, 16)
    connect leds, temp_2

Now to generate a SystemVerilog file:

firtool --format=fir -O=release --verilog \
      -disable-all-randomization -strip-debug-info \
      --lowering-options=disallowPackedArrays,disallowLocalVariables \
      Blink.fir -o Blink.sv 

Which should output a file similar to:

// Generated by CIRCT firtool-1.149.0
module Top(
  input        clk,
               rst,
  output [7:0] leds
);

  reg [23:0] reg_0;
  always @(posedge clk) begin
    if (rst)
      reg_0 <= 24'h0;
    else
      reg_0 <= reg_0 + 24'h1;
  end // always @(posedge)
  assign leds = reg_0[23:16];
endmodule

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.