An intuitive Python based HDL code generator for Verilog/SystemVerilog and VHDL.
Project description
HDLGen
A Python library for programmatically generating HDL (Hardware Description Language) code including Verilog, SystemVerilog, and VHDL.
Features
- Intuitive context manager-based API
- Support for multiple HDL languages
- Clean, readable HDL output generation
- Python-native approach to hardware description
Installation
pip install hdlgen
Quick Start
from rtlgen import CodeGen
# Create a Verilog generator
gen = CodeGen("conditional_module.v", "verilog")
# Create a module with ports and logic
with gen.Module("conditional_module") as m:
# Define internal logic
with m.LogicRegion() as lr:
# Create signals
clk = lr.Signal("clk")
reset = lr.Signal("reset")
counter = lr.Signal("counter", 8)
# Create an always block for synchronous logic
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)
# file auto written when gen.Module out of context
Side-by-Side Examples
Here are examples showing HDLGen Python code and the resulting HDL output for Verilog, SystemVerilog, and VHDL.
Module and Signal Declaration
Verilog
| Python Code (Verilog) | 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
|
SystemVerilog
| Python Code (SystemVerilog) | Generated SystemVerilog |
|---|---|
from rtlgen import CodeGen
gen = CodeGen("module.sv", "systemverilog") # Target SystemVerilog
with gen.Module("test_module") as m:
with m.LogicRegion() as lr:
# SystemVerilog typically uses 'logic' type
test_signal = lr.Signal("test_signal", 8, type="logic")
single_bit = lr.Signal("single_bit", type="logic")
|
module test_module (
);
// Logic
logic [7:0] test_signal; // 'logic' type
logic single_bit; // 'logic' type
endmodule
|
VHDL
| Python Code (VHDL) | Generated VHDL |
|---|---|
from rtlgen import CodeGen
gen = CodeGen("module.vhd", "vhdl") # Target VHDL
gen.Library("ieee")
gen.Use("ieee.std_logic_1164.all")
with gen.Module("test_module") as m:
# In VHDL, signals are part of an architecture
with m.Architecture("rtl") as arch:
test_signal = arch.Signal("test_signal", "std_logic_vector(7 downto 0)")
single_bit = arch.Signal("single_bit", "std_logic")
|
library ieee;
use ieee.std_logic_1164.all;
entity test_module is
-- Ports would be defined here if any
end entity test_module;
architecture rtl of test_module is
-- Signals
signal test_signal : std_logic_vector(7 downto 0);
signal single_bit : std_logic;
begin
-- Concurrent statements or processes
end architecture rtl;
|
If-Else Conditions
Verilog
| Python Code (Verilog) | Generated Verilog |
|---|---|
from rtlgen import CodeGen
gen = CodeGen("conditional_module.v", "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)"): # Synchronous block
with lr.IfElse("reset"):
lr.Assign(counter, 0, blocking=False) # Non-blocking
with lr.Else():
lr.Assign(counter, counter + 1, blocking=False) # Non-blocking
|
module conditional_module (
);
// Logic
reg clk;
reg reset;
reg [7:0] counter;
always @(posedge clk) begin
if (reset) begin
counter <= 0; // Non-blocking assignment
end else begin
counter <= counter + 1; // Non-blocking assignment
end
end
endmodule
|
SystemVerilog
| Python Code (SystemVerilog) | Generated SystemVerilog |
|---|---|
from rtlgen import CodeGen
gen = CodeGen("conditional_module.sv", "systemverilog")
with gen.Module("conditional_module") as m:
with m.LogicRegion() as lr:
clk = lr.Signal("clk", type="logic")
reset = lr.Signal("reset", type="logic")
counter = lr.Signal("counter", 8, type="logic")
# Using always_ff for synchronous logic
with lr.AlwaysFF("@(posedge clk or posedge reset)") as ff_block: # Async reset
with ff_block.If("reset"): # Active-high reset
ff_block.Assign(counter, "\'0\'", blocking=False) # SV literal assignment
with ff_block.Else():
ff_block.Assign(counter, counter + 1, blocking=False)
|
module conditional_module (
);
// Logic
logic clk;
logic reset;
logic [7:0] counter;
always_ff @(posedge clk or posedge reset) begin // Assuming asynchronous reset
if (reset) begin
counter <= \'0\';
end else begin
counter <= counter + 1;
end
end
endmodule
|
VHDL
| Python Code (VHDL) | Generated VHDL |
|---|---|
from rtlgen import CodeGen
gen = CodeGen("conditional_module.vhd", "vhdl")
gen.Library("ieee")
gen.Use("ieee.std_logic_1164.all")
gen.Use("ieee.numeric_std.all") # For arithmetic
with gen.Module("conditional_module") as m:
# Define Entity Ports
clk = m.Port("clk_i", "in", "std_logic")
reset = m.Port("reset_i", "in", "std_logic")
counter_out = m.Port("counter_o", "out", "std_logic_vector(7 downto 0)")
with m.Architecture("rtl") as arch:
# Internal signal for counter logic, using 'unsigned' for arithmetic
counter_reg = arch.Signal("counter_s", "unsigned(7 downto 0)")
with arch.Process([clk, reset]) as p: # Process sensitive to clk and reset
with p.If(f"{reset} = \'1\'"): # Asynchronous reset
p.Assign(counter_reg, "(others => \'0\')")
with p.ElsIf(f"rising_edge({clk})"):
p.Assign(counter_reg, f"{counter_reg} + 1")
# Assign internal signal to output port
arch.Assign(counter_out, f"std_logic_vector({counter_reg})")
|
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity conditional_module is
port (
clk_i : in std_logic;
reset_i : in std_logic;
counter_o : out std_logic_vector(7 downto 0)
);
end entity conditional_module;
architecture rtl of conditional_module is
signal counter_s : unsigned(7 downto 0);
begin
process (clk_i, reset_i)
begin
if reset_i = \'1\' then
counter_s <= (others => \'0\');
elsif rising_edge(clk_i) then
counter_s <= counter_s + 1;
end if;
end process;
counter_o <= std_logic_vector(counter_s);
end architecture rtl;
|
Supported HDL Languages
- Verilog
- SystemVerilog
- VHDL
Contributing
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
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hdlgen-0.0.1.dev1.tar.gz.
File metadata
- Download URL: hdlgen-0.0.1.dev1.tar.gz
- Upload date:
- Size: 22.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c8d6cf3a4f24c88945b0e1b5edc0498d3eaa27790dd61a69296379ac342f230c
|
|
| MD5 |
3147ee7cc44e94a4c2d8a9fff8ae10a4
|
|
| BLAKE2b-256 |
a9f3d1ed3155bda687556b66a9d83867a263b2572958f4ca512c282213690442
|
File details
Details for the file hdlgen-0.0.1.dev1-py3-none-any.whl.
File metadata
- Download URL: hdlgen-0.0.1.dev1-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a10a39e47cb9f13ee5821c4112a7de7bef79b32cff65a9c69fcfcca9afe5d2cd
|
|
| MD5 |
4faf838d9693554fab7a61c4c5bab3e7
|
|
| BLAKE2b-256 |
bc85a86b9e479fcae360b9357172fd2e64a63eec2931a6238290024a1a80ead9
|