- labs/src/: 59 lab scripts covering OA API (Ch2-Ch25 + extras) - All C++ references removed, oapy-only documentation - labs/tools/: debug and test utilities - labs/run_lab.sh: lab runner with LD_PRELOAD and env setup
137 lines
5.0 KiB
Python
137 lines
5.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Lab 13-4: OccProducer — Occurrence Producer
|
|
Demonstrates the oaOccProducer class for producing occurrence-domain objects.
|
|
The producer generates occurrence objects for a given root occurrence.
|
|
|
|
|
|
Key concepts:
|
|
- Constructing oaOccProducer with a root occurrence
|
|
- Calling produce() to generate occurrence objects
|
|
- Setting a new occurrence with setOccurrence() and producing again
|
|
|
|
Note: The oapy bindings do not have Python director support for process*()
|
|
virtuals, so we demonstrate the base API pattern.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
|
|
__dir__ = os.path.dirname(os.path.abspath(__file__))
|
|
sys.path.insert(0, os.path.join(__dir__, "..", "..", "build"))
|
|
sys.path.insert(0, __dir__)
|
|
|
|
from oapy._oa import _base, _dm, _design
|
|
from utils import init_oa, make_oa_name, make_oa_string, get_namespace, create_lib
|
|
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("Lab 13-4: OccProducer — Occurrence Producer")
|
|
print("=" * 60)
|
|
|
|
init_oa()
|
|
ns = get_namespace("native")
|
|
|
|
import shutil
|
|
LIB_DIR = os.path.join(__dir__, "..", "data", "lab13_4_dir")
|
|
if os.path.exists(LIB_DIR):
|
|
shutil.rmtree(LIB_DIR)
|
|
|
|
sn_lib, lib = create_lib("lab13_4_lib", LIB_DIR)
|
|
|
|
vt = _dm.oaViewType.find(make_oa_string("schematic"))
|
|
sv_name = make_oa_name(ns, "schematic")
|
|
bv_enum = _design.oaBlockDomainVisibilityEnum
|
|
ps_enum = _design.oaPlacementStatusEnum
|
|
xform = _base.oaTransform(0, 0, _base.oaOrient(_base.oaOrientEnum.oacR0))
|
|
|
|
# ── Build hierarchy: top → sub (2 inst) → leaf (2 inst each) ──
|
|
print("\n─── Building Hierarchy ───")
|
|
leaf_view = _design.oaDesign.open(sn_lib, make_oa_name(ns, "leaf"), sv_name, vt, 'w')
|
|
_design.oaBlock.create(leaf_view, True)
|
|
leaf_view.save()
|
|
leaf_view.close()
|
|
|
|
leaf_master = _design.oaDesign.open(sn_lib, make_oa_name(ns, "leaf"), sv_name, vt, 'r')
|
|
sub_view = _design.oaDesign.open(sn_lib, make_oa_name(ns, "sub"), sv_name, vt, 'w')
|
|
sub_blk = _design.oaBlock.create(sub_view, True)
|
|
_design.oaScalarInst.create(sub_blk, leaf_master, make_oa_name(ns, "subLeaf1"),
|
|
xform, _base.oaParamArray(0),
|
|
_design.oaBlockDomainVisibility(bv_enum.oacInheritFromTopBlock),
|
|
_design.oaPlacementStatus(ps_enum.oacUnplacedPlacementStatus))
|
|
_design.oaScalarInst.create(sub_blk, leaf_master, make_oa_name(ns, "subLeaf2"),
|
|
xform, _base.oaParamArray(0),
|
|
_design.oaBlockDomainVisibility(bv_enum.oacInheritFromTopBlock),
|
|
_design.oaPlacementStatus(ps_enum.oacUnplacedPlacementStatus))
|
|
sub_view.save()
|
|
leaf_master.close()
|
|
|
|
sub_master = _design.oaDesign.open(sn_lib, make_oa_name(ns, "sub"), sv_name, vt, 'r')
|
|
top_view = _design.oaDesign.open(sn_lib, make_oa_name(ns, "top"), sv_name, vt, 'w')
|
|
top_blk = _design.oaBlock.create(top_view, True)
|
|
_design.oaScalarInst.create(top_blk, sub_master, make_oa_name(ns, "topSub1"),
|
|
xform, _base.oaParamArray(0),
|
|
_design.oaBlockDomainVisibility(bv_enum.oacInheritFromTopBlock),
|
|
_design.oaPlacementStatus(ps_enum.oacUnplacedPlacementStatus))
|
|
_design.oaScalarInst.create(top_blk, sub_master, make_oa_name(ns, "topSub2"),
|
|
xform, _base.oaParamArray(0),
|
|
_design.oaBlockDomainVisibility(bv_enum.oacInheritFromTopBlock),
|
|
_design.oaPlacementStatus(ps_enum.oacUnplacedPlacementStatus))
|
|
top_view.save()
|
|
print(" [PASS] 3-level hierarchy created")
|
|
|
|
# ── oaOccProducer: construct and produce ──
|
|
print("\n─── oaOccProducer ───")
|
|
top_occ = top_view.getTopOccurrence()
|
|
assert top_occ is not None
|
|
|
|
prod = _design.oaOccProducer(top_occ)
|
|
assert prod is not None
|
|
print(f" [PASS] oaOccProducer constructed with root occ")
|
|
|
|
prod.produce()
|
|
print(" [PASS] produce() called on top occurrence")
|
|
|
|
# ── setOccurrence: produce from a different occurrence ──
|
|
print("\n─── setOccurrence to sub-level ──")
|
|
sTopSub1 = _base.oaSimpleName(ns, "topSub1")
|
|
oi_topSub1 = _design.oaOccInst.find(top_occ, sTopSub1)
|
|
assert oi_topSub1 is not None
|
|
|
|
sub1_master = oi_topSub1.getMasterOccurrence(True)
|
|
assert sub1_master is not None
|
|
|
|
# Set the producer to sub1's master occurrence
|
|
prod.setOccurrence(sub1_master)
|
|
prod.produce()
|
|
print(" [PASS] produce() called on topSub1's master occurrence")
|
|
|
|
# Verify we can access the inner instances
|
|
sSubLeaf = _base.oaSimpleName(ns, "subLeaf1")
|
|
oi_subLeaf = _design.oaOccInst.find(sub1_master, sSubLeaf)
|
|
assert oi_subLeaf is not None
|
|
print(" [PASS] Found subLeaf1 inside topSub1's master")
|
|
|
|
# ── CalcVM ──
|
|
print("\n─── Design size ──")
|
|
vm = top_view.calcVMSize()
|
|
assert vm > 0
|
|
print(f" [PASS] VM size: {vm}")
|
|
|
|
# ── Cleanup ──
|
|
print("\n─── Cleanup ───")
|
|
top_view.close()
|
|
sub_master.close()
|
|
lib.close()
|
|
shutil.rmtree(LIB_DIR, ignore_errors=True)
|
|
|
|
print("\n" + "=" * 60)
|
|
print("✅ Lab 13-4 (OccProducer) PASSED!")
|
|
print("=" * 60)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
os._exit(0)
|