Skip to content

Commit

Permalink
Add RS flushing mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
tilk committed Mar 21, 2024
1 parent 074ff6b commit 179077c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
31 changes: 29 additions & 2 deletions coreblocks/func_blocks/fu/common/rs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand All @@ -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]

Expand All @@ -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):
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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())
Expand Down
4 changes: 3 additions & 1 deletion coreblocks/func_blocks/fu/common/rs_func_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 179077c

Please sign in to comment.