From e2a2ca0a69f3fdb079c62829eaff6fea0533c912 Mon Sep 17 00:00:00 2001 From: Raphael Kunz Date: Mon, 13 Jul 2026 13:47:27 +0200 Subject: [PATCH] [BUGFIX] Fixing inconsistent check to classify Memory Type This fix ensures that the check if a given memory is a float register of something similar is performed equally wherever it is called. --- .../templates/etiss_arch_specific_h.mako | 4 +- m2isar/backends/etiss/virtualstruct_utils.py | 8 ++-- .../coredsl2/architecture_model_builder.py | 8 ++-- m2isar/metamodel/arch.py | 45 +++++++++++++++---- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/m2isar/backends/etiss/templates/etiss_arch_specific_h.mako b/m2isar/backends/etiss/templates/etiss_arch_specific_h.mako index 5de2720..94b2b8e 100644 --- a/m2isar/backends/etiss/templates/etiss_arch_specific_h.mako +++ b/m2isar/backends/etiss/templates/etiss_arch_specific_h.mako @@ -136,7 +136,7 @@ class FloatRegField_${core_name} : public etiss::VirtualStruct::Field { // clang-format off assert((offset == 0 || (offset < (bitwidth_ / sizeof(uint64_t)))) && "Virtualstruct field offset out of range"); - % if len(main_reg.children) > 0: + % if len(float_reg.children) > 0: return (uint64_t) *((${core_name}*)parent_.structure_)->${float_reg.name}[gprid_]; % else: return (uint64_t) ((${core_name}*)parent_.structure_)->${float_reg.name}[gprid_]; @@ -149,7 +149,7 @@ class FloatRegField_${core_name} : public etiss::VirtualStruct::Field // clang-format off assert((offset == 0 || (offset < (bitwidth_ / sizeof(uint64_t)))) && "Virtualstruct field offset out of range"); etiss::log(etiss::VERBOSE, "write to ETISS cpu state", name_, val); - % if len(main_reg.children) > 0: + % if len(float_reg.children) > 0: *((${core_name}*)parent_.structure_)->${float_reg.name}[gprid_] = (etiss_uint${float_reg.size}) val; % else: ((${core_name}*)parent_.structure_)->${float_reg.name}[gprid_] = (etiss_uint${float_reg.size}) val; diff --git a/m2isar/backends/etiss/virtualstruct_utils.py b/m2isar/backends/etiss/virtualstruct_utils.py index 82a4492..ccce8f6 100644 --- a/m2isar/backends/etiss/virtualstruct_utils.py +++ b/m2isar/backends/etiss/virtualstruct_utils.py @@ -164,13 +164,13 @@ def get_virtualstruct_regs(mapping: dict, memories: dict, memory_aliases: dict): for mem in memories.values(): if mem.is_pc: pc_reg = mem - elif MemoryAttribute.IS_MAIN_REG in mem.attributes or mem.name == "X": + elif mem.is_main_reg: main_reg = mem - elif MemoryAttribute.IS_FLOAT_REG in mem.attributes or mem.name == "F": + elif mem.is_float_reg: float_reg = mem - elif MemoryAttribute.IS_VECTOR_REG in mem.attributes or mem.name == "F": + elif mem.is_vector_reg: vector_reg = mem - elif MemoryAttribute.IS_CSR_REG in mem.attributes or mem.name == "CSR": + elif mem.is_csr_reg: csr_reg = mem aliased_csrs = set() if csr_reg is not None: diff --git a/m2isar/frontends/coredsl2/architecture_model_builder.py b/m2isar/frontends/coredsl2/architecture_model_builder.py index b028798..347f422 100644 --- a/m2isar/frontends/coredsl2/architecture_model_builder.py +++ b/m2isar/frontends/coredsl2/architecture_model_builder.py @@ -405,13 +405,13 @@ def visitDeclaration(self, ctx: CoreDSL2Parser.DeclarationContext): if init is not None: m._initval[None] = exprInterpretVisitor.generate(init, None) - if arch.MemoryAttribute.IS_MAIN_REG in attributes: + if m.is_main_reg: self._main_reg_file = m - if arch.MemoryAttribute.IS_FLOAT_REG in attributes: + if m.is_float_reg: self._float_reg_file = m - if arch.MemoryAttribute.IS_VECTOR_REG in attributes: + if m.is_vector_reg: self._vector_reg_file = m - if arch.MemoryAttribute.IS_CSR_REG in attributes or name.upper() == "CSR": + if m.is_csr_reg: self._csr_reg_file = m self._memories[name] = m diff --git a/m2isar/metamodel/arch.py b/m2isar/metamodel/arch.py index 4c820ee..5c64aa1 100644 --- a/m2isar/metamodel/arch.py +++ b/m2isar/metamodel/arch.py @@ -374,12 +374,41 @@ def data_range(self): @property def is_pc(self): """Return true if this memory is tagged as being the program counter.""" - return MemoryAttribute.IS_PC in self.attributes + return self._is_specific_memory(MemoryAttribute.IS_PC) @property def is_main_mem(self): """Return true if this memory is tagged as being the main memory array.""" - return MemoryAttribute.IS_MAIN_MEM in self.attributes + return self._is_specific_memory(MemoryAttribute.IS_MAIN_MEM) + + @property + def is_main_reg(self) -> bool: + """Return true if this memory is tagged as being the main memory register.""" + return self._is_specific_memory(MemoryAttribute.IS_MAIN_REG, "X") + + @property + def is_float_reg(self) -> bool: + """Return true if this memory is tagged as being a float register array or named F.""" + return self._is_specific_memory(MemoryAttribute.IS_FLOAT_REG, "F") + + @property + def is_vector_reg(self) -> bool: + """Return true if this memory is tagged as being a vector register array or named V.""" + return self._is_specific_memory(MemoryAttribute.IS_VECTOR_REG, "V") + + @property + def is_csr_reg(self) -> bool: + """Return true if this memory is tagged as being a csr register array or named CSR.""" + return self._is_specific_memory(MemoryAttribute.IS_CSR_REG, "CSR") + + def _is_specific_memory(self, memory_type: MemoryAttribute, expected_name: str = "") -> bool: + """ + This is a helper function to ensure, that all checks are performed always the same. + :param memory_type: The memory attribute qualifying for this check + :param expected_name: The fixed name for this specific type of memory + :return: True if the memory matches the constraints, False otherwise + """ + return memory_type in self.attributes or expected_name.upper() == self.name.upper() @dataclasses.dataclass class BitVal: @@ -617,17 +646,17 @@ def __init__(self, name, contributing_types: "list[str]", template: str, constan self.functions_by_ext[fn_def.ext_name][fn_name] = fn_def for mem in itertools.chain(self.memories.values(), self.memory_aliases.values()): - if MemoryAttribute.IS_MAIN_REG in mem.attributes: + if mem.is_main_reg: self.main_reg_file = mem - if MemoryAttribute.IS_FLOAT_REG in mem.attributes: + if mem.is_float_reg: self.float_reg_file = mem - if MemoryAttribute.IS_VECTOR_REG in mem.attributes: + if mem.is_vector_reg: self.vector_reg_file = mem - if MemoryAttribute.IS_CSR_REG in mem.attributes or mem.name.upper() == "CSR": + if mem.is_csr_reg: self.csr_reg_file = mem - elif MemoryAttribute.IS_PC in mem.attributes: + elif mem.is_pc: self.pc_memory = mem - elif MemoryAttribute.IS_MAIN_MEM in mem.attributes: + elif mem.is_main_mem: self.main_memory = mem elif MemoryAttribute.ETISS_IS_GLOBAL_IRQ_EN in mem.attributes: self.global_irq_en_memory = mem