EVIA Paradigma is visual programming: drag blocks from the palette onto the canvas, wire them together and press Run. The same program can be turned into C (C99, C11, C17) or C++ (C++98 to C++20) and compiled with Clang or GCC, or into code for Arduino and ESP32 boards.
The interface itself is in English, Russian or Armenian too: Settings > Interface language. Menus, buttons, the palette and the names on the blocks follow; the generated code and the compilers' messages stay in English. The change takes effect when EVIA Paradigma starts again.
Look and language. View > Theme chooses the IntelliJ light theme, the Darcula dark theme or the setting of your system; it changes at once and is remembered. Above the topic list you can read this guide in English, Russian or Armenian.
| Block | Code | What it does |
|---|---|---|
| Start / End | - | Where the main program begins and stops. |
| Set | x = x + 1 | Assigns a variable (or a field: this.count = 0). |
| Input | n | Asks for a value and stores it. |
"x = " + x | Prints the value of an expression. | |
| If / Else | x > 10 | Two outputs: then and else. |
| For | i = 1; i <= 10; i = i + 1 | Output body runs while the condition holds; wire the end of the body back to the For block. done continues after the loop. |
| While | n > 0 | Checks before every pass. |
| Do-While | n > 0 | Runs the body once, then checks. |
| Enter / Exit | exit name | Only inside a class method: where it begins and the ways it can end. |
The Board blocks (Pin Mode, Digital Write, Digital Read, Analog Read, Analog Write, Delay, Millis, UART, SPI, I2C) are for microcontrollers; see Arduino and ESP32 boards.
Values are numbers or text. Operators, from lowest to highest priority:
|| &&== != < <= > >= (texts compare alphabetically)+ - (+ joins text if either side is text)* / %- and !, parenthesesText uses double quotes and \", \\, \n escapes. A condition is true
when it is a non-zero number or a non-empty text.
A class bundles fields (data each object keeps) and methods (block programs that work on it). Create one with Edit > New Class, the palette's + New class, or select blocks and press Ctrl+G to turn them into a class.
this.name.n is read as this.n.init (button + Constructor). When an object is
created its fields get their initial values first, then init runs once.Drag a method from the Classes section of the palette onto the canvas to call it. Right-click the block, or double-click it, to choose the method, the object and the arguments. Blocks with the same object name share one object (and its fields); a block with no object name has an object of its own. Objects are created the first time they are used.
A module (*.eviam) is a file of classes that several programs can use.
File > New Project creates a folder with everything a program needs:
MyProject/ MyProject.eviaproj project settings main.evia the main program modules/ class modules build/ generated code (not committed) README.md .gitignore
Open it again with File > Open Project (choose the folder or the .eviaproj file). In a project,
modules are imported from and exported to modules/, and Generate code also writes
build/<name>.c or .cpp. The project remembers its language.
The Git menu runs the git installed on your computer and uses the login it already has
(Git Credential Manager, an SSH key or gh auth login). EVIA Paradigma never asks for or stores
passwords or tokens.
git init on branch main (new projects do this automatically when git is installed).owner/repo or a clone URL. Create repository on GitHub
opens github.com in your browser with the name filled in; create it empty, then press OK.Install git from git-scm.com if the menu says it is missing.
Generate code (F7) turns the whole program into one source file. Three drop-down lists in the toolbar (and in the code window) choose what you get; Run > Code Language and Mode has the same choices. Changing them in the code window generates the code again.
| List | Choices | What changes |
|---|---|---|
| Language | C99, C11, C17 C++98, C++11, C++14, C++17, C++20 |
C: a struct per class and functions Class_m_method(self, ...), a small runtime with only
the helpers the program uses. C++: a struct per class with member functions; C++98 uses plain pointers,
C++11/14 std::unique_ptr, C++17/20 std::variant and std::to_chars. |
| Flow | Structured Goto |
Structured: if/else, for, while, do/while
and switch (labels only where the wiring is not block-structured). Goto: every block is a label and every
wire a jump, closest to the diagram. |
| Values | Safe Fast |
Safe: numbers and text with exactly the interpreter's checks (undefined variables, division by zero, text that is
not a number, endless recursion). Fast: plain double variables and fields, text only in Print, no
runtime checks. A program that keeps text in a variable can't use Fast values; Generate code says which block. |
Every combination is tested to give the same output as the interpreter (with Fast values: for programs that run without errors). Right-click a block, a method or a class and choose View source code to see the code it became, highlighted, in the language you chose.
The code window can save the file, compile it and run it. For C it uses the matching C compiler (clang, gcc), the
right -std= and -lm. Settings chooses the compiler: Clang (clang++ / clang) or
GCC (g++ / gcc, version 13 or newer). On Windows EVIA Paradigma can install either one for you: llvm-mingw
(Clang) or WinLibs (GCC, MinGW-w64). Visual Studio is not needed.
Three more languages make code for microcontrollers. Both use fast values (numbers; text only in Print), and Print and Input go over the serial port at 115200 baud.
| Language | Boards | Built with |
|---|---|---|
| Arduino | Arduino Uno, Nano, Mega 2560, Leonardo, Micro, Pro Mini; ESP32, ESP32-S2, -S3, -C3, -C6, -H2 |
One sketch (.ino) with setup() and loop(); arduino-cli with the arduino:avr
and esp32:esp32 cores. |
| AVR C | the six Arduino AVR boards (ATmega328P, ATmega2560, ATmega32U4) | Bare-metal C: no Arduino core. Pins, timers, PWM, the ADC and the UART are driven through the chip's registers. avr-gcc and avr-libc build it, avrdude uploads it. |
| PIC32 C | nine PIC32MX chips: MX1xx/2xx (PIC32MX150F128B, 250F128B, 270F256B), MX3xx/4xx (320F128H, 340F512H, 440F256H, 460F512L), MX5xx/6xx/7xx (695F512L, 795F512L) and the PIC32 Ethernet Starter Kit II (LED1 on RD0) | Bare-metal C for Microchip's XC32: clock, pins, PWM, ADC, UART, SPI and I2C are driven through the registers; no Harmony or plib.
xc32-gcc builds it, xc32-bin2hex makes the .hex, and an upload command of your choice (pic32prog by default) loads it. |
Choose the board in the Board list next to the language (also in Settings). Build in the code window compiles for it; Upload builds and sends the program to the board on the serial port set in Settings.
| Block | Code | What it does |
|---|---|---|
| Pin Mode | LED_BUILTIN, OUTPUT | OUTPUT, INPUT or INPUT_PULLUP (a button to ground reads LOW when pressed). |
| Digital Write | LED_BUILTIN, HIGH | HIGH for any non-zero value, LOW for 0. |
| Digital Read | pressed = 4 | Stores 1 (HIGH) or 0 (LOW). |
| Analog Read | level = A0 | 0..1023 on AVR boards, 0..4095 on ESP32. |
| Analog Write | 5, brightness | PWM, 0 (off) .. 255 (always on). |
| Delay | 500 | Waits this many milliseconds. |
| Millis | t | Stores the milliseconds since the program started. |
| UART Open | 9600 | Starts the serial port used by the UART blocks, at this baud rate. |
| UART Write | 65 | Sends one byte (0..255). |
| UART Read | c | Stores the next received byte, or -1 if none has arrived. |
| SPI Open | 1000000 | Starts the SPI bus as master at this clock in Hz (mode 0, most significant bit first). |
| SPI Transfer | reply = 66 | Sends a byte and stores the byte that came back at the same time. |
| I2C Open | 100000 | Starts the I2C bus as master at this clock in Hz. |
| I2C Write | 80, 0, 42 | Writes a value to a register of the device at this 7-bit address: address, register, value. |
| I2C Read | v = 80, 0 | Stores the register's value, or -1 if no device answers at that address. |
| MQTT Connect | "network", "password", "broker.example.com", 1883 | Joins the network and connects to the MQTT broker. |
| MQTT Publish | "evia/temperature", t | Sends a message on that topic: a number or a text. |
| MQTT Subscribe | "evia/command" | Asks the broker for the messages of that topic (up to four topics). |
| MQTT Has Message | waiting = "evia/command" | Stores 1 when a message of that topic is waiting, 0 when none is. |
| MQTT Read | cmd = "evia/command" | Stores the number in the next message, or -1 if none has arrived. |
MQTT. The network name, password, broker and topics are fixed texts, because they are written into the program when it is built. PIC32 C drives an ESP8266 or ESP32 module with AT firmware on UART2 (RB5/RB1 on the 28-pin chips, RF4/RF5 on the others), so Print keeps UART1. Arduino on an ESP32 board uses the board's own WiFi. Run answers from a broker on your computer: publishing to a topic you subscribed to brings the message back. An AVR board refuses the MQTT blocks (one serial port, which Print uses), and so does an FPGA. A message is a number, written as Print writes it; since -1 also means "nothing has arrived", MQTT Has Message tells a real -1 apart. MQTT can also go through the chip's own Ethernet port on the MX695F512L, the MX795F512L and the Ethernet Starter Kit II: set PIC32 MQTT over to Ethernet in Settings and the generated file becomes an application for an MPLAB X Harmony project, which brings the TCP/IP stack. That route is experimental: it compiles against stub headers here, but has never been built against real Harmony or run on a board, so the WiFi module is still the tested one.
MQTT over Ethernet (experimental). For the MX695F512L, the MX795F512L and the PIC32 Ethernet Starter Kit II, Settings > PIC32 MQTT over > Ethernet makes the generated file an application for an MPLAB X Harmony project: Harmony brings the TCP/IP stack, the project keeps its own configuration, clock and main(), and you call app_run() from it. Enable TCP, the DHCP and DNS clients, the Ethernet MAC driver and the board's PHY (LAN8740 on the starter kit). The address comes from DHCP, so the network name and password are not used. This path compiles against stub headers in the checks, but has not been built against real Harmony or run on a board: the WiFi module is the tested one.
Pins can be numbers, expressions or the board's names LED_BUILTIN, A0 ... A15;
HIGH and LOW work in any expression. These names can't be used as variables.
The bus blocks work in Run and in all three board languages. Open a bus before using it; addresses are 7-bit and the numbers are decimal (80 is 0x50). On a PIC32 the pins are fixed per chip family and listed at the top of the generated code (the chip's own UART1, SPI and I2C1). Run simulates the buses: the UART's transmitter is wired to its receiver, so what UART Write sends comes back from UART Read (and also appears as output text), SPI's input is wired to its output, and one I2C device with 256 registers answers at address 80.
Run simulates an Arduino Uno: pin changes appear in the output as board [500 ms] pin 13 HIGH,
time only moves forward in Delay (the main window also really waits, unless the speed slider is at full speed),
a button on every input pin is pressed during the second half of each 2 seconds, and analog pins read a slow wave
0..1023..0. The program runs once, as if from setup(); afterwards the pins keep their state.
File > Open Example > Arduino and ESP32 Boards has blink, button, fade, an analog meter, a Led class, and UART, SPI and I2C examples.
Desktop languages (C, C++) can't use the Board blocks; Generate code says which block to change.
Three more languages, SystemVerilog, Verilog-2001 and VHDL (VHDL-2008), turn the same diagram into hardware. Every block becomes one state of a state machine and takes one clock cycle. Variables are signed 32-bit registers.
| Board | Chip | Clock | Pins you can use |
|---|---|---|---|
| Digilent Nexys A7-100T | Artix-7 XC7A100T | 100 MHz | LED0-15, SW0-15, BTNC/U/L/R/D, JA-JD, USB-UART |
| Digilent Arty A7-35 / A7-100 | Artix-7 | 100 MHz | 4 LEDs, 4 switches, 4 buttons, JA-JD, USB-UART |
| Digilent Basys 3 | Artix-7 XC7A35T | 100 MHz | 16 LEDs, 16 switches, 5 buttons, JA-JC, USB-UART |
| Olimex GateMateA1-EVB | GateMate CCGM1A1 | 10 MHz | LED0, BTN0, debug UART |
| Cologne Chip GateMate A1 evaluation board | GateMate CCGM1A1 | 10 MHz | LED0 only |
Pins are fixed when the design is built, so a pin must be a number or a name: LED0, SW3, BTNC, BTN0, JA1. A pin the board does not have is an error that lists the pins it has. A pin cannot be both read and written.
Whole numbers. Arithmetic wraps at 32 bits; / and % truncate toward zero, and dividing by 0 gives 0. Run uses double numbers, so 5 / 2 is 2.5 in Run and 2 on the FPGA. Not supported yet: classes, Input, Analog Read, SPI, I2C and text in variables (text works in Print).
Build and Upload. Artix-7: Vivado in batch mode, or the open-source flow (yosys, nextpnr-xilinx, Project X-Ray), chosen in Settings. GateMate: yosys, nextpnr-himbaechel, gmpack. Upload uses Vivado or openFPGALoader. The pin constraints are in the first comment of the file, and -o on the command line also writes a .xdc or .ccf file.
Tested: simulation against Run, and synthesis with open-source tools. Not tested: Vivado, openXC7 and real boards.
Examples are in File > Open Example > FPGA Boards.
| Ctrl+N | New program |
| Ctrl+Shift+N | New project |
| Ctrl+O | Open program |
| Ctrl+S / Ctrl+Shift+S | Save / Save As |
| Ctrl+A | Select all blocks |
| Delete | Delete the selected blocks |
| Ctrl+G | Group selected blocks into a class |
| F5 / Shift+F5 | Run / Stop |
| F7 | Generate code |
| Mouse wheel | Zoom the diagram in or out toward the pointer (25% to 300%) |
| Shift+wheel / Ctrl+wheel | Scroll sideways / up and down |
| Middle button + drag | Move the canvas (also when you start on a block) |
| Ctrl+= / Ctrl+- | Zoom in / out |
| Ctrl+0 / Ctrl+9 | Actual size (100%) / fit the diagram in the window |
| Ctrl+K | Git commit |
| F1 | This guide |
| Shift+click, drag a rectangle | Select several blocks |
| Right-click a block | Block menu (edit, View source code, delete ...) |
Code fields, the code window and the commit message editor use Vim keys (turn them off in Settings). Text starts in insert mode; Esc switches to normal mode.
h j k l, w b e, 0 ^ $, gg G, %, f ti a I A o O, x, dd, cw, yy, p, u, Ctrl+R, .v, V; search: /text, n N, *:w accept/save, :q close, :wq, :s/a/b/g, :make compile and run (code window), :vim open in real Vim