Skip to main content

A Python-based SystemVerilog code generator using context managers

Project description

Pyrilog

一个基于 Python 上下文管理器的 SystemVerilog 代码生成工具。使用简洁的 Python 语法生成结构化的硬件描述语言代码。

特性

  • 🏗️ 层次化设计: 基于上下文管理器的嵌套块结构
  • 🎯 简洁 API: 使用 v_ 前缀的短别名,代码更加简洁
  • 🔄 case 语句支持: 支持单语句和多语句两种 case 语句写法
  • 🧩 模块化: 支持参数化模块、实例化、多维数组等
  • 🚀 现代语法: 生成 SystemVerilog always_ffalways_comb 语法

安装

pip install pyrilog

快速开始

基本模块定义

from pyrilog import *

with v_gen() as gen:
    with v_module("counter"):
        # 参数定义
        v_param("WIDTH", "8")
        
        # 端口定义
        v_input("clk")
        v_input("rst_n") 
        v_input("data_in", "WIDTH")
        v_output("count", "WIDTH", None, "reg")

print(gen.generate())

生成的 SystemVerilog 代码:

module counter #(
parameter WIDTH = 8
) (
input clk,
input rst_n,
input [WIDTH-1:0] data_in,
output reg [WIDTH-1:0] count
);
endmodule

时序逻辑 - 计数器

from pyrilog import *

with v_gen() as gen:
    with v_module("counter"):
        v_param("WIDTH", "8")
        v_input("clk")
        v_input("rst_n")
        v_output("count", "WIDTH", None, "reg")
        
        # SystemVerilog always_ff 块  
        with v_always_ff("clk", "rst_n"):
            with v_if("!rst_n"):
                v_body("count <= '0;")
            with v_else():
                v_body("count <= count + 1'b1;")

with open("counter.sv", "w") as f:
    f.write(gen.generate())

Case 语句 - ALU 设计

Pyrilog 支持两种 case 语句写法:

1. 单语句模式

from pyrilog import *

with v_gen() as gen:
    with v_module("simple_alu"):
        v_input("opcode", 3)
        v_input("a", 8)
        v_input("b", 8) 
        v_output("result", 8, None, "reg")
        
        with v_always_comb():
            with v_case("opcode"):
                v_case_item("3'b000", "result = a + b;")
                v_case_item("3'b001", "result = a - b;")
                v_case_item("3'b010", "result = a & b;")
                v_case_default("result = 8'h00;")

print(gen.generate())

2. 多语句模式(使用上下文管理器)

from pyrilog import *

with v_gen() as gen:
    with v_module("complex_alu"):
        v_input("clk")
        v_input("rst_n")
        v_input("opcode", 4)
        v_input("a", 16)
        v_input("b", 16)
        v_output("result", 16, None, "reg")
        v_output("valid", 1, None, "reg")
        v_output("overflow", 1, None, "reg")
        
        with v_always_ff("clk", "rst_n"):
            with v_if("!rst_n"):
                v_body("result <= 16'h0000;")
                v_body("valid <= 1'b0;")
                v_body("overflow <= 1'b0;")
            with v_else():
                with v_case("opcode"):
                    # 单语句 case
                    v_case_item("4'b0000", "result <= a + b;")
                    v_case_item("4'b0001", "result <= a - b;")
                    
                    # 多语句 case,使用 with 上下文管理器
                    with v_case_item("4'b0010"):  # 位与运算,带有效信号
                        v_body("result <= a & b;")
                        v_body("valid <= 1'b1;")
                        v_body("overflow <= 1'b0;")
                    
                    with v_case_item("4'b0011"):  # 位或运算,带溢出检测
                        v_body("result <= a | b;")
                        v_body("valid <= 1'b1;")
                        v_body("overflow <= (a[15] | b[15]) & !result[15];")
                    
                    # 默认情况
                    v_case_default("result <= 16'h0000;")
                
                v_body("valid <= 1'b1;")  # case 外的公共语句

print(gen.generate())

生成的 SystemVerilog 代码:

module complex_alu (
input clk,
input rst_n,
input [3:0] opcode,
input [15:0] a,
input [15:0] b,
output reg [15:0] result,
output reg valid,
output reg overflow
);
always_ff @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
result <= 16'h0000;
valid <= 1'b0;
overflow <= 1'b0;
end
else begin
case (opcode)
4'b0000: result <= a + b;
4'b0001: result <= a - b;
4'b0010: begin
result <= a & b;
valid <= 1'b1;
overflow <= 1'b0;
end
4'b0011: begin
result <= a | b;
valid <= 1'b1;
overflow <= (a[15] | b[15]) & !result[15];
end
default: result <= 16'h0000;
endcase
valid <= 1'b1;
end
end
endmodule

