diff --git a/coreblocks/func_blocks/fu/common/rs.py b/coreblocks/func_blocks/fu/common/rs.py index 56287df27..d159d4a2d 100644 --- a/coreblocks/func_blocks/fu/common/rs.py +++ b/coreblocks/func_blocks/fu/common/rs.py @@ -5,8 +5,11 @@ from transactron import Method, def_method, TModule from coreblocks.params import GenParams from coreblocks.frontend.decoder import OpType -from coreblocks.interface.layouts import RSLayouts +from coreblocks.interface.layouts import FuncUnitLayouts, RSLayouts +from coreblocks.interface.keys import CoreStateKey +from transactron.core.transaction import Transaction from transactron.utils import RecordDict +from transactron.utils.dependencies import DependencyManager from transactron.utils.transactron_helpers import make_layout __all__ = ["RS"] @@ -32,6 +35,9 @@ def __init__( self.update = Method(i=self.layouts.rs.update_in) self.take = Method(i=self.layouts.take_in, o=self.layouts.take_out) + # The accept method acts as a FU bypass for RS flushing + self.accept = Method(o=gen_params.get(FuncUnitLayouts).accept) + self.ready_for = [list(op_list) for op_list in ready_for] self.get_ready_list = [Method(o=self.layouts.get_ready_list_out, nonexclusive=True) for _ in self.ready_for] @@ -41,6 +47,11 @@ def __init__( def elaborate(self, platform): m = TModule() + core_state = self.gen_params.get(DependencyManager).get_dependency(CoreStateKey()) + + with Transaction().body(m): + flushing = core_state(m).flushing + m.submodules.enc_select = PriorityEncoder(width=self.rs_entries) for i, record in enumerate(self.data): @@ -54,6 +65,9 @@ def elaborate(self, platform): take_vector = Cat(self.data_ready[i] & record.rec_full for i, record in enumerate(self.data)) take_possible = take_vector.any() + accept_vector = Cat(record.rec_full for record in self.data) + accept_possible = accept_vector.any() + ready_lists: list[Value] = [] for op_list in self.ready_for: op_vector = Cat(Cat(record.rs_data.exec_fn.op_type == op for op in op_list).any() for record in self.data) @@ -84,7 +98,7 @@ def _(reg_id: Value, reg_val: Value) -> None: m.d.sync += record.rs_data.rp_s2.eq(0) m.d.sync += record.rs_data.s2_val.eq(reg_val) - @def_method(m, self.take, ready=take_possible) + @def_method(m, self.take, ready=take_possible & ~flushing) def _(rs_entry_id: Value) -> RecordDict: record = self.data[rs_entry_id] m.d.sync += record.rec_reserved.eq(0) @@ -99,6 +113,19 @@ def _(rs_entry_id: Value) -> RecordDict: "pc": record.rs_data.pc, } + @def_method(m, self.accept, ready=accept_possible & flushing) + def _() -> RecordDict: + last = Signal(range(self.rs_entries)) + for i in range(self.rs_entries): + with m.If(accept_vector[i]): + m.d.comb += last.eq(i) + + record = self.data[last] + m.d.sync += record.rec_reserved.eq(0) + m.d.sync += record.rec_full.eq(0) + + return {"rob_id": record.rs_data.rob_id, "result": 0, "rp_dst": record.rs_data.rp_dst, "exception": 0} + for get_ready_list, ready_list in zip(self.get_ready_list, ready_lists): @def_method(m, get_ready_list, ready=ready_list.any()) diff --git a/coreblocks/func_blocks/fu/common/rs_func_block.py b/coreblocks/func_blocks/fu/common/rs_func_block.py index 66fed3d0e..5d9e94abf 100644 --- a/coreblocks/func_blocks/fu/common/rs_func_block.py +++ b/coreblocks/func_blocks/fu/common/rs_func_block.py @@ -73,7 +73,9 @@ def elaborate(self, platform): m.submodules[f"func_unit_{n}"] = func_unit m.submodules[f"wakeup_select_{n}"] = wakeup_select - m.submodules.collector = collector = Collector([func_unit.accept for func_unit, _ in self.func_units]) + m.submodules.collector = collector = Collector( + [self.rs.accept] + [func_unit.accept for func_unit, _ in self.func_units] + ) self.insert.proxy(m, self.rs.insert) self.select.proxy(m, self.rs.select)