/ coreblocks / core.py
core.py
1 from amaranth import * 2 from amaranth.lib.wiring import Component, flipped, connect, In, Out 3 from transactron import Transaction 4 from transactron.lib.allocators import PriorityEncoderAllocator 5 6 from transactron.utils.dependencies import DependencyContext 7 from coreblocks.priv.traps.instr_counter import CoreInstructionCounter 8 from coreblocks.func_blocks.interface.func_blocks_unifier import FuncBlocksUnifier 9 from coreblocks.priv.traps.interrupt_controller import ISA_RESERVED_INTERRUPTS, InternalInterruptController 10 from transactron.core import TModule, Method, def_method 11 from transactron.lib import CrossbarConnectTrans 12 from coreblocks.interface.layouts import * 13 from coreblocks.interface.keys import ( 14 CSRInstancesKey, 15 CommonBusDataKey, 16 ) 17 from coreblocks.params.genparams import GenParams 18 from coreblocks.core_structs.crat import CheckpointRAT 19 from coreblocks.core_structs.rat import RRAT 20 from coreblocks.core_structs.rob import ReorderBuffer 21 from coreblocks.core_structs.rf import RegisterFile 22 from coreblocks.func_blocks.instruction_metrics import InstructionMetrics 23 from coreblocks.priv.csr.csr_instances import CSRInstances 24 from coreblocks.frontend.frontend import CoreFrontend 25 from coreblocks.priv.traps.exception import ExceptionInformationRegister 26 from coreblocks.scheduler.scheduler import Scheduler 27 from coreblocks.backend.announcement import ResultAnnouncement 28 from coreblocks.backend.retirement import Retirement 29 from coreblocks.peripherals.bus_adapter import WishboneMasterAdapter 30 from coreblocks.peripherals.wishbone import WishboneMaster, WishboneInterface 31 from transactron.lib.metrics import HwMetricsEnabledKey, TaggedCounter 32 33 __all__ = ["Core"] 34 35 36 class Core(Component): 37 wb_instr: WishboneInterface 38 wb_data: WishboneInterface 39 interrupts: Signal 40 41 def __init__(self, *, gen_params: GenParams): 42 super().__init__( 43 { 44 "wb_instr": Out(WishboneInterface(gen_params.wb_params).signature), 45 "wb_data": Out(WishboneInterface(gen_params.wb_params).signature), 46 "interrupts": In(ISA_RESERVED_INTERRUPTS + gen_params.interrupt_custom_count), 47 } 48 ) 49 50 self.gen_params = gen_params 51 52 self.dm = DependencyContext.get() 53 if self.gen_params.debug_signals_enabled: 54 self.dm.add_dependency(HwMetricsEnabledKey(), True) 55 56 self.wb_master_instr = WishboneMaster(self.gen_params.wb_params, "instr") 57 self.wb_master_data = WishboneMaster(self.gen_params.wb_params, "data") 58 59 self.bus_master_instr_adapter = WishboneMasterAdapter(self.wb_master_instr) 60 self.bus_master_data_adapter = WishboneMasterAdapter(self.wb_master_data) 61 self.dm.add_dependency(CommonBusDataKey(), self.bus_master_data_adapter) 62 63 self.frontend = CoreFrontend(gen_params=self.gen_params, instr_bus=self.bus_master_instr_adapter) 64 65 self.rf_allocator = PriorityEncoderAllocator( 66 gen_params.phys_regs, gen_params.frontend_superscalarity, init=2**gen_params.phys_regs - 2 67 ) 68 69 self.CRAT = CheckpointRAT(gen_params=self.gen_params) 70 self.RRAT = RRAT(gen_params=self.gen_params) 71 self.RF = RegisterFile( 72 gen_params=self.gen_params, 73 read_ports=2 * self.gen_params.frontend_superscalarity, 74 write_ports=self.gen_params.announcement_superscalarity, 75 free_ports=1, 76 ) 77 self.ROB = ReorderBuffer( 78 gen_params=self.gen_params, mark_done_ports=self.gen_params.announcement_superscalarity 79 ) 80 81 self.retirement = Retirement(self.gen_params) 82 83 self.exception_information_register = ExceptionInformationRegister( 84 self.gen_params, 85 rob_get_indices=self.ROB.get_indices, 86 fetch_stall_exception=self.frontend.stall, 87 ) 88 89 self.func_blocks_unifier = FuncBlocksUnifier( 90 gen_params=gen_params, 91 blocks=gen_params.func_units_config, 92 ) 93 94 self.csr_instances = CSRInstances(self.gen_params) 95 self.dm.add_dependency(CSRInstancesKey(), self.csr_instances) 96 97 self.interrupt_controller = InternalInterruptController(self.gen_params) 98 99 self.announcement_counter = TaggedCounter( 100 "backend.announcement.announcement_count", 101 "Number of instruction results announced in one cycle", 102 tags=range(gen_params.announcement_superscalarity + 1), 103 ) 104 105 def elaborate(self, platform): 106 m = TModule() 107 108 m.submodules += [self.announcement_counter] 109 110 connect(m.top_module, flipped(self.wb_instr), self.wb_master_instr.wb_master) 111 connect(m.top_module, flipped(self.wb_data), self.wb_master_data.wb_master) 112 113 m.submodules.wb_master_instr = self.wb_master_instr 114 m.submodules.wb_master_data = self.wb_master_data 115 116 m.submodules.bus_master_instr_adapter = self.bus_master_instr_adapter 117 m.submodules.bus_master_data_adapter = self.bus_master_data_adapter 118 119 m.submodules.frontend = self.frontend 120 121 m.submodules.rf_allocator = rf_allocator = self.rf_allocator 122 m.submodules.CRAT = crat = self.CRAT 123 m.submodules.RRAT = rrat = self.RRAT 124 m.submodules.RF = rf = self.RF 125 m.submodules.rob = rob = self.ROB 126 127 m.submodules.csr_instances = self.csr_instances 128 m.submodules.interrupt_controller = self.interrupt_controller 129 m.d.comb += self.interrupt_controller.internal_report_level.eq(self.interrupts[0:16]) 130 m.d.comb += self.interrupt_controller.custom_report.eq(self.interrupts[16:]) 131 132 m.submodules.core_counter = core_counter = CoreInstructionCounter(self.gen_params) 133 134 m.submodules.instruction_metrics = InstructionMetrics() 135 136 get_instr = Method.like(self.frontend.consume_instr) 137 138 @def_method(m, get_instr) 139 def _(): 140 ret = self.frontend.consume_instr(m) 141 core_counter.increment(m, ret.count) 142 return ret 143 144 m.submodules.scheduler = scheduler = Scheduler(gen_params=self.gen_params) 145 scheduler.get_instr.provide(get_instr) 146 scheduler.get_free_reg.provide(rf_allocator.alloc) 147 scheduler.crat_commit_checkpoint.provide(crat.commit_checkpoint) 148 scheduler.crat_rename.provide(crat.rename) 149 scheduler.crat_tag.provide(crat.tag) 150 scheduler.crat_active_tags.provide(crat.get_active_tags) 151 scheduler.rob_put.provide(rob.put) 152 scheduler.rf_read_req.provide(rf.read_req) 153 scheduler.rf_read_resp.provide(rf.read_resp) 154 for i, block in enumerate(self.func_blocks_unifier.rs_blocks): 155 scheduler.rs_select[i].provide(block.select) 156 scheduler.rs_insert[i].provide(block.insert) 157 158 m.submodules.exception_information_register = self.exception_information_register 159 160 announce_result: list[Method] = [] 161 for i in range(self.gen_params.announcement_superscalarity): 162 m.submodules[f"announcement_{i}"] = announcement = ResultAnnouncement(gen_params=self.gen_params) 163 announcement.rob_mark_done.provide(self.ROB.mark_done[i]) 164 announcement.rs_update.provide(self.func_blocks_unifier.update[i]) 165 announcement.rf_write_val.provide(self.RF.write[i]) 166 announce_result.append(announcement.push_result) 167 168 with Transaction().body(m): 169 self.announcement_counter.incr(m, tag=sum(method.run for method in announce_result)) 170 171 m.submodules.announcement_connector = CrossbarConnectTrans.create( 172 self.func_blocks_unifier.get_result, announce_result 173 ) 174 175 m.submodules.retirement = retirement = self.retirement 176 retirement.rob_peek.provide(rob.peek) 177 retirement.rob_retire.provide(rob.retire) 178 retirement.r_rat_commit.provide(rrat.commit[0]) 179 retirement.r_rat_peek.provide(rrat.peek[0]) 180 retirement.free_rf_put.provide(rf_allocator.free[0]) 181 retirement.rf_free.provide(rf.free[0]) 182 retirement.exception_cause_get.provide(self.exception_information_register.get) 183 retirement.exception_cause_clear.provide(self.exception_information_register.clear) 184 retirement.c_rat_restore.provide(crat.flush_restore) 185 retirement.fetch_continue.provide(self.frontend.resume_from_exception) 186 retirement.instr_decrement.provide(core_counter.decrement) 187 retirement.trap_entry.provide(self.interrupt_controller.entry) 188 retirement.async_interrupt_cause.provide(self.interrupt_controller.interrupt_cause) 189 retirement.checkpoint_get_active_tags.provide(crat.get_active_tags) 190 retirement.checkpoint_tag_free.provide(crat.free_tag) 191 192 m.submodules.func_blocks_unifier = self.func_blocks_unifier 193 194 return m