From 117514968c077e8fa8bd8ff9aaa1b95f5f43818e Mon Sep 17 00:00:00 2001 From: Johannes Kappes Date: Fri, 31 Jul 2026 14:36:19 +0200 Subject: [PATCH 1/2] [MetaModel] Arch.Alias add init_val_dict --- m2isar/metamodel/arch.py | 55 +++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/m2isar/metamodel/arch.py b/m2isar/metamodel/arch.py index 96b78a1..d27faf9 100644 --- a/m2isar/metamodel/arch.py +++ b/m2isar/metamodel/arch.py @@ -417,43 +417,52 @@ def _is_specific_memory(self, memory_type: attribute_info.MemoryAttribute, expec # unsigned& S0 = X[8]; vs # Intention: alias S0 <- X[8]; class Alias(Symbol): - """A class representing an (potentially ranged) alias to a Register/Memory/RegisterBank entity, + """A class representing an (potentially ranged) alias to a Register/Memory/RegisterBank entity, which refer to the architectural part of an M2-ISA-R model. This access might be ranged""" - parent: Union[Memory, RegisterBank] - _initval = 0 + parent: Union[Memory, RegisterBank] + _initval: "dict[int, Union[int, Parameter, BaseNode]]" + + def __init__(self, name, parent: Union[Memory, RegisterBank], range: RangeSpec, type: type_info.PointerType, attributes: dict = {}): + self.parent = parent + self.range = range + self.ty = type + self._initval = {} + assert isinstance(parent.ty, (type_info.ArrayType, type_info.PrimitiveType)) + super().__init__(name, type, attributes) + + + def initval(self, idx=None): + """Return the initial value for the given index.""" + + return get_const_or_val(self._initval[idx]) + - def __init__(self, name, parent: Union[Memory, RegisterBank], range: RangeSpec, type: type_info.PointerType, attributes: dict = {}): - self.parent = parent - self.range = range - self.ty = type - assert isinstance(parent.ty, (type_info.ArrayType, type_info.PrimitiveType)) - super().__init__(name, type, attributes) + @property + def data_range(self): + """Returns a RangeSpec object with upper=range.upper-range.lower, lower=0.""" + if self.range.upper is None or self.range.lower is None: + return None - @property - def data_range(self): - """Returns a RangeSpec object with upper=range.upper-range.lower, lower=0.""" + return RangeSpec(self.range.upper - self.range.lower, 0) - if self.range.upper is None or self.range.lower is None: - return None - return RangeSpec(self.range.upper - self.range.lower, 0) - @property - def length(self): - """Returns the length of the range using following algorithm: + @property + def length(self): + """Returns the length of the range using following algorithm: if self.upper is None: return None elif self.lower is None: return self.upper else return self.upper - self.lower + 1 """ - if self.range.upper is None: - return None + if self.range.upper is None: + return None - if self.range.lower is None: - return self.range.upper + if self.range.lower is None: + return self.range.upper - return self.range.upper - self.range.lower + 1 + return self.range.upper - self.range.lower + 1 # ============================================================ # END From 705f2463e8d3a785cb7dd805b8bb0174189db6ad Mon Sep 17 00:00:00 2001 From: Johannes Kappes Date: Fri, 31 Jul 2026 14:38:41 +0200 Subject: [PATCH 2/2] [Backend] ETISS fix actual_regs handling Issue: https://github.com/tum-ei-eda/etiss/pull/245 F0...F32 + RA, TO .. never initialized --- m2isar/backends/etiss/architecture_writer.py | 8 +++++--- .../backends/etiss/templates/etiss_arch_cpp.mako | 14 +++++++------- .../coredsl2/architecture_model_builder.py | 3 +-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/m2isar/backends/etiss/architecture_writer.py b/m2isar/backends/etiss/architecture_writer.py index 9c731be..6f70b18 100644 --- a/m2isar/backends/etiss/architecture_writer.py +++ b/m2isar/backends/etiss/architecture_writer.py @@ -125,7 +125,7 @@ def build_reg_hierarchy(reg: Union[arch.Memory, arch.Alias, arch.Register, arch. """Populate the passed lists with memory objects of their category. # CSR is actually an extern memory range but treatet as a reg ptr_regs: Registers that need to be a pointer within ETISS - actual_regs: Registers that are not a pointer + actual_regs: Registers that are not a pointer/have no children ... (Alias by default) alias_regs: Registers which are an alias to some other register initval_regs: Registers which have initial value(s) defined in the model """ @@ -148,7 +148,9 @@ def build_reg_hierarchy(reg: Union[arch.Memory, arch.Alias, arch.Register, arch. else: actual_regs.append(reg) else: - assert isinstance(reg, arch.Alias) + # Alias of Aliases are not implemented => No Children + assert isinstance(reg, arch.Alias) and not isinstance(reg.parent, arch.Alias) + actual_regs.append(reg) return def write_arch_cpp(core: arch.CoreDef, start_time: str, output_path: pathlib.Path, aliased_regnames: bool=True): @@ -165,7 +167,7 @@ def write_arch_cpp(core: arch.CoreDef, start_time: str, output_path: pathlib.Pat # determine memory types for _, mem_desc in chain(core.memories.items(), core.register_banks.items(), core.memory_aliases.items(), core.register_aliases.items()): - if hasattr(mem_desc, "is_main_mem"): + if hasattr(mem_desc, "is_main_mem"): if mem_desc.is_main_mem: continue build_reg_hierarchy(mem_desc, ptr_regs, actual_regs, alias_regs, initval_regs) diff --git a/m2isar/backends/etiss/templates/etiss_arch_cpp.mako b/m2isar/backends/etiss/templates/etiss_arch_cpp.mako index 1ceb5f9..90e735e 100644 --- a/m2isar/backends/etiss/templates/etiss_arch_cpp.mako +++ b/m2isar/backends/etiss/templates/etiss_arch_cpp.mako @@ -94,18 +94,18 @@ void ${core_name}Arch::resetCPU(ETISS_CPU *cpu, etiss::uint64 *startpointer) % endfor % for reg in actual_regs: - % if not isinstance(reg, (arch.Memory, arch.Alias)): - % if isinstance(reg, arch.RegisterBank): - <% assert isinstance(reg.ty, type_info.ArrayType) %> + % if isinstance(reg.ty, type_info.ArrayType): for (int i = 0; i < ${arch.get_const_or_val(reg.ty.length)}; ++i) { ${core_name.lower()}cpu->${reg.name}[i] = 0; } % else: - <% assert isinstance(reg.ty, type_info.PrimitiveType) %> - % if not reg.is_pc: - ${core_name.lower()}cpu->${reg.name} = 0; - % endif + % if hasattr(reg, "is_pc"): + % if not reg.is_pc: + ${core_name.lower()}cpu->${reg.name} = 0; + % endif + % else: + ${core_name.lower()}cpu->${reg.name} = 0; % endif % endif % endfor diff --git a/m2isar/frontends/coredsl2/architecture_model_builder.py b/m2isar/frontends/coredsl2/architecture_model_builder.py index 3cdfe44..7a3f895 100644 --- a/m2isar/frontends/coredsl2/architecture_model_builder.py +++ b/m2isar/frontends/coredsl2/architecture_model_builder.py @@ -600,8 +600,7 @@ def visitAssignment_expression(self, ctx: CoreDSL2Parser.Assignment_expressionCo if isinstance(left, behav.NamedReference): if isinstance(left.reference, arch.Parameter): left.reference.value = exprInterpretVisitor.generate(right, None) - - elif isinstance(left.reference, arch.Memory): + elif isinstance(left.reference, (arch.Register, arch.Alias)): left.reference._initval[None] = exprInterpretVisitor.generate(right, None) elif isinstance(left, behav.IndexedReference): left.reference._initval[exprInterpretVisitor.generate(left.index, None)] = exprInterpretVisitor.generate(right, None)