Skip to content

Commit

Permalink
Move CoreCounter behind the frontend (#699)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakub Urbańczyk authored May 14, 2024
1 parent 255abce commit 6c872cd
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 31 deletions.
20 changes: 14 additions & 6 deletions coreblocks/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
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 InterruptController
from transactron.core import Transaction, TModule
from transactron.lib import ConnectTrans
from transactron.lib import ConnectTrans, MethodProduct
from coreblocks.interface.layouts import *
from coreblocks.interface.keys import (
FetchResumeKey,
Expand Down Expand Up @@ -64,7 +65,7 @@ def __init__(self, *, gen_params: GenParams, wb_instr_bus: WishboneInterface, wb
self.exception_cause_register = ExceptionCauseRegister(
self.gen_params,
rob_get_indices=self.ROB.get_indices,
fetch_stall_exception=self.frontend.fetch.stall_exception,
fetch_stall_exception=self.frontend.stall,
)

self.func_blocks_unifier = FuncBlocksUnifier(
Expand Down Expand Up @@ -105,8 +106,15 @@ def elaborate(self, platform):
m.submodules.RF = rf = self.RF
m.submodules.ROB = rob = self.ROB

m.submodules.core_counter = core_counter = CoreInstructionCounter(self.gen_params)

drop_second_ret_value = (self.gen_params.get(DecodeLayouts).decoded_instr, lambda _, rets: rets[0])
m.submodules.get_instr = get_instr = MethodProduct(
[self.frontend.consume_instr, core_counter.increment], combiner=drop_second_ret_value
)

m.submodules.scheduler = Scheduler(
get_instr=self.frontend.fifo_decode.read,
get_instr=get_instr.method,
get_free_reg=free_rf_fifo.read,
rat_rename=frat.rename,
rob_put=rob.put,
Expand All @@ -121,7 +129,7 @@ def elaborate(self, platform):
fetch_resume_fb, fetch_resume_unifiers = self.connections.get_dependency(FetchResumeKey())
m.submodules.fetch_resume_unifiers = ModuleConnector(**fetch_resume_unifiers)

m.submodules.fetch_resume_connector = ConnectTrans(fetch_resume_fb, self.frontend.fetch.resume_from_unsafe)
m.submodules.fetch_resume_connector = ConnectTrans(fetch_resume_fb, self.frontend.resume_from_unsafe)

m.submodules.announcement = self.announcement
m.submodules.func_blocks_unifier = self.func_blocks_unifier
Expand All @@ -136,8 +144,8 @@ def elaborate(self, platform):
exception_cause_get=self.exception_cause_register.get,
exception_cause_clear=self.exception_cause_register.clear,
frat_rename=frat.rename,
fetch_continue=self.frontend.fetch.resume_from_exception,
instr_decrement=self.frontend.core_counter.decrement,
fetch_continue=self.frontend.resume_from_exception,
instr_decrement=core_counter.decrement,
trap_entry=self.interrupt_controller.entry,
)

Expand Down
61 changes: 37 additions & 24 deletions coreblocks/frontend/frontend.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,42 @@
from amaranth import *

from transactron.core import Transaction, TModule
from transactron.lib import FIFO, MethodMap, MethodProduct
from transactron.core import *
from transactron.lib import BasicFifo, Pipe
from transactron.utils.dependencies import DependencyContext

from coreblocks.params.genparams import GenParams
from coreblocks.frontend.decoder.decode_stage import DecodeStage
from coreblocks.frontend.fetch.fetch import FetchUnit
from coreblocks.cache.icache import ICache, ICacheBypass
from coreblocks.cache.refiller import SimpleCommonBusCacheRefiller
from coreblocks.priv.traps.instr_counter import CoreInstructionCounter
from coreblocks.interface.layouts import *
from coreblocks.interface.keys import BranchVerifyKey, FlushICacheKey
from coreblocks.peripherals.bus_adapter import BusMasterInterface


class CoreFrontend(Elaboratable):
"""Frontend of the core.
Attributes
----------
inject_instr: Method
Inject a raw instruction (of type FetchLayouts.raw_instr) directly
into the instruction buffer.
consume_instr: Method
Consume a single decoded instruction.
resume_from_exception: Method
Resume the frontend from the given PC after an exception.
resume_from_unsafe: Method
Resume the frontend from the given PC after an unsafe instruction.
stall: Method
Stall and flush the frontend.
"""

def __init__(self, *, gen_params: GenParams, instr_bus: BusMasterInterface):
self.gen_params = gen_params

self.connections = DependencyContext.get()

self.instr_bus = instr_bus

self.core_counter = CoreInstructionCounter(self.gen_params)

# make fetch_continue visible outside the core for injecting instructions
self.fifo_fetch = FIFO(self.gen_params.get(FetchLayouts).raw_instr, 2)

drop_args_transform = (self.gen_params.get(FetchLayouts).raw_instr, lambda _a, _b: {})
self.core_counter_increment_discard_map = MethodMap(
self.core_counter.increment, i_transform=drop_args_transform
)
self.fetch_continue = MethodProduct([self.fifo_fetch.write, self.core_counter_increment_discard_map.method])
self.instr_buffer = BasicFifo(self.gen_params.get(FetchLayouts).raw_instr, self.gen_params.instr_buffer_size)

cache_layouts = self.gen_params.get(ICacheLayouts)
if gen_params.icache_params.enable:
Expand All @@ -43,9 +47,15 @@ def __init__(self, *, gen_params: GenParams, instr_bus: BusMasterInterface):

self.connections.add_dependency(FlushICacheKey(), self.icache.flush)

self.fetch = FetchUnit(self.gen_params, self.icache, self.fetch_continue.method)
self.fetch = FetchUnit(self.gen_params, self.icache, self.instr_buffer.write)

self.fifo_decode = FIFO(self.gen_params.get(DecodeLayouts).decoded_instr, 2)
self.decode_pipe = Pipe(self.gen_params.get(DecodeLayouts).decoded_instr)

self.inject_instr = self.instr_buffer.write
self.consume_instr = self.decode_pipe.read
self.resume_from_exception = self.fetch.resume_from_exception
self.resume_from_unsafe = self.fetch.resume_from_unsafe
self.stall = Method()

def elaborate(self, platform):
m = TModule()
Expand All @@ -54,20 +64,23 @@ def elaborate(self, platform):
m.submodules.icache_refiller = self.icache_refiller
m.submodules.icache = self.icache

m.submodules.fetch_continue = self.fetch_continue
m.submodules.fetch = self.fetch
m.submodules.fifo_fetch = self.fifo_fetch
m.submodules.core_counter = self.core_counter
m.submodules.args_discard_map = self.core_counter_increment_discard_map
m.submodules.instr_buffer = self.instr_buffer

m.submodules.fifo_decode = self.fifo_decode
m.submodules.decode_pipe = self.decode_pipe
m.submodules.decode = DecodeStage(
gen_params=self.gen_params, get_raw=self.fifo_fetch.read, push_decoded=self.fifo_decode.write
gen_params=self.gen_params, get_raw=self.instr_buffer.read, push_decoded=self.decode_pipe.write
)

# TODO: Remove when Branch Predictor implemented
with Transaction(name="DiscardBranchVerify").body(m):
read = self.connections.get_dependency(BranchVerifyKey())
read(m) # Consume to not block JB Unit

@def_method(m, self.stall)
def _():
self.fetch.stall_exception(m)
self.instr_buffer.clear(m)
self.decode_pipe.clean(m)

return m
5 changes: 5 additions & 0 deletions coreblocks/params/configurations.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class _CoreConfigurationDataClass:
Log of the cache line size (in bytes).
fetch_block_bytes_log: int
Log of the size of the fetch block (in bytes).
instr_buffer_size: int
Size of the instruction buffer.
allow_partial_extensions: bool
Allow partial support of extensions.
extra_verification: bool
Expand Down Expand Up @@ -105,6 +107,8 @@ def __post_init__(self):

fetch_block_bytes_log: int = 2

instr_buffer_size: int = 4

allow_partial_extensions: bool = False

extra_verification: bool = True
Expand Down Expand Up @@ -162,6 +166,7 @@ def replace(self, **kwargs) -> Self:
),
compressed=True,
fetch_block_bytes_log=4,
instr_buffer_size=16,
)

# Core configuration used in internal testbenches
Expand Down
1 change: 1 addition & 0 deletions coreblocks/params/genparams.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def __init__(self, cfg: CoreConfiguration):
self.fetch_width = 2**cfg.fetch_block_bytes_log // self.min_instr_width_bytes
self.fetch_width_log = exact_log2(self.fetch_width)

self.instr_buffer_size = cfg.instr_buffer_size
self.extra_verification = cfg.extra_verification

self._toolchain_isa_str = gen_isa_string(extensions, cfg.xlen, skip_internal=True)
2 changes: 1 addition & 1 deletion test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def elaborate(self, platform):
wb_params=self.gen_params.wb_params, width=32, depth=len(self.data_mem), init=self.data_mem
)
self.core = Core(gen_params=self.gen_params, wb_instr_bus=wb_instr_bus, wb_data_bus=wb_data_bus)
self.io_in = TestbenchIO(AdapterTrans(self.core.frontend.fetch_continue.method))
self.io_in = TestbenchIO(AdapterTrans(self.core.frontend.inject_instr))
self.interrupt = TestbenchIO(AdapterTrans(self.core.interrupt_controller.report_interrupt))

m.submodules.wb_mem_slave = self.wb_mem_slave
Expand Down

0 comments on commit 6c872cd

Please sign in to comment.