Source code for hwtLib.abstract.busStaticRemap

from hwt.code import SwitchLogic, Concat
from hwt.hdl.types.bits import HBits
from hwt.hwModule import HwModule
from hwt.hwParam import HwParam
from hwt.math import inRange, isPow2
from hwt.pyUtils.typingFuture import override


[docs] class BusStaticRemap(HwModule): """ Abstract class for component which remaps memory regions on bus interfaces :ivar ~.MEM_MAP: list of tuples (addr_from, size, addr_to) for each memory region on second interface :ivar ~.m: slave interface of first HwIO class where master should be connected :ivar ~.s: slave interface of second HwIO class where master slave be connected """ @override def hwConfig(self): self.MEM_MAP = HwParam([])
[docs] def _normalize_mem_map(self, mem_map): assert mem_map, "This would mean that second interface is entirely disconnected" # sort by addr from input interface mem_map = sorted(mem_map, key=lambda x: x[0]) # assert the mapped segments are not overlapping on input interface last_end = 0x0 for (offset, size, _) in mem_map: assert offset >= 0, offset assert size > 0, size assert offset >= last_end last_end = offset + size return mem_map
[docs] def translate_addr_val(self, mem_map, addr: int): for (offset_in, size, offset_out) in mem_map: if inRange(addr, offset_in, offset_in + size): return addr - (offset_in - offset_out) return addr
[docs] def translate_addr_signal(self, mem_map, sig_in, sig_out): cases = [] AW = sig_in._dtype.bit_length() for (offset_in, size, offset_out) in mem_map: in_is_aligned = offset_in % size == 0 and isPow2(size) out_is_aligned = offset_out % size == 0 and isPow2(size) if in_is_aligned: L = (size - 1).bit_length() en_sig = sig_in[:L]._eq(offset_in >> L) _sig_in = sig_in[L:] if out_is_aligned: addr_drive = Concat( HBits(AW - L).from_py(offset_out), _sig_in) else: addr_drive = Concat(HBits(AW - L).from_py(0), _sig_in) + offset_out else: en_sig = inRange(sig_in, offset_in, offset_in + size) if offset_in == offset_out: addr_drive = sig_in elif offset_in < offset_out: addr_drive = sig_in + (offset_out - offset_in) else: # offset_in > offset_out: addr_drive = sig_in - (offset_in - offset_out) cases.append((en_sig, sig_out(addr_drive))) SwitchLogic(cases, default=sig_out(sig_in))
@override def hwDeclr(self): with self._hwParamsShared(): self.m = self.hwIOCls()._m() self.s = self.hwIOCls() self.MEM_MAP = self._normalize_mem_map(self.MEM_MAP)