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 debugTopDown = new Bundle { 55 val robHeadPaddr = Valid(UInt(PAddrBits.W)) 56 val l3MissMatch = Input(Bool()) 57 } 58 val chi = EnableCHIAsyncBridge match { 59 case Some(param) => Some(new AsyncPortIO(param)) 60 case None => Some(new PortIO) 61 } 62 val nodeID = if (enableCHI) Some(Input(UInt(NodeIDWidth.W))) else None 63 val clintTime = EnableClintAsyncBridge match { 64 case Some(param) => Some(Flipped(new AsyncBundle(UInt(64.W), param))) 65 case None => Some(Input(ValidIO(UInt(64.W)))) 66 } 67 }) 68 69 val imsicAsync = Module(new IMSICAsync()) 70 imsicAsync.i.msiInfo := io.msiInfo 71 72 tile.module.io.hartId := io.hartId 73 tile.module.io.msiInfo := imsicAsync.o.msiInfo 74 tile.module.io.reset_vector := io.reset_vector 75 io.cpu_halt := tile.module.io.cpu_halt 76 io.debugTopDown <> tile.module.io.debugTopDown 77 tile.module.io.nodeID.foreach(_ := io.nodeID.get) 78 79 // CLINT Async Queue Sink 80 EnableClintAsyncBridge match { 81 case Some(param) => 82 val sink = Module(new AsyncQueueSink(UInt(64.W), param)) 83 sink.io.async <> io.clintTime.get 84 sink.io.deq.ready := true.B 85 tile.module.io.clintTime.valid := sink.io.deq.valid 86 tile.module.io.clintTime.bits := sink.io.deq.bits 87 case None => 88 tile.module.io.clintTime := io.clintTime.get 89 } 90 91 // CHI Async Queue Source 92 EnableCHIAsyncBridge match { 93 case Some(param) => 94 val source = Module(new CHIAsyncBridgeSource(param)) 95 source.io.enq <> tile.module.io.chi.get 96 io.chi.get <> source.io.async 97 case None => 98 require(enableCHI) 99 io.chi.get <> tile.module.io.chi.get 100 } 101 102 dontTouch(io.hartId) 103 dontTouch(io.msiInfo) 104 } 105 lazy val module = new XSTileWrapImp(this) 106} 107