SkillAgentSearch skills...

Agravic

Simulation platform that enables VHDL-style C++ coding. VCD generation for easy debug. VHDL code generation using C preprocessor. Simple risc-V rv32i SoC example, + Risc-V test suite and gcc bare-metal example. Linux (or WSL) / clang or gcc / risc-v toolchain / quartus required

Install / Use

/learn @graffou/Agravic

README

January'21 updates

  • This risc-V SoC has been used for +9 months to test BTLE/802.15.4 IPs in C++ simulation environment.
  • Verilog IPs can easily be compiled with verilator and be integrated to this C++ SoC. The cycle eval method provided by verilator is easily scheduled by the Agravic simulator. The SoC has been running the verilated IPs and the ~500kB BTLE/MAC link layer firmware, which heavily runs on IRQ processing with WFI core stalling. This FW is compiled using a regular risc-V toolchain, and: so far, so good. Of course, these BTLE/MAC IPs are not provided here.
  • FPGA operation is still demonstrated with the "Agravic invaders" game.
  • What is new here is that the preferred development platform is the DE10-lite one. This implies that VGA output has been added to the project.
  • On the DE10, the firmware is loaded using a USB-to-UART interface, physically wired to GPIOs 11 and 13 of the DE10 board. On the 2x20 expansion connector, we have: pin 14 -> uart_rx of SoC pin 16 -> uart_tx of SoC
  • To load the FW, put board switch 0 on (the screen turns blue). Then go to FIRMWARE folder and do make PROGRAM=invaders ./load_uart invaders.bin Then put board switch 0 off, the FW starts.

Agravic

HW development platform in C++, NOT HLS but hardware-level C++ (VHDL generation via C preprocessor, HW simulation in C++). Arduino Vidor target (with HDMI console output). Risc-V small SoC (simple UART + DMA + HDMI console peripherals). Video demo of the SoC running on the Arduino Vidor: https://youtu.be/4wAXtRFF0tc (blurry video and awful speech inside ;)

https://www.youtube.com/watch?v=dMSiSrPnSbE

Latest updates

Too many, I should have committed a long time ago.

Platform improvements

  • Most important change is that Agravic now implements an event-driven simulator (Include_libs/scheduler2.h)

  • As a result, main.cpp and tb.h are way cleaner than before

  • Non-synchronous clocks can be created using FOREVER_PROCESS (see tb.h)

  • FOREVER_PROCESS can generate clocks. Though, it is a very simple piece of code that can't handle more complicated logic (e.g. conditions)

  • Despite the event-driven scheme, true combinational logic is not possible yet.

  • Though, the number of processes (synchronous or pseudo-combinational) per module is now 8 instead of 4.

  • FOREVER_PROCESSES create base clocks. Derived clocks can be created in regular processes (see Source/clk_gen.h)

  • Every <= operation on a clock signal creates 3 delta cycles (compute flop inputs, assign flop outputs, update combinational logic)

  • Delta cycles can be converted to ps delays in vcd output (define REPORT_DELTAS_AS_PS in scheduler2.h)

  • Arrays of arrays are now possible

  • Flops outputs update is only performed over modified flop inputs (improves simulation time)

  • One generic parameter per block is available. This is not enough, but this enables generic configuration of register base address and address span.

  • Clean-up started in Include_libs/slv.h (C macros and arrays are now separate files)

Risc-V SoC improvements

  • Some bugs corrected (rv core, dma...)
  • CSR are now implemented as a memory device. CSR instructions generate memory accesses. CSR tests now pass!
  • Timer and IRQs are implemented inside the csr_irq block. However, this feature is not fully implemented (HW and FW).
  • Thanks to flop-update only performed on modified flops, memory models are now common to C++ model and VHDL implementations.
  • Memory size is a generic parameter. This enables defining different instruction and data memory sizes.
  • Cleaner register configuration using block generic parameter. Register configuration is shared by HW and FW (Source.reg_defs.h).

Agravic has reached some level of maturity

The Risc-V tiny SoC HW can now be downloaded to the Arduino Vidor FPGA development platform and is running properly so far. HDMI console mode (with programmable fonts) available via the micro-HDMI connector The test firmware runs on the risc-V core on the cyclone-10 FPGA. The HW HDMI console offers some means of SW and HW debug. "agravic invaders" is a space invaders basic clone FW, fully written in bare-metal C++, and is now playable.

