socks.py
1 from amaranth import * 2 from amaranth.lib.wiring import Component, In, Out, connect, flipped 3 4 from coreblocks.arch.isa_consts import InterruptCauseNumber 5 from coreblocks.core import Core 6 from coreblocks.params import GenParams 7 from coreblocks.peripherals.wishbone import WishboneInterface, WishboneMuxer 8 from coreblocks.priv.traps.interrupt_controller import ISA_RESERVED_INTERRUPTS 9 from coreblocks.socks.clint import ClintPeriph 10 from coreblocks.socks.peripheral import bus_in_periph_range 11 12 CLINT_BASE = 0xE1000000 13 14 # This is a temporary wrapper solution to provide external memory-mapped components, required to run Linux. 15 # It is intended to be only usable with LiteX, that uses a simple core-facing interface and Wishbone bus 16 # (and is currenty the only supported integration). 17 # TODO: Replace this with a proper bus-agnostic (and multicore?) soultion at a later stage. 18 19 20 class Socks(Component): 21 wb_instr: WishboneInterface 22 wb_data: WishboneInterface 23 interrupts: Signal 24 25 def __init__(self, core: Core, core_gen_params: GenParams): 26 super().__init__( 27 { 28 "wb_instr": Out(WishboneInterface(core_gen_params.wb_params).signature), 29 "wb_data": Out(WishboneInterface(core_gen_params.wb_params).signature), 30 "interrupts": In(ISA_RESERVED_INTERRUPTS + core_gen_params.interrupt_custom_count), 31 } 32 ) 33 34 self.clint = ClintPeriph(base_addr=CLINT_BASE, wb_params=core_gen_params.wb_params) 35 36 self.core = core 37 self.core_gen_params = core_gen_params 38 39 def elaborate(self, platform): 40 m = Module() 41 42 muxer_ssel = Signal(2) 43 periph_muxer = WishboneMuxer(self.core_gen_params.wb_params, 2, muxer_ssel) 44 periph_bus = self.clint.bus # only one peripheral for now 45 46 connect(m, self.core.wb_instr, flipped(self.wb_instr)) 47 48 connect(m, self.core.wb_data, periph_muxer.master_wb) 49 connect(m, periph_muxer.slaves[0], flipped(self.wb_data)) 50 51 connect(m, periph_muxer.slaves[1], periph_bus) 52 53 clint_addr = Signal() 54 m.d.comb += clint_addr.eq(bus_in_periph_range(self.core.wb_data, self.clint)) 55 m.d.comb += muxer_ssel.eq(Cat(~clint_addr, clint_addr)) 56 57 m.submodules.clint = self.clint 58 m.submodules.periph_muxer = periph_muxer 59 60 m.submodules.core = self.core 61 62 m.d.comb += self.core.interrupts[InterruptCauseNumber.MEI].eq(self.interrupts[InterruptCauseNumber.MEI]) 63 m.d.comb += self.core.interrupts[InterruptCauseNumber.MTI].eq(self.clint.mtip) 64 m.d.comb += self.core.interrupts[InterruptCauseNumber.MSI].eq(self.clint.msip) 65 m.d.comb += self.core.interrupts[ISA_RESERVED_INTERRUPTS:].eq(self.interrupts[ISA_RESERVED_INTERRUPTS:]) 66 67 return m