A Python library for programmatically generating HDL (Hardware Description Language) code including Verilog, SystemVerilog, and VHDL.
- Intuitive context manager-based API
- Support for multiple HDL languages
- Clean, readable HDL output generation
- Python-native approach to hardware description
pip install rtlgen
from rtlgen import CodeGen
# Create a Verilog generator
gen = CodeGen("output.v", "verilog")
# Create a module with ports and logic
with gen.Module("example_counter") as m:
# Define module parameters
with m.ParameterRegion() as params:
params.Parameter("WIDTH", 8)
# Define ports
with m.PortRegion() as ports:
ports.Input("clk")
ports.Input("rst_n")
ports.Output("count", "WIDTH")
# Define internal logic
with m.LogicRegion() as lr:
# Create signals
counter = lr.Signal("counter", "WIDTH")
# Create an always block for synchronous logic
with lr.BeginEnd("always @(posedge clk or negedge rst_n)"):
with lr.IfElse("!rst_n"):
lr.Assign(counter, 0, blocking=True)
with lr.Else():
lr.Assign(counter, counter + 1, blocking=True)
# Continuous assignment
lr.Assign("count", counter)
# file auto written when gen.Module out of context
Here are examples showing RTLGen Python code and the resulting Verilog output:
Python Code | Generated Verilog |
---|---|
from rtlgen import CodeGen
gen = CodeGen("module.v", "verilog")
with gen.Module("test_module") as m:
with m.LogicRegion() as lr:
signal = lr.Signal("test_signal", 8)
single_bit = lr.Signal("single_bit") |
module test_module (
);
// Logic
reg [7:0] test_signal;
reg single_bit;
endmodule |
Python Code | Generated Verilog |
---|---|
with gen.Module("assign_module") as m:
with m.LogicRegion() as lr:
signal_a = lr.Signal("a", 8)
signal_b = lr.Signal("b", 8)
# Signal to signal assignment
lr.Assign(signal_a, signal_b)
# Constant assignment
lr.Assign(signal_a, 42) |
module assign_module (
);
// Logic
reg [7:0] a;
reg [7:0] b;
assign a = b;
assign a = 8'd42;
endmodule |
Python Code | Generated Verilog |
---|---|
with gen.Module("conditional_module") as m:
with m.LogicRegion() as lr:
clk = lr.Signal("clk")
reset = lr.Signal("reset")
counter = lr.Signal("counter", 8)
with lr.BeginEnd("always @(posedge clk)"):
with lr.IfElse("reset"):
lr.Assign(counter, 0, blocking=True)
with lr.Else():
lr.Assign(counter, counter + 1, blocking=True) |
module conditional_module (
);
// Logic
reg clk;
reg reset;
reg [7:0] counter;
always @(posedge clk) begin
if (reset) begin
counter = 0;
end else begin
counter = counter + 1;
end
end
endmodule |
Python Code | Generated Verilog |
---|---|
with gen.Module("top_module") as m:
with m.LogicRegion() as lr:
clk = lr.Signal("clk")
reset = lr.Signal("reset")
data_out = lr.Signal("data_out", 8)
# Create connections
clk_conn = lr.ConnectPair("clk", clk)
rst_conn = lr.ConnectPair("reset", reset)
out_conn = lr.ConnectPair("result", data_out)
# Instantiate a module
lr.InitModule("counter", "counter_inst",
[clk_conn, rst_conn, out_conn]) |
module top_module (
);
// Logic
reg clk;
reg reset;
reg [7:0] data_out;
counter #() counter_inst (
.clk(clk),
.reset(reset),
.result(data_out)
);
endmodule |
- Verilog
- SystemVerilog
- VHDL
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.