To build the HW

  • A linux system is preferred
  • You need a native g++ compiler, verions 7.4 to 8
  • You need to have quartus installed
  • You need the Arduino IDE
  • Download and install quartus prime lite (this is free from Intel website. This requires creating an account)
  • In agravic folder, run make. This builds the linux executable and VHDL files as well
  • Go to the RTL/Source folder. You should find the quartus project (top.qpf)
  • Open top.qpf in quartus and run compilation flow (hit start compilation button) After a few minutes (depending on HW configuration), compilation should complete with generation of a top.ttf file
  • Go to the ARDUINO/Agravic folder
  • Install the GO language package (this is just for the Arduino ttf->.h converter. This is Arduino's choice, I don't approve using an extra language to generate this kind of files: sudo apt-get install golang)
  • Generate .h files for the arduino project : go run make_composite_binary.go -i ../../RTL/Source/top.ttf:1:512 -o app.h -t 1 > signature.h
  • In the same directory, open Agravic.ino in Arduino IDE
  • Make sure you have the Arduino libraries for the Arduino mkr4000 Vidor board. If not, run the Arduino IDE board manager and download them.
  • When done, select the Arduino mkr4000 vidor board, /dev/ttyACM0 port (or whatever), and programmer as USBAsp. Then, upload the code.
  • You should see the GIORNO CORE prompt out of the Vidor HDMI interface (requires a micro HDMI -> HDMI cable)

To build and load the risc-V firmware

  • Go to the FIRMWARE folder
  • Edit the Makefile to set the actual path of your risc-V toolchain
  • Type make
  • The led.bin firware binary is available
  • Alternatively, build the invader example. Type:
  • make -f Makefile_invaders
  • Install putty (sudo apt-get install putty on ubuntu platforms)
  • Open putty. Configure putty for a Serial, 115200 bauds session using /dev/ttyACM0 device (the Vidor board might show up as the /dev/ttyACM1 or /dev/ttyUSB* device). Opening putty is sometimes required for proper serial configuration.
  • The FW is loaded via the USB serial port of the Arduino Vidor (the arduino FW mirrors it to the HW UART of the Risc-V SoC)
  • from the FIRMWARE directory:
  • use the load script to download the binary file: load invaders.bin
  • The HDMI console screen should (shortly) turn blue during FW upload
  • If the firmware does not load properly, the risc-V core might go into trap. The HDMI console then shows the execution trace, and might even turn red. Reset the board, then check that putty is open and set properly.
  • Code can be reloaded without resetting the Vidor board. However, I am aware that there might be some glitches (the HW is not properly resetted after code loading)
  • To play agravic invaders, bring the putty window to the front. Use the 's' and 'd' keys to move your ship, space bar to fire.

What is Agravic ?

Agravic is a framework that enables writing VHDL-like code inside a C++ program. It uses heavy preprocessor abuse for that, but the counterpart is that synthesizable VHDL code can be preprocessor-generated from the C++ code!

The syntax has been chosen to enable VHDL and C++ code generation using the C preprocessor and sed. At first, it might seem confusing for both C++ developers and rtl designers, but in the end, the syntax is so close to VHDL's that I feel this is not a problem.

So, agravic enables rtl code writing without the expense of EDA tools. Furthermore, C++ simulation of agravic designs should be faster than classical rtl simulation. But the platform is not optimized yet, and it is sure that designs with low flip-flop activity are slower than necessary. This is why memory models are not the same for simulation as for VHDL generation (altera memory inferring requires describing memories as wide arrays of flip-flops, with inherently low toggling rate).

Limitations

  • Unlike mentor ac_int types, arbitrary length types in Agravic only cover the 1-64 bits range. This is generally enough for most designs and enables using native int64 types as a base type.
  • Agravic does not make a true difference between bit-types and vector bit-types with size 1. So, some designs might compile in C++, but not the auto-generated VHDL files.
  • True combinational logic does not exist in Agravic. Traditional uses of combinational logic can be achieved this way:
    • Use in-process variables for intermediate calculations
    • Be careful of the non-retained nature of agravic variables. VHDL variables are retained, this can lead to a different behavior betwwen simulation and generated VHDL.
    • Use clock-driven combinational processes for output assignments
    • The risc-V SoC example shows how to do this
  • For now, a single clock signal is supported. Though, gated clocks can be created. => The SoC runs on three clocks, all derived from the master clock (240MHz) using a gating clock technique in simulation. The HW makes use of true clocks (24MHz pixel clk, 48MHz core clk, and 120MHz HDMI clk, all derived from the master 48MHz clk of the Arduino Vidor)

Requirements

  • A linux distribution, with a recent gcc ( > 7.4 ).
  • Ubuntu on windows, cygwin might do the job as well.
  • Gtkwave is highly recommended for waveform viewing.

Provided example (small risc-V SoC based on Giorno core)

A risc-V SoC example is provided to demonstrate the platform capabilities, for simulation and rtl generation as well.

The SoC is composed of the Giorno risc-V core (custom design based on rv32i instruction set), two 24kB RAMs (instruction and data), a peripheral block (used as printf port for now), a very simple UART interface (half duplex), DMA controller (for the UART only) and an HDMI console. An SDRAM controller is provided but is not functional yet, its projected use is for HDMI bitmap mode.

  • The Giorno core doe
View on GitHub
GitHub Stars5
CategoryDevelopment
Updated3mo ago
Forks1

Languages

C

Security Score

72/100

Audited on Dec 18, 2025

No findings