1/*************************************************************************************** 2* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3* Copyright (c) 2024 Institute of Computing Technology, Chinese Academy of Sciences 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan 18 19import chisel3._ 20import chisel3.util._ 21import org.chipsalliance.cde.config._ 22import freechips.rocketchip.diplomacy._ 23import freechips.rocketchip.interrupts._ 24import freechips.rocketchip.util._ 25import system.HasSoCParameter 26import device.{IMSICAsync, MsiInfoBundle} 27import coupledL2.tl2chi.{PortIO, AsyncPortIO, CHIAsyncBridgeSource} 28import utility.IntBuffer 29 30// This module is used for XSNoCTop for async time domain and divide different 31// voltage domain. Everything in this module should be in the core clock domain 32// and higher voltage domain. 33class XSTileWrap()(implicit p: Parameters) extends LazyModule 34 with HasXSParameter 35 with HasSoCParameter 36{ 37 override def shouldBeInlined: Boolean = false 38 39 val tile = LazyModule(new XSTile()) 40 41 // interrupts sync 42 val clintIntNode = IntIdentityNode() 43 val debugIntNode = IntIdentityNode() 44 val plicIntNode = IntIdentityNode() 45 tile.clint_int_node := IntBuffer(2) := clintIntNode 46 tile.debug_int_node := IntBuffer(2) := debugIntNode 47 tile.plic_int_node :*= IntBuffer(2) :*= plicIntNode 48 class XSTileWrapImp(wrapper: LazyModule) extends LazyModuleImp(wrapper) { 49 val io = IO(new Bundle { 50 val hartId = Input(UInt(hartIdLen.W)) 51 val msiInfo = Input(ValidIO(new MsiInfoBundle)) 52 val reset_vector = Input(UInt(PAddrBits.W)) 53 val cpu_halt = Output(Bool()) 54 val hartIsInReset = Output(Bool()) 55 val debugTopDown = new Bundle { 56 val robHeadPaddr = Valid(UInt(PAddrBits.W)) 57 val l3MissMatch = Input(Bool()) 58 } 59 val chi = EnableCHIAsyncBridge match { 60 case Some(param) => Some(new AsyncPortIO(param)) 61 case None => Some(new PortIO) 62 } 63 val nodeID = if (enableCHI) Some(Input(UInt(NodeIDWidth.W))) else None 64 val clintTime = EnableClintAsyncBridge match { 65 case Some(param) => Some(Flipped(new AsyncBundle(UInt(64.W), param))) 66 case None => Some(Input(ValidIO(UInt(64.W)))) 67 } 68 }) 69 70 val imsicAsync = Module(new IMSICAsync()) 71 imsicAsync.i.msiInfo := io.msiInfo 72 73 tile.module.io.hartId := io.hartId 74 tile.module.io.msiInfo := imsicAsync.o.msiInfo 75 tile.module.io.reset_vector := io.reset_vector 76 io.cpu_halt := tile.module.io.cpu_halt 77 io.hartIsInReset := tile.module.io.hartIsInReset 78 io.debugTopDown <> tile.module.io.debugTopDown 79 tile.module.io.nodeID.foreach(_ := io.nodeID.get) 80 81 // CLINT Async Queue Sink 82 EnableClintAsyncBridge match { 83 case Some(param) => 84 val sink = Module(new AsyncQueueSink(UInt(64.W), param)) 85 sink.io.async <> io.clintTime.get 86 sink.io.deq.ready := true.B 87 tile.module.io.clintTime.valid := sink.io.deq.valid 88 tile.module.io.clintTime.bits := sink.io.deq.bits 89 case None => 90 tile.module.io.clintTime := io.clintTime.get 91 } 92 93 // CHI Async Queue Source 94 EnableCHIAsyncBridge match { 95 case Some(param) => 96 val source = Module(new CHIAsyncBridgeSource(param)) 97 source.io.enq <> tile.module.io.chi.get 98 io.chi.get <> source.io.async 99 case None => 100 require(enableCHI) 101 io.chi.get <> tile.module.io.chi.get 102 } 103 104 dontTouch(io.hartId) 105 dontTouch(io.msiInfo) 106 } 107 lazy val module = new XSTileWrapImp(this) 108} 109