From bbebde236f33bb481075e2b90fe5edd850fd3bca Mon Sep 17 00:00:00 2001 From: Marek Materzok Date: Tue, 10 Dec 2024 11:51:21 +0100 Subject: [PATCH] Use bit vector allocator for free registers (#766) --- coreblocks/core.py | 20 ++++++-------------- coreblocks/params/genparams.py | 9 ++++++--- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/coreblocks/core.py b/coreblocks/core.py index fbf96ce09..6c06d96c8 100644 --- a/coreblocks/core.py +++ b/coreblocks/core.py @@ -1,12 +1,13 @@ from amaranth import * from amaranth.lib.wiring import Component, flipped, connect, In, Out +from transactron.lib.allocators import PriorityEncoderAllocator from transactron.utils.amaranth_ext.elaboratables import ModuleConnector from transactron.utils.dependencies import DependencyContext from coreblocks.priv.traps.instr_counter import CoreInstructionCounter from coreblocks.func_blocks.interface.func_blocks_unifier import FuncBlocksUnifier from coreblocks.priv.traps.interrupt_controller import ISA_RESERVED_INTERRUPTS, InternalInterruptController -from transactron.core import Transaction, TModule +from transactron.core import TModule from transactron.lib import ConnectTrans, MethodProduct from coreblocks.interface.layouts import * from coreblocks.interface.keys import ( @@ -26,7 +27,6 @@ from coreblocks.backend.retirement import Retirement from coreblocks.peripherals.bus_adapter import WishboneMasterAdapter from coreblocks.peripherals.wishbone import WishboneMaster, WishboneInterface, WishboneSignature -from transactron.lib import BasicFifo from transactron.lib.metrics import HwMetricsEnabledKey __all__ = ["Core"] @@ -60,9 +60,7 @@ def __init__(self, *, gen_params: GenParams): self.frontend = CoreFrontend(gen_params=self.gen_params, instr_bus=self.bus_master_instr_adapter) - self.free_rf_fifo = BasicFifo( - self.gen_params.get(SchedulerLayouts).free_rf_layout, 2**self.gen_params.phys_regs_bits - ) + self.rf_allocator = PriorityEncoderAllocator(gen_params.phys_regs, init=2**gen_params.phys_regs - 2) self.FRAT = FRAT(gen_params=self.gen_params) self.RRAT = RRAT(gen_params=self.gen_params) @@ -109,7 +107,7 @@ def elaborate(self, platform): m.submodules.frontend = self.frontend - m.submodules.free_rf_fifo = free_rf_fifo = self.free_rf_fifo + m.submodules.rf_allocator = rf_allocator = self.rf_allocator m.submodules.FRAT = frat = self.FRAT m.submodules.RRAT = rrat = self.RRAT m.submodules.RF = rf = self.RF @@ -129,7 +127,7 @@ def elaborate(self, platform): m.submodules.scheduler = Scheduler( get_instr=get_instr.method, - get_free_reg=free_rf_fifo.read, + get_free_reg=rf_allocator.alloc[0], rat_rename=frat.rename, rob_put=rob.put, rf_read_req1=rf.read_req1, @@ -157,7 +155,7 @@ def elaborate(self, platform): rob_retire=rob.retire, r_rat_commit=rrat.commit, r_rat_peek=rrat.peek, - free_rf_put=free_rf_fifo.write, + free_rf_put=rf_allocator.free[0], rf_free=rf.free, exception_cause_get=self.exception_information_register.get, exception_cause_clear=self.exception_information_register.clear, @@ -168,10 +166,4 @@ def elaborate(self, platform): async_interrupt_cause=self.interrupt_controller.interrupt_cause, ) - # push all registers to FreeRF at reset. r0 should be skipped, stop when counter overflows to 0 - free_rf_reg = Signal(self.gen_params.phys_regs_bits, init=1) - with Transaction(name="InitFreeRFFifo").body(m, request=(free_rf_reg.bool())): - free_rf_fifo.write(m, free_rf_reg) - m.d.sync += free_rf_reg.eq(free_rf_reg + 1) - return m diff --git a/coreblocks/params/genparams.py b/coreblocks/params/genparams.py index 0cfa36142..5f39aa38d 100644 --- a/coreblocks/params/genparams.py +++ b/coreblocks/params/genparams.py @@ -1,6 +1,6 @@ from __future__ import annotations -from amaranth.utils import exact_log2 +from amaranth.utils import ceil_log2, exact_log2 from coreblocks.arch.isa import ISA, gen_isa_string from .icache_params import ICacheParameters @@ -59,11 +59,14 @@ def __init__(self, cfg: CoreConfiguration): for block in self.func_units_config: self.max_rs_entries = max(self.max_rs_entries, block.get_rs_entry_count()) - self.rs_number_bits = (len(self.func_units_config) - 1).bit_length() + self.rs_number_bits = ceil_log2(len(self.func_units_config)) + + self.phys_regs = 2**cfg.phys_regs_bits + self.rob_entries = 2**cfg.rob_entries_bits self.phys_regs_bits = cfg.phys_regs_bits self.rob_entries_bits = cfg.rob_entries_bits - self.max_rs_entries_bits = (self.max_rs_entries - 1).bit_length() + self.max_rs_entries_bits = ceil_log2(self.max_rs_entries) self.start_pc = cfg.start_pc self.min_instr_width_bytes = 2 if cfg.compressed else 4