Source code for hwt.serializer.xdc.serializer

from itertools import islice
from typing import Union, Tuple

from hwt.constraints import set_max_delay, set_false_path, \
    set_async_reg, get_clock_of, iHdlConstrain
from hwt.hdl.types.bits import Bits
from hwt.pyUtils.arrayQuery import iter_with_last
from hwt.synthesizer.interface import Interface
from hwt.synthesizer.rtlLevel.rtlSyncSignal import RtlSyncSignal
from hwt.synthesizer.rtlLevel.rtlSignal import RtlSignal
from hwt.synthesizer.unit import Unit


[docs]class XdcSerializer(): """ Convert constrains containers to a XDC format (For Xilinx Vivado) """ fileExtension = ".xdc"
[docs] def __init__(self, out): self.out = out
[docs] def _get(self, o: Union[Tuple[Unit, RtlSignal, Interface], iHdlConstrain], only_first=False): """ :param only_first: if true select only first bit from vector, else select whole vector """ if isinstance(o, iHdlConstrain): return self.visit_iHdlConstrain(o) is_reg = False _o = o[-1] if isinstance(_o, RtlSignal): q = "get_cells" for d in _o.drivers: if d._event_dependent_from_branch is not None: is_reg = True elif isinstance(_o, Interface): q = "get_pins" else: raise NotImplementedError(o) w = self.out.write w(q) w(" -hier -filter {NAME =~ */") path = o # [TODO] find out how to make select with ip top module/entity name for last, p in iter_with_last(islice(path, 1, None)): if isinstance(p, Unit): w(p._name) w("_inst") elif isinstance(p, RtlSignal): w(p.name) elif isinstance(p, Interface): w(p._name) else: raise NotImplementedError(p) if not last: w("/") t = _o._dtype if is_reg: w("_reg") if isinstance(t, Bits) and (t.bit_length() > 1 or t.force_vector): # * on end because of Vivado _replica if only_first: w("[0]*") else: w("[*]*") w("}")
[docs] def visit_get_clock_of(self, o: get_clock_of): w = self.out.write if isinstance(o.obj[-1], RtlSyncSignal): w("get_clocks -of [") self._get(o.obj) w("]") else: raise NotImplementedError()
[docs] def visit_iHdlConstrain(self, o): visitFn = getattr(self, "visit_" + o.__class__.__name__, None) if visitFn is None: return o.to_xdc(self, o) else: return visitFn(o)
[docs] def visit_HdlConstraintList(self, o_list): return [self.visit_iHdlConstrain(o) for o in o_list]
[docs] def visit_set_async_reg(self, o: set_async_reg): w = self.out.write w("set_property ASYNC_REG TRUE [") self._get(o.sig) w("]\n")
[docs] def visit_set_false_path(self, o: set_false_path): w = self.out.write w("set_false_path") if o.start is not None: w(" -from [") self._get(o.start) w("]") if o.end is not None: w(" -to [") self._get(o.end) w("]") w("\n")
[docs] def visit_set_max_delay(self, o: set_max_delay): w = self.out.write w("set_max_delay -from [") self._get(o.start) w("] -to [") self._get(o.end) w("]") if o.datapath_only: w(" -datapath_only") w(f" {o.time_ns:f}\n")