| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
A Formal Modeling Framework for JEDEC DRAM Standards using Timed Petri Nets
DRAMpyML is a modeling approach for DRAM standards using timed Petri nets, developed by Fraunhofer IESE and Normal Computing. It addresses the challenges emerging from formalizing increasingly complex DRAM protocols defined in JEDEC standards (DDR2-4, LPDDR2-4, GDDR5-6, HBM2).
Like DRAMml, DRAMpyML uses timed Petri nets to capture structure and constraints. Unlike DRAMml, DRAMpyML leverages Python for greater flexibility and direct executability, further pushing adoption amongst industry practitioneers.
DRAMpyML releases ground truth Petri nets for all but the newest JEDEC standards to avoid polluting auto-formalization benchmarks with data that could be used to train models on recent standards. This ensures that:
This policy supports rigorous evaluation of automated formalization approaches while maintaining a clean benchmark suite.
DRAMpyML leverages rustworkx (rx), a high-performance graph library, to construct and manipulate Petri nets. The framework builds timed Petri nets iteratively by adding places, transitions, and arcs with associated timing constraints.
import rustworkx as rx
from drampyml.components.petri_net import Place, Transition, ResetArc
g = rx.PyDiGraph()
for rank in range(numberOfRanks):
for bank in range(numberOfBanks):
# ACTIVE place with an associated bank coordinate:
p_active = g.add_node(Place(ACTIVE, bank_coord))
# PREA transition with an associated rank coordinate:
t_prea = g.add_node(Transition(PREA, rank_coord))
# Reset arc from ACTIVE to PREA:
g.add_edge(p_active, t_prea, ResetArc())In each level of hierarchy, the respective places, transitions, and arcs are added to the graph. The timing dependencies are similarly defined at this level.
DRAMpyML supports multiple arc types to model different Petri net semantics, as defined in petri_net.py:
Standard Arc (Arc):
Inhibitor Arc (InhibitorArc):
Reset Arc (ResetArc):
Timed Arc (TimedArc):
Custom Arc (CustomArc):
Timing constraints are applied using the CommandTimingConstraint class from command_timing.py. Due to the large number of possible command transitions, timing arcs are generated in a second step:
from drampyml.constraints.command_timing import CommandTimingConstraint
CommandTimingConstraint(
intra_bank, [ACT], [RD, WR, RDA, WRA], tRCD
)This example applies the timing constraint tRCD between the ACT command and the column commands RD, RDA, WR, and WRA for a specific memory bank. The commands are interpreted as a Cartesian product of the two lists ({ACT} × {RD, RDA, WR, WRA}), generating a timing arc for every combination.
Timing constraints are defined using:
DRAMpyML can generate both timed and untimed valid command sequences using the unrolling algorithm in unroll.py and transitions.py.
The unroll_petri_net function builds a reachability graph via breadth-first search (BFS):
from drampyml.algorithms.unroll import unroll_petri_net
# Generate reachability graph
graph, max_depth = unroll_petri_net(petri_net, numberOfBanks)The explore_next_transitions function generates k-step command sequences:
from drampyml.algorithms.transitions import explore_next_transitions
# Generate all valid k-step command sequences with timing information
paths = explore_next_transitions(
petri_net,
k_max=5,
include_timings=True
)Each path is a tuple of CommandTransition objects containing:
Command sequences can be used to compute similarity between two Petri nets using the Jaccard index:
J(A, B) = |A ∩ B| / |A ∪ B|
Where:
This metric quantifies how similar two DRAM models are in terms of their legal command sequences, useful for:
DRAMpyML organizes specifications into modular components:
drampyml/ ├── algorithms/ # Petri net analysis algorithms │ ├── unroll.py # Reachability graph generation │ ├── transitions.py # Command sequence exploration │ └── state.py # State management utilities ├── command_sets/ # Command sets for each standard │ ├── ddr2.py | ... ├── components/ # Core Petri net components │ ├── petri_net.py # Petri net classes (Place, Transition, Arc types) │ └── standard.py # Standard wrapper class ├── constraints/ # Constraint definitions │ ├── command_timing.py # Timing constraint generation │ ├── naw.py # Bank group constraints │ └── queries.py # Coordinate selectors ├── memspecs/ # Complete memory specifications │ ├── ddr2.py # Combines timing + structural params | ... ├── standards/ # Petri net generators for each standard │ ├── ddr2.py | ... └── timing_params/ # Timing parameters only | ├── ddr2.py # e.g., tRCD, tRAS, tRP, tRC, tRFC | ...
This modular structure allows easy comparison of standards and parameter variation studies.
uv is a fast Python package installer and resolver. It's the recommended way to install DRAMpyML.
# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone the repository
git clone https://github.com/your-org/drampyml.git
cd DRAMBench
# Create a virtual environment and install dependencies
uv sync
# Activate the virtual environment
source .venv/bin/activate # On Unix/macOS
# or
.venv\Scripts\activate # On WindowsThe uv sync command will:
# Clone the repository
git clone https://github.com/your-org/drampyml.git
cd DRAMBench
# Create and activate a virtual environment
python3.13 -m venv .venv
source .venv/bin/activate # On Unix/macOS
# Install the package
pip install -e .from drampyml.standards.ddr3 import ddr3
from drampyml.memspecs.ddr3 import DDR3_1600
from drampyml.algorithms.transitions import explore_next_transitions
# Create DDR3 Petri net
petri_net = ddr3(DDR3_1600)
# Generate all valid 4-step command sequences with timing
paths = explore_next_transitions(
petri_net,
k_max=4,
include_timings=True
)
print(f"Found {len(paths)} valid 4-step command sequences")
# Example path: ACT → [tRCD] RD → [tCCD] RD → [tRTP] PRE
for path in list(paths)[:5]:
cmd_str = " → ".join(
f"[{ct.timing}] {ct.command}" if ct.timing else str(ct.command)
for ct in path
)
print(cmd_str)Petri nets can be exported to DOT format or rendered as images:
# Export to DOT file
petri_net.write_dot("ddr3_model.dot")
# Render as PNG/SVG
petri_net.write_img("ddr3_model.png", format="png")Visualization features:
Contributions are welcome! Please open issues or pull requests on the GitHub repository.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Developed by Fraunhofer IESE and Normal Computing as part of research on formal verification of memory systems.
For questions or support, please open an issue on the GitHub repository.
| Back | FazBrowse Home | New Git URL |