Quickstart¶
This guide will get you up and running with the Zuspec SystemVerilog backend in 5 minutes.
Installation¶
Install from PyPI:
pip install zuspec-be-sv zuspec-dataclasses
Or for development:
git clone https://github.com/zuspec/zuspec-be-sv
cd zuspec-be-sv
pip install -e ".[dev]"
Basic Example¶
Let’s create a simple counter and generate SystemVerilog:
import zuspec.dataclasses as zdc
from zuspec.be.sv import SVGenerator
from pathlib import Path
@zdc.dataclass
class Counter(zdc.Component):
"""Simple up-counter with reset."""
clock : zdc.bit = zdc.input()
reset : zdc.bit = zdc.input()
count : zdc.bit32 = zdc.output()
@zdc.sync(clock=lambda s:s.clock, reset=lambda s:s.reset)
def _count(self):
"""Increment counter each clock cycle."""
if self.reset:
self.count = 0
else:
self.count += 1
# Build the intermediate representation
factory = zdc.DataModelFactory()
ctxt = factory.build(Counter)
# Generate SystemVerilog
output_dir = Path("sv_output")
generator = SVGenerator(output_dir)
sv_files = generator.generate(ctxt)
print(f"Generated: {sv_files[0]}")
Generated SystemVerilog¶
The above code generates a SystemVerilog module like:
module Counter(
input logic clock,
input logic reset,
output logic [31:0] count
);
always @(posedge clock or posedge reset) begin
if (reset) begin
count <= 0;
end else begin
count <= count + 1;
end
end
endmodule
Key Concepts¶
SVGenerator¶
The SVGenerator class is the main entry point for code generation.
Constructor parameters:
output_dir: Path where SystemVerilog files will be writtendebug_annotations: Enable source location comments (default: False)
generator = SVGenerator(
output_dir=Path("output"),
debug_annotations=True # Add source file comments
)
Clocked Processes¶
Methods decorated with @zdc.sync become always blocks:
@zdc.sync(clock=lambda s:s.clock, reset=lambda s:s.reset)
def _behavior(self):
if self.reset:
self.state = 0
else:
self.state += 1
Generates:
always @(posedge clock or posedge reset) begin
if (reset) begin
state <= 0;
end else begin
state <= state + 1;
end
end
Async Processes¶
Methods decorated with @zdc.process become initial blocks with timing control:
@zdc.process
async def _stimulus(self):
for i in range(10):
self.data = i
await self.posedge(self.clock)
Generates:
initial begin
for (int i = 0; i < 10; i++) begin
data = i;
@(posedge clock);
end
end
Next Steps¶
Learn about Features - parameterization, bundles, interfaces
Browse Examples - complete component examples
Read the API Reference - full API reference