ruverta
Rust to Verilog: Very Simple Verilog Builder
English | 日本語
What is ruverta for?
Ruverta (/rʊˈvɛrtə/) is a library for easily creating IP generators in Rust.
- Flexible Generation : The abstraction of modules using SystemVerilog parameters is not very flexible. Create highly flexible IPs using Rust + Ruverta.
- Minimalist Syntax : Supports only simple subset of SystemVerilog which is enough for most cases.
- Variables: Only
logicis available. Noregorwire. - Combinational circuits: Only
always_combis available. Noassign. - Sequential circuits: Only
always_ffis available. Noalways.
- Variables: Only
- Human Friendly : Builder API is designed to be easy to use. Additionally, the generated SystemVerilog code is readable. You don't have to struggle with a bunch of meaningless variable names.
Table of Contents
Crash Course: Blink
- Init rust project and add ruverta
- Write code
Parameter "div"
use ;
- Generate Verilog
module blink (
input logic clk,
input logic rst,
output logic led
);
logic [23:0] cnt;
always_ff @(posedge clk) begin
if (!rstn) cnt <= 0;
else cnt <= cnt + 1;
end
always_comb led = cnt[23];
endmodule
Features
Ruverta is aimed at generating branch modules.
- core: Only wrapper of system verilog.
- atom: Support API to generate single clock domain module.
- cros: Add support to generate cross clock domain module.
- top: Support API to generate top module. Multiple clocks and resets can be specified.
Basic API
use ;
module test_module #(
parameter BIT = 8
) (
input logic clk,
input logic rstn,
input logic [ 7:0] in0,
input logic [ 7:0] in1,
output logic [ 7:0] out
);
always_comb
out = in0 + in1;
always_ff @(posedge clk)
begin
a <= b;
end
endmodule;
Input/Output Ports
.input(name, width).output(name, width).inout(name, width)
Parameters
.param(name, default_value).lparam(name, value)
Wires
.logic(name, bit, len)
Instances
.instant(inst: Instant)
Combinational Circuits
.always_comb(stmt: Stmt)
Stmt is a class representing a statement.
Sequential Circuits
.always_ff(Sens, Stmt)
Sens is a class representing a sensitivity list.
.posedge(wire_name).negedge(wire_name).bothedge(wire_name)
Verilog Generation
Generate Verilog with .verilog(). Since it returns Vec<String>, use .join("\n") to concatenate.
Extended API
Extend the builder methods of Module to easily construct various circuits.
DFF
When implementing sequential circuits, it is recommended to use the DFF extension instead of always_ff.
DFF has several usage patterns depending on the clock and reset settings.
- clock edge: posedge / negedge / bothedge
- reset edge: positive / negative
- reset timing: sync / async
Currently, only the following patterns are supported.
| clock edge | reset logic | reset timing | |
|---|---|---|---|
DFF::sync |
posedge | negative | sync |
DFF::async |
posedge | negative | async |
Clock and reset signals are taken from the module's default clock and reset.
use ;
new
.input
.input
.input
.input
.output
.add;
Comb
When implementing combinational circuits, it is recommended to use the Comb extension instead of always_comb.
Since it always requires a default, there are no omissions in case distinctions.
use ;
new
.input
.input
.input
.input
.output
.output
.add;
StateMachine
Construct a state machine with a single state variable.
use ;
const INIT: &str = "INIT";
const FUGA: &str = "FUGA";
new
.input
.input
.input
.add;
Stream
FIFO
Bus API
| Rust | Verilog | Test | |
|---|---|---|---|
| AXILiteSlave | axi_lite_slave.rs | axi_lite_slave.sv | axi_lite_slave_tb.sv |
| PicoSlave | pico_slave.rs |
use ;
new
.input
.input
.add;
- AXI Lite Slave
- Pico Slave
Test
Tests are located under tests.
will output sv files under tests/verilog/.
Running make will launch gtkwave.
??? is the name of the test case.