多维数组支持

from pyrilog import *

with v_gen() as gen:
    with v_module("memory_array"):
        v_input("clk")
        v_input("addr", 8)
        v_input("wr_data", 32)
        v_output("rd_data", 32, None, "reg")
        
        # 创建二维内存数组:32位宽,256x4 的数组
        v_reg("memory", 32, [256, 4])
        
        # 一维数组:32位宽,16个元素
        v_wire("buffer", 32, 16)

print(gen.generate())

模块实例化

from pyrilog import *

with v_gen() as gen:
    with v_module("cpu_top"):
        v_input("clk")
        v_input("rst_n")
        v_input("instruction", 32)
        v_output("result", 32, None, "wire")
        
        # 实例化 ALU 模块(完整参数)
        v_inst("complex_alu", "alu_inst", 
               {"WIDTH": "32"},  # 参数
               {                 # 端口连接
                   "clk": "clk",
                   "rst_n": "rst_n", 
                   "opcode": "instruction[3:0]",
                   "a": "instruction[31:16]",
                   "b": "instruction[15:4]",
                   "result": "result"
               })
        
        # 简化实例化(利用默认参数)
        v_inst("simple_counter", "cnt_inst")  # 无参数、无端口连接
        
        # 部分参数实例化
        v_inst("timer", "timer_inst", ports={"clk": "clk", "rst_n": "rst_n"})

print(gen.generate())

API 参考

核心块结构

  • v_gen(): 顶层生成器
  • v_module(name): 模块定义
  • v_always_ff(clk, rst=None): always_ff 时序逻辑块
  • v_always_comb(): always_comb 组合逻辑块
  • v_if(condition): 条件语句
  • v_else(): else 语句
  • v_case(expression): case 语句

Case 语句

  • v_case_item(value, statement=None): case 项
    • 单语句:v_case_item("3'b001", "result = a + b;")
    • 多语句:with v_case_item("3'b001"): ...
  • v_case_default(statement=None): 默认 case

端口和变量

  • v_input(name, width=1, dimensions=None, var_type=""): 输入端口
  • v_output(name, width=1, dimensions=None, var_type=""): 输出端口
  • v_inout(name, width=1, dimensions=None, var_type=""): 双向端口
  • v_wire(name, width=1, dimensions=None): wire 信号
  • v_reg(name, width=1, dimensions=None): reg 信号

其他功能

  • v_param(name, value): 参数定义
  • v_assign(lhs, rhs): assign 语句
  • v_inst(module_name, inst_name, params, ports): 模块实例化
  • v_body(code): 添加原始代码行

维度格式

支持多种维度表示方法:

# 位宽
v_reg("data", 8)        # [7:0] data
v_reg("data", "WIDTH")  # [WIDTH-1:0] data

# 一维数组
v_reg("mem", 8, 16)     # [7:0] mem[15:0] 
v_reg("mem", 8, [16])   # [7:0] mem[15:0]

# 多维数组  
v_reg("mem", 8, [16, 4]) # [7:0] mem[15:0][3:0]

许可证

本项目采用 MIT 许可证。详情请见 LICENSE 文件。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyrilog-0.2.4.tar.gz (25.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyrilog-0.2.4-py3-none-any.whl (6.9 kB view details)

Uploaded Python 3

File details

Details for the file pyrilog-0.2.4.tar.gz.

File metadata

  • Download URL: pyrilog-0.2.4.tar.gz
  • Upload date:
  • Size: 25.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.15

File hashes

Hashes for pyrilog-0.2.4.tar.gz
Algorithm Hash digest
SHA256 37f8588865cbcf31fc478be2c9270f3729a9b8cf78245b38c9e1f735de140f70
MD5 1d04f39bc5d0b4584474a6b778990614
BLAKE2b-256 f525f16df8da7c4970bb55848b35c691b923a7cfa67aadade591007cd4044435

See more details on using hashes here.

File details

Details for the file pyrilog-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: pyrilog-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 6.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.15

File hashes

Hashes for pyrilog-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 82cdb3554b9ba917dfcde191bfd3f19ecceb969a24b70a2d0d8481c79b7105f8
MD5 802fc558a911606124e0a3d3a0ff8e2b
BLAKE2b-256 81842b152ddc74efaaddfb4d0a587e735d34d6aadf86b5ec9cceb0e42489eb98

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page