Skip to content

Quickstart

Five minutes from git clone to the first SPARC instruction running inside Tero. For the full build and host-requirement detail, see Installation.

1. Build

git clone https://github.com/claaj/tero.git
cd tero
cmake --preset default
cmake --build --preset default
git clone https://github.com/claaj/tero.git
cd tero
cmake -S . -B build -G Ninja
cmake --build build

CMake fetches fmt, tl::expected and Catch2 automatically (pinned in CMakeLists.txt). SoftFloat is vendored. The host must provide a C++20 compiler (GCC ≥ 13 or Clang ≥ 17), CMake ≥ 3.25, Ninja, git, LLVM ≥ 18 dev libraries, and internet access on the first configure. LLVM is the one dependency CMake does not download — see Installation.

For a reproducible, pre-pinned toolchain (LLVM included) use nix develop (documented in Installation).

2. Run the test suite

ctest --test-dir build --output-on-failure

All tests pass, with a small number of conditional skips for tests that need external artifacts (the SPARC cross-toolchain, pre-built RTEMS ELFs, or nm). See Verifying.

3. Run a tiny SPARC program

No cross-toolchain? Use the pre-built RTEMS image

The two steps below need the RCC cross-compiler to build SPARC binaries. If you have not installed it yet, skip to step 4 of First RTEMS boot — the repo ships a pre-built hello-world.elf you can run right now:

./build/src/app/tero-emu \
    --image tests/guest-programs/rtems/hello-world/hello-world.elf
You can come back and install RCC later if you need to build your own guests.

A minimal "hello UART" assembly program ships under tests/guest-programs/asm/hello-uart/hello_uart.S. The test harness builds it with the RCC cross-compiler; the resulting ELF can be passed straight to the CLI:

./build/src/app/tero-emu --image build/tests/guest-programs/asm/hello_uart.elf

Expected output on stdout:

Hello UART!

The CLI also writes a one-line halt summary to stderr when the run ends:

[tero-emu] halted: reason=DurationExpired instructions=... sim_time_ns=1000000000

--image is the only required flag; everything else has a sensible default (GR712RC recipe, 1 core, 16 MiB RAM, 1 second budget, realtime pacing, JIT on). The full list is in the CLI reference.

4. Turbo vs. realtime pacing

By default tero-emu paces simulated time to wall-clock time, so a 1-second budget really takes about 1 second. Pass --turbo to disable pacing and run as fast as the host can:

./build/src/app/tero-emu --turbo \
    --image build/tests/guest-programs/asm/hello_uart.elf

Use --turbo for CI, benchmarks, and any time you want maximum throughput regardless of wall-clock correlation. See Pacing for the model.

5. Inspect the lifecycle

Add --verbose to switch the logger to Debug and watch the emulator narrate each phase on stderr:

./build/src/app/tero-emu --verbose \
    --image build/tests/guest-programs/asm/hello_uart.elf

You will see, in order:

  1. EmulatorConfig validation
  2. RAM allocation at the configured base
  3. The GR712RC peripheral set being wired (IRQMP, MemCtrl, GPTimer, six APBUARTs, two GPIO ports)
  4. ELF segment loading with addresses and sizes
  5. The round-robin step loop running, with periodic time markers

6. Try multi-core

./build/src/app/tero-emu --cores 2 \
    --image build/tests/guest-programs/asm/hello_uart.elf

CPU 1 boots in power-down mode (per real GR712RC behaviour). It stays idle until CPU 0 releases it via the IRQMP, exactly as on the hardware. The single-threaded round-robin scheduler still guarantees Total Store Order and makes atomics (CASA, LDSTUB, SWAP) correct by construction. For true host-concurrency SMP add --mt (MultiThread). See Multi-core and timing.

7. Try the GR740

./build/src/app/tero-emu --soc gr740 \
    --image my_gr740_program.elf

--soc gr740 selects the quad-core LEON4FT recipe (RAM at 0x00000000, no PROM by default, the GR740 peripheral/IRQ map). When --soc gr740 is set, --cores and --ram are ignored (the recipe fixes them). See the CLI reference for the full flag interaction matrix.


What next?

  • Boot real RTEMS — cross-compile (or use a pre-built) RTEMS hello-world image and watch the BSP come up.
  • Embed Tero as a library — a few lines of C++, no globals, no allocation surprises.
  • CLI reference — every tero-emu flag, what it does, its default, and when to use it.
  • Configuration — every EmulatorConfig field with meaning, default, and effect.
  • Write a custom peripheral — implement IPeripheral, register it with add_peripheral(). DMA, IRQs and scheduled events all work out of the box.
  • Read the architecture — the design decisions that make the emulator embeddable, deterministic and SMP2-compatible.