Source code for hwtLib.abstract.busStaticRemap

from hwt.code import SwitchLogic, Concat
from hwt.synthesizer.param import Param
from hwt.synthesizer.unit import Unit
from hwt.math import inRange, isPow2
from hwt.hdl.types.bits import Bits


[docs]class BusStaticRemap(Unit): """ 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 interface class where master should be connected :ivar ~.s: slave interface of second interface class where master slave be connected """ def _config(self): self.MEM_MAP = Param([])
[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( Bits(AW - L).from_py(offset_out), _sig_in) else: addr_drive = Concat(Bits(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))
def _declr(self): with self._paramsShared(): self.m = self.intfCls()._m() self.s = self.intfCls() self.MEM_MAP = self._normalize_mem_map(self.MEM_MAP)