diff --git a/src/main/scala/Example-axi.scala b/src/main/scala/Example-axi.scala index 305558c..4d26bb7 100644 --- a/src/main/scala/Example-axi.scala +++ b/src/main/scala/Example-axi.scala @@ -33,7 +33,7 @@ class AXI4AIA()(implicit p: Parameters) extends LazyModule { toAIA_xbar := toAIA // Here we create 2 imsic groups, each group contains two 2 CPUs - val imsic_params = IMSICParams(EnableImsicAsyncBridge = true) + val imsic_params = IMSICParams(EnableImsicAsyncBridge = true, HasTEEIMSIC = false) val aplic_params = APLICParams(groupsNum = 2, membersNum = 2) val imsics_fromMem_xbar = LazyModule(new AXI4Xbar).node imsics_fromMem_xbar := toAIA_xbar @@ -91,10 +91,7 @@ class AXI4AIA()(implicit p: Parameters) extends LazyModule { } sec_notice_pending.foreach { sec_notice_pending => - imsics(i).module.io_sec.foreach { - instance_iosec => - sec_notice_pending(i) := instance_iosec.notice_pending - } + sec_notice_pending(i) := imsics(i).module.toCSR.notice_pending.get } } } @@ -107,7 +104,7 @@ object AXI4AIA extends App { val axi4top = LazyModule(new AXI4AIA()( Parameters.empty.alterPartial({ - case IMSICParameKey => IMSICParameters(HasTEEIMSIC=false) + case IMSICParameKey => IMSICParameters(HasTEEIMSIC = false) }) )) diff --git a/src/main/scala/Example.scala b/src/main/scala/Example.scala index 04db668..e2d24c6 100644 --- a/src/main/scala/Example.scala +++ b/src/main/scala/Example.scala @@ -88,10 +88,7 @@ class TLAIA()(implicit p: Parameters) extends LazyModule { } } sec_notice_pending.foreach { sec_notice_pending => - imsics(i).module.io_sec.foreach { - instance_iosec => - sec_notice_pending(i) := instance_iosec.notice_pending - } + sec_notice_pending(i) := imsics(i).module.toCSR.notice_pending.get } } } diff --git a/src/main/scala/IMSIC.scala b/src/main/scala/IMSIC.scala index 8beff94..1ca620a 100644 --- a/src/main/scala/IMSIC.scala +++ b/src/main/scala/IMSIC.scala @@ -16,21 +16,23 @@ import utility._ object RegMapDV { def Unwritable = null + def apply(addr: Int, reg: UInt, wfn: UInt => UInt = (x => x)) = (addr, (reg, wfn)) + def generate( - default: UInt, - mapping: Map[Int, (UInt, UInt => UInt)], - raddr: UInt, - rvld: Bool, - rdata: UInt, - rvalid: Bool, - waddr: UInt, - wen: Bool, - wdata: UInt, - wmask: UInt, - illegal_priv: Bool, - illegal_op: Bool - ): Unit = { + default: UInt, + mapping: Map[Int, (UInt, UInt => UInt)], + raddr: UInt, + rvld: Bool, + rdata: UInt, + rvalid: Bool, + waddr: UInt, + wen: Bool, + wdata: UInt, + wmask: UInt, + illegal_priv: Bool, + illegal_op: Bool + ): Unit = { val chiselMapping = mapping.map { case (a, (r, w)) => (a.U, r, w) } when(rvld) { rdata := LookupTreeDefault( @@ -40,7 +42,7 @@ object RegMapDV { ) rvalid := true.B }.otherwise { - rdata := 0.U((rdata.getWidth).W) + rdata := 0.U((rdata.getWidth).W) rvalid := illegal_priv | illegal_op } @@ -52,88 +54,96 @@ object RegMapDV { } } } + def generate( - default: UInt, - mapping: Map[Int, (UInt, UInt => UInt)], - addr: UInt, - rvld: Bool, - rdata: UInt, - rvalid: Bool, - wen: Bool, - wdata: UInt, - wmask: UInt, - illegal_priv: Bool, - illegal_wdata_op: Bool - ): Unit = generate(default, mapping, addr, rvld, rdata, rvalid, addr, wen, wdata, wmask, illegal_priv, illegal_wdata_op) + default: UInt, + mapping: Map[Int, (UInt, UInt => UInt)], + addr: UInt, + rvld: Bool, + rdata: UInt, + rvalid: Bool, + wen: Bool, + wdata: UInt, + wmask: UInt, + illegal_priv: Bool, + illegal_wdata_op: Bool + ): Unit = generate(default, mapping, addr, rvld, rdata, rvalid, addr, wen, wdata, wmask, illegal_priv, illegal_wdata_op) } // Based on Xiangshan NewCSR object OpType extends ChiselEnum { val ILLEGAL = Value(0.U) - val CSRRW = Value(1.U) - val CSRRS = Value(2.U) - val CSRRC = Value(3.U) + val CSRRW = Value(1.U) + val CSRRS = Value(2.U) + val CSRRC = Value(3.U) } + object PrivType extends ChiselEnum { val U = Value(0.U) val S = Value(1.U) val H = Value(2.U) val M = Value(3.U) } + class MSITransBundle(params: IMSICParams) extends Bundle { val vld_req = Input(Bool()) // request from axireg val data = Input(UInt(params.MSI_INFO_WIDTH.W)) - val vld_ack = Output(Bool()) // ack for axireg from imsic. which indicates imsic can work actively. + val vld_ack = Output(Bool()) // ack for axireg from imsic. which indicates imsic can work actively. } + class ForCVMBundle extends Bundle { val cmode = Input(Bool()) // add port: cpu mode is tee or ree - val notice_pending = - Output(Bool()) // add port: interrupt pending of ree when cmode is tee,else interrupt pending of tee. } -class AddrBundle(params: IMSICParams) extends Bundle { - val valid = Bool() // 表示 addr 是否有效 - val bits = new Bundle { + +class AddrBundle(params: IMSICParams) extends Bundle { + val valid = Bool() // 表示 addr 是否有效 + val bits = new Bundle { val addr = UInt(params.iselectWidth.W) // 存储实际地址值 - val virt = Bool() - val priv = PrivType() + val virt = Bool() + val priv = PrivType() } } + class CSRToIMSICBundle(params: IMSICParams) extends Bundle { - val addr = new AddrBundle(params) + val addr = new AddrBundle(params) val vgein = UInt(params.vgeinWidth.W) val wdata = ValidIO(new Bundle { - val op = OpType() + val op = OpType() val data = UInt(params.xlen.W) }) val claims = Vec(params.privNum, Bool()) } + class IMSICToCSRBundle(params: IMSICParams) extends Bundle { - val rdata = ValidIO(UInt(params.xlen.W)) - val illegal = Bool() + val rdata = ValidIO(UInt(params.xlen.W)) + val illegal = Bool() val pendings = UInt(params.intFilesNum.W) - val topeis = Vec(params.privNum, UInt(32.W)) + val topeis = Vec(params.privNum, UInt(32.W)) + // add port: interrupt pending of ree when cmode is tee,else interrupt pending of tee. + val notice_pending = Option.when(params.HasTEEIMSIC)(Output(Bool())) } + case class IMSICParams( - // MC IMSIC中断源数量的对数,默认值8表示IMSIC支持最多256(2^8)个中断源 - - // MC (Logarithm of number of interrupt sources to IMSIC. - // MC The default 8 means IMSIC support at most 256 (2^8) interrupt sources): - // MC{visible} - imsicIntSrcWidth: Int = 8, - // MC 👉 本IMSIC的机器态中断文件的地址(Address of machine-level interrupt files for this IMSIC): - mAddr: Long = 0x00000L, - // MC 👉 本IMSIC的监管态和客户态中断文件的地址(Addr for supervisor-level and guest-level interrupt files for this IMSIC): - sgAddr: Long = 0x10000L, - // MC 👉 客户中断文件的数量(Number of guest interrupt files): - geilen: Int = 7, - // MC vgein信号的位宽(The width of the vgein signal): - vgeinWidth: Int = 6, - // MC iselect信号的位宽(The width of iselect signal): - iselectWidth: Int = 12, - EnableImsicAsyncBridge: Boolean = false, - HasTEEIMSIC: Boolean = false - // MC{hide} -) { + // MC IMSIC中断源数量的对数,默认值8表示IMSIC支持最多256(2^8)个中断源 + + // MC (Logarithm of number of interrupt sources to IMSIC. + // MC The default 8 means IMSIC support at most 256 (2^8) interrupt sources): + // MC{visible} + imsicIntSrcWidth: Int = 8, + // MC 👉 本IMSIC的机器态中断文件的地址(Address of machine-level interrupt files for this IMSIC): + mAddr: Long = 0x00000L, + // MC 👉 本IMSIC的监管态和客户态中断文件的地址(Addr for supervisor-level and guest-level interrupt files for this IMSIC): + sgAddr: Long = 0x10000L, + // MC 👉 客户中断文件的数量(Number of guest interrupt files): + geilen: Int = 7, + // MC vgein信号的位宽(The width of the vgein signal): + vgeinWidth: Int = 6, + // MC iselect信号的位宽(The width of iselect signal): + iselectWidth: Int = 12, + EnableImsicAsyncBridge: Boolean = false, + HasTEEIMSIC: Boolean = false + // MC{hide} + ) { lazy val xlen: Int = 64 // currently only support xlen = 64 lazy val xlenWidth = log2Ceil(xlen) require( @@ -141,7 +151,7 @@ case class IMSICParams( f"imsicIntSrcWidth=${imsicIntSrcWidth}, must not greater than log2(2048)=11, as there are at most 2048 eip/eie bits" + "must not be less than log2(64)=6, as there must be at least 64 eip/eie bits" ) - lazy val privNum: Int = 3 // number of privilege modes: machine, supervisor, virtualized supervisor + lazy val privNum: Int = 3 // number of privilege modes: machine, supervisor, virtualized supervisor lazy val intFilesNum: Int = 2 + geilen // number of interrupt files, m, s, vs0, vs1, ... lazy val eixNum: Int = pow2(imsicIntSrcWidth).toInt / xlen // number of eip/eie registers @@ -152,19 +162,19 @@ case class IMSICParams( f"iselectWidth=${iselectWidth} needs to be able to cover addr [0x70, 0xFF], that is from CSR eidelivery to CSR eie63" ) lazy val INTP_FILE_WIDTH = log2Ceil(intFilesNum) - lazy val MSI_INFO_WIDTH = imsicIntSrcWidth + INTP_FILE_WIDTH + lazy val MSI_INFO_WIDTH = imsicIntSrcWidth + INTP_FILE_WIDTH } class IMSIC( - params: IMSICParams, - beatBytes: Int = 4 -)(implicit p: Parameters) extends Module { + params: IMSICParams, + beatBytes: Int = 4 + )(implicit p: Parameters) extends Module { println(f"IMSICParams.geilen: ${params.geilen}%d") class IMSICGateWay extends Module { // === io port define === val msiio = IO(new MSITransBundle(params)) - val msi_data_o = IO(Output(UInt(params.imsicIntSrcWidth.W))) + val msi_data_o = IO(Output(UInt(params.imsicIntSrcWidth.W))) val msi_valid_o = IO(Output(UInt(params.intFilesNum.W))) // === main body === @@ -185,47 +195,50 @@ class IMSIC( // generate the msi_vld_ack,to handle with the input msi request. msiio.vld_ack := msi_vld_ack_cpu val msi_vld_ris_cpu = msi_vld_req_cpu & (~msi_vld_ack_cpu) // rising of msi_vld_req - val msi_data_catch = RegInit(0.U(params.imsicIntSrcWidth.W)) + val msi_data_catch = RegInit(0.U(params.imsicIntSrcWidth.W)) val msi_intf_valids = RegInit(0.U(params.intFilesNum.W)) - msi_data_o := msi_data_catch(params.imsicIntSrcWidth - 1, 0) + msi_data_o := msi_data_catch(params.imsicIntSrcWidth - 1, 0) msi_valid_o := msi_intf_valids // multi-bis switch vector when(msi_vld_ris_cpu) { msi_data_catch := msi_in(params.imsicIntSrcWidth - 1, 0) - msi_intf_valids := 1.U << msi_in(params.MSI_INFO_WIDTH - 1,params.imsicIntSrcWidth) + msi_intf_valids := 1.U << msi_in(params.MSI_INFO_WIDTH - 1, params.imsicIntSrcWidth) }.otherwise { msi_intf_valids := 0.U } } + class IntFile extends Module { override def desiredName = "IntFile" + val fromCSR = IO(Input(new Bundle { val seteipnum = ValidIO(UInt(params.imsicIntSrcWidth.W)) - val addr = ValidIO(UInt(params.iselectWidth.W)) - val virt = Bool() - val priv = PrivType() - val vgein = UInt(params.vgeinWidth.W) + val addr = ValidIO(UInt(params.iselectWidth.W)) + val virt = Bool() + val priv = PrivType() + val vgein = UInt(params.vgeinWidth.W) val wdata = ValidIO(new Bundle { - val op = OpType() + val op = OpType() val data = UInt(params.xlen.W) }) val claim = Bool() })) val toCSR = IO(Output(new Bundle { - val rdata = ValidIO(UInt(params.xlen.W)) + val rdata = ValidIO(UInt(params.xlen.W)) val illegal = Bool() val pending = Bool() - val topei = UInt(params.imsicIntSrcWidth.W) + val topei = UInt(params.imsicIntSrcWidth.W) + // add port: interrupt pending of ree when cmode is tee,else interrupt pending of tee. })) val illegal_io = IO(new Bundle { val illegal_priv = Input(Bool()) }) val illegal_priv = illegal_io.illegal_priv - + /// indirect CSRs - val eidelivery = RegInit(0.U(params.xlen.W)) + val eidelivery = RegInit(0.U(params.xlen.W)) val eithreshold = RegInit(0.U(params.xlen.W)) - val eips = RegInit(VecInit.fill(params.eixNum)(0.U(params.xlen.W))) - val eies = RegInit(VecInit.fill(params.eixNum)(0.U(params.xlen.W))) + val eips = RegInit(VecInit.fill(params.eixNum)(0.U(params.xlen.W))) + val eies = RegInit(VecInit.fill(params.eixNum)(0.U(params.xlen.W))) val illegal_wdata_op = WireDefault(false.B) locally { // scope for xiselect CSR reg map @@ -250,8 +263,11 @@ class IMSIC( } } } + def bit0ReadOnlyZero(x: UInt): UInt = x & ~1.U(x.getWidth.W) + def fixEIDelivery(x: UInt): UInt = x & 1.U + RegMapDV.generate( 0.U, Map( @@ -264,26 +280,26 @@ class IMSIC( } ++ eies.drop(1).zipWithIndex.map { case (eie: UInt, i: Int) => RegMapDV(0xc2 + i * 2, eie) }, - /*raddr*/ fromCSR.addr.bits, - /*rvld */ fromCSR.addr.valid, - /*rdata*/ toCSR.rdata.bits, + /*raddr*/ fromCSR.addr.bits, + /*rvld */ fromCSR.addr.valid, + /*rdata*/ toCSR.rdata.bits, /*rvalid*/ toCSR.rdata.valid, - /*waddr*/ fromCSR.addr.bits, - /*wen */ fromCSR.wdata.valid, - /*wdata*/ wdata, - /*wmask*/ wmask, - /*priv*/ illegal_priv, - /*op*/ illegal_wdata_op + /*waddr*/ fromCSR.addr.bits, + /*wen */ fromCSR.wdata.valid, + /*wdata*/ wdata, + /*wmask*/ wmask, + /*priv*/ illegal_priv, + /*op*/ illegal_wdata_op ) val illegal_csr = WireDefault(false.B) when(fromCSR.addr.bits >= 0x80.U && fromCSR.addr.bits <= 0xFF.U && fromCSR.addr.bits(0) === 1.U) { - illegal_csr := true.B + illegal_csr := true.B } toCSR.illegal := illegal_csr } locally { - val index = fromCSR.seteipnum.bits(params.imsicIntSrcWidth - 1, params.xlenWidth) + val index = fromCSR.seteipnum.bits(params.imsicIntSrcWidth - 1, params.xlenWidth) val offset = fromCSR.seteipnum.bits(params.xlenWidth - 1, 0) when(fromCSR.seteipnum.valid) { // set eips bit @@ -300,15 +316,16 @@ class IMSIC( // [0, 2^intSrcWidth-1] :+ 2^intSrcWidth val eipBools = Cat(eips.reverse).asBools :+ true.B val eieBools = Cat(eies.reverse).asBools :+ true.B - + def xtopei_filter(xeidelivery: UInt, xeithreshold: UInt, xtopei: UInt): UInt = { - val tmp_xtopei = Mux(xeidelivery(params.xlen - 1, 1) === 0.U, Mux(xeidelivery(0), xtopei, 0.U) , 0.U) + val tmp_xtopei = Mux(xeidelivery(params.xlen - 1, 1) === 0.U, Mux(xeidelivery(0), xtopei, 0.U), 0.U) // { // all interrupts are enabled, when eithreshold == 1; // interrupts, when i < eithreshold, are enabled; // } <=> interrupts, when i <= (eithreshold -1), are enabled Mux(tmp_xtopei <= (xeithreshold - 1.U), tmp_xtopei, 0.U) } + toCSR.topei := xtopei_filter( eidelivery, eithreshold, @@ -322,71 +339,79 @@ class IMSIC( toCSR.pending := toCSR.topei =/= 0.U when(fromCSR.claim) { - val index = toCSR.topei(params.imsicIntSrcWidth - 1, params.xlenWidth) + val index = toCSR.topei(params.imsicIntSrcWidth - 1, params.xlenWidth) val offset = toCSR.topei(params.xlenWidth - 1, 0) // clear the pending bit indexed by xtopei in xeip eips(index) := eips(index) & ~UIntToOH(offset) } } - val toCSR = IO(Output(new IMSICToCSRBundle(params))) + + val toCSR = IO(Output(new IMSICToCSRBundle(params))) val fromCSR = IO(Input(new CSRToIMSICBundle(params))) - val msiio = IO(new MSITransBundle(params)) + val msiio = IO(new MSITransBundle(params)) val illegal_priv = WireInit(false.B) private val intFilesSelOH_r = WireDefault(0.U(params.intFilesNum.W)) private val intFilesSelOH_w = WireDefault(0.U(params.intFilesNum.W)) locally { - when (fromCSR.addr.valid) - { - when(fromCSR.addr.bits.virt === false.B ) - { - when(((fromCSR.addr.bits.priv.asUInt === 3.U) || (fromCSR.addr.bits.priv.asUInt === 1.U)) && fromCSR.vgein === 0.U){ + when(fromCSR.addr.valid) { + when(fromCSR.addr.bits.virt === false.B) { + when(((fromCSR.addr.bits.priv.asUInt === 3.U) || (fromCSR.addr.bits.priv.asUInt === 1.U)) && fromCSR.vgein === 0.U) { illegal_priv := false.B - }.otherwise{ + }.otherwise { illegal_priv := true.B } - }.otherwise{ - when(fromCSR.addr.bits.priv.asUInt === 1.U && (fromCSR.vgein >= 1.U) && (fromCSR.vgein < (params.geilen + 1).U(params.vgeinWidth.W))) - { + }.otherwise { + when(fromCSR.addr.bits.priv.asUInt === 1.U && (fromCSR.vgein >= 1.U) && (fromCSR.vgein < (params.geilen + 1).U(params.vgeinWidth.W))) { illegal_priv := false.B - }.otherwise{ + }.otherwise { illegal_priv := true.B } } } - when (fromCSR.addr.valid && !illegal_priv) // read + when(fromCSR.addr.valid && !illegal_priv) // read { val pv = Cat(fromCSR.addr.bits.priv.asUInt, fromCSR.addr.bits.virt) - when(pv === Cat(PrivType.M.asUInt, false.B)){intFilesSelOH_r := UIntToOH(0.U)} - .elsewhen(pv === Cat(PrivType.S.asUInt, false.B)){intFilesSelOH_r := UIntToOH(1.U)} - .elsewhen(pv === Cat(PrivType.S.asUInt, true.B)){intFilesSelOH_r := UIntToOH(1.U((fromCSR.vgein.getWidth+1).W) - + fromCSR.vgein.pad(params.vgeinWidth+1)) + when(pv === Cat(PrivType.M.asUInt, false.B)) { + intFilesSelOH_r := UIntToOH(0.U) } + .elsewhen(pv === Cat(PrivType.S.asUInt, false.B)) { + intFilesSelOH_r := UIntToOH(1.U) + } + .elsewhen(pv === Cat(PrivType.S.asUInt, true.B)) { + intFilesSelOH_r := UIntToOH(1.U((fromCSR.vgein.getWidth + 1).W) + + fromCSR.vgein.pad(params.vgeinWidth + 1)) + } } - when (fromCSR.addr.valid && fromCSR.wdata.valid && !(fromCSR.wdata.bits.op.asUInt === 0.U) && !illegal_priv) // write + when(fromCSR.addr.valid && fromCSR.wdata.valid && !(fromCSR.wdata.bits.op.asUInt === 0.U) && !illegal_priv) // write { - val pv = Cat(fromCSR.addr.bits.priv.asUInt, fromCSR.addr.bits.virt) - when(pv === Cat(PrivType.M.asUInt, false.B)){intFilesSelOH_w := UIntToOH(0.U)} - .elsewhen(pv === Cat(PrivType.S.asUInt, false.B)){intFilesSelOH_w := UIntToOH(1.U)} - .elsewhen(pv === Cat(PrivType.S.asUInt, true.B)){intFilesSelOH_w := UIntToOH(1.U((fromCSR.vgein.getWidth+1).W) - + fromCSR.vgein.pad(params.vgeinWidth+1)) + val pv = Cat(fromCSR.addr.bits.priv.asUInt, fromCSR.addr.bits.virt) + when(pv === Cat(PrivType.M.asUInt, false.B)) { + intFilesSelOH_w := UIntToOH(0.U) + } + .elsewhen(pv === Cat(PrivType.S.asUInt, false.B)) { + intFilesSelOH_w := UIntToOH(1.U) + } + .elsewhen(pv === Cat(PrivType.S.asUInt, true.B)) { + intFilesSelOH_w := UIntToOH(1.U((fromCSR.vgein.getWidth + 1).W) + + fromCSR.vgein.pad(params.vgeinWidth + 1)) } } } - private val topeis_forEachIntFiles = Wire(Vec(params.intFilesNum, UInt(params.imsicIntSrcWidth.W))) + private val topeis_forEachIntFiles = Wire(Vec(params.intFilesNum, UInt(params.imsicIntSrcWidth.W))) private val illegals_forEachIntFiles = Wire(Vec(params.intFilesNum, Bool())) // instance and connect IMSICGateWay. val imsicGateWay = Module(new IMSICGateWay) imsicGateWay.msiio <> msiio - val pendings = Wire(Vec(params.intFilesNum,Bool())) + val pendings = Wire(Vec(params.intFilesNum, Bool())) val vec_rdata = Wire(Vec(params.intFilesNum, ValidIO(UInt(params.xlen.W)))) Seq(1, 1 + params.geilen).zipWithIndex.map { case (intFilesNum: Int, i: Int) => { // j: index for S intFile: S, G1, G2, ... val maps = (0 until intFilesNum).map { j => val flati = i + j - val pi = if (flati > 2) 2 else flati // index for privileges: M, S, VS. + val pi = if (flati > 2) 2 else flati // index for privileges: M, S, VS. def sel_addr(old: AddrBundle): AddrBundle = { val new_ = Wire(new AddrBundle(params)) @@ -396,40 +421,41 @@ class IMSIC( new_.bits.priv := old.bits.priv new_ } + def sel_wdata[T <: Data](old: Valid[T]): Valid[T] = { val new_ = Wire(Valid(chiselTypeOf(old.bits))) - new_.bits := old.bits + new_.bits := old.bits new_.valid := old.valid & intFilesSelOH_w(flati) new_ } val intFile = Module(new IntFile) // Preventing overflow - when (flati.U((params.vgeinWidth + 1).W) === fromCSR.vgein.pad(params.vgeinWidth + 1)+1.U) { + when(flati.U((params.vgeinWidth + 1).W) === fromCSR.vgein.pad(params.vgeinWidth + 1) + 1.U) { intFile.fromCSR.vgein := fromCSR.vgein - } .otherwise { + }.otherwise { intFile.fromCSR.vgein := 0.U } val intfile_rdata_d = RegNext(intFile.toCSR.rdata) - intFile.fromCSR.seteipnum.bits := imsicGateWay.msi_data_o + intFile.fromCSR.seteipnum.bits := imsicGateWay.msi_data_o intFile.fromCSR.seteipnum.valid := imsicGateWay.msi_valid_o(flati) - intFile.fromCSR.addr.valid := sel_addr(fromCSR.addr).valid - intFile.fromCSR.addr.bits := sel_addr(fromCSR.addr).bits.addr - intFile.fromCSR.virt := sel_addr(fromCSR.addr).bits.virt - intFile.fromCSR.priv := sel_addr(fromCSR.addr).bits.priv - intFile.fromCSR.wdata := sel_wdata(fromCSR.wdata) - intFile.fromCSR.claim := fromCSR.claims(pi) + intFile.fromCSR.addr.valid := sel_addr(fromCSR.addr).valid + intFile.fromCSR.addr.bits := sel_addr(fromCSR.addr).bits.addr + intFile.fromCSR.virt := sel_addr(fromCSR.addr).bits.virt + intFile.fromCSR.priv := sel_addr(fromCSR.addr).bits.priv + intFile.fromCSR.wdata := sel_wdata(fromCSR.wdata) + intFile.fromCSR.claim := fromCSR.claims(pi) intFile.illegal_io.illegal_priv := illegal_priv - vec_rdata(flati) := intfile_rdata_d - pendings(flati) := intFile.toCSR.pending - topeis_forEachIntFiles(flati) := intFile.toCSR.topei + vec_rdata(flati) := intfile_rdata_d + pendings(flati) := intFile.toCSR.pending + topeis_forEachIntFiles(flati) := intFile.toCSR.topei illegals_forEachIntFiles(flati) := intFile.toCSR.illegal } } } - toCSR.rdata.valid := vec_rdata.map(_.valid).reduce(_|_) - toCSR.rdata.bits := vec_rdata.map(_.bits).reduce(_|_) - toCSR.pendings := (pendings.zipWithIndex.map{case (p,i) => p << i.U}).reduce(_ | _) //vector -> multi-bit + toCSR.rdata.valid := vec_rdata.map(_.valid).reduce(_ | _) + toCSR.rdata.bits := vec_rdata.map(_.bits).reduce(_ | _) + toCSR.pendings := (pendings.zipWithIndex.map { case (p, i) => p << i.U }).reduce(_ | _) //vector -> multi-bit locally { // Format of *topei: // * bits 26:16 Interrupt identity @@ -441,6 +467,7 @@ class IMSIC( val zeros = 0.U((16 - params.imsicIntSrcWidth).W) Cat(zeros, topei, zeros, topei) } + val pv = Cat(fromCSR.addr.bits.priv.asUInt, fromCSR.addr.bits.virt) toCSR.topeis(0) := wrap(topeis_forEachIntFiles(0)) // m toCSR.topeis(1) := wrap(topeis_forEachIntFiles(1)) // s @@ -448,22 +475,23 @@ class IMSIC( UIntToOH(fromCSR.vgein - 1.U, params.geilen).asBools, topeis_forEachIntFiles.drop(2) )) // vs - } + } val toCSR_illegal_d = RegNext((fromCSR.addr.valid | fromCSR.wdata.valid) & Seq( illegals_forEachIntFiles.reduce(_ | _), (fromCSR.wdata.valid && fromCSR.wdata.bits.op.asUInt === 0.U), illegal_priv ).reduce(_ | _)) toCSR.illegal := toCSR_illegal_d + toCSR.notice_pending.foreach(_ := false.B) } //define IMSIC_WRAP: instance one imsic when HasCVMExtention is supported, else instance two imsic modules. class IMSIC_WRAP( - params: IMSICParams, - beatBytes: Int = 4 -)(implicit p: Parameters) extends Module { + params: IMSICParams, + beatBytes: Int = 4 + )(implicit p: Parameters) extends Module { // define the ports - val toCSR = IO(Output(new IMSICToCSRBundle(params))) + val toCSR = IO(Output(new IMSICToCSRBundle(params))) val fromCSR = IO(Input(new CSRToIMSICBundle(params))) val msiio = IO(new MSITransBundle(params)) // define additional ports when HasCVMExtention is supported. @@ -473,47 +501,47 @@ class IMSIC_WRAP( // instance module,and body logic private val imsic = Module(new IMSIC(params, beatBytes)) imsic.fromCSR := fromCSR - toCSR := imsic.toCSR + toCSR := imsic.toCSR imsic.msiio <> msiio // define additional logic for sec extention // .foreach logic only happens when sec is not none. sec.foreach { secIO => // get the sec.mode, connect sec.o_notice_pending to top. - val cmode = Wire(Bool()) - val notice_pending = Wire(Bool()) - cmode := secIO.cmode - secIO.notice_pending := notice_pending + val cmode = RegInit(false.B) + val notice_pending = RegInit(false.B) + cmode := secIO.cmode + toCSR.notice_pending.foreach(_ := notice_pending) // instance tee imsic module. val teeimsic = Module(new IMSIC(params, beatBytes)) teemsiio.foreach(teemsiio => teeimsic.msiio <> teemsiio) - toCSR.rdata := Mux(cmode, teeimsic.toCSR.rdata, imsic.toCSR.rdata) // toCSR needs to the selected depending cmode. + toCSR.rdata := Mux(cmode, teeimsic.toCSR.rdata, imsic.toCSR.rdata) // toCSR needs to the selected depending cmode. toCSR.illegal := Mux(cmode, teeimsic.toCSR.illegal, imsic.toCSR.illegal) - val s_pendings = Mux(cmode, teeimsic.toCSR.pendings(params.intFilesNum-1,1), imsic.toCSR.pendings(params.intFilesNum-1,1)) + val s_pendings = Mux(cmode, teeimsic.toCSR.pendings(params.intFilesNum - 1, 1), imsic.toCSR.pendings(params.intFilesNum - 1, 1)) val m_pendings = imsic.toCSR.pendings(0) // machine mode only from imsic. - toCSR.pendings := Cat(s_pendings,m_pendings) + toCSR.pendings := Cat(s_pendings, m_pendings) // toCSR.pendings := VecInit((0 until params.intFilesNum).map(i => pendings(i))) // uint->vector - - toCSR.topeis := Mux(cmode, teeimsic.toCSR.topeis, imsic.toCSR.topeis) + + toCSR.topeis := Mux(cmode, teeimsic.toCSR.topeis, imsic.toCSR.topeis) toCSR.topeis(0) := imsic.toCSR.topeis(0) // machine mode only from imsic. // to get the o_notice_pending, excluding the machine interrupt -// val s_orpend_ree = imsic.toCSR.pendings.slice(1, params.intFilesNum) // extract the | of vector(1,N-1) -// val s_orpend_tee = teeimsic.toCSR.pendings.slice(1, params.intFilesNum) -// notice_pending := Mux(cmode, s_orpend_ree.reduce(_ | _), s_orpend_tee.reduce(_ | _)) - val s_orpend_ree = imsic.toCSR.pendings(params.intFilesNum-1,1) // extract the | of vector(1,N-1) - val s_orpend_tee = teeimsic.toCSR.pendings(params.intFilesNum-1,1) //bit(params.intFilesNum-1:1) - notice_pending := Mux(cmode, s_orpend_ree.orR, s_orpend_tee.orR) + // val s_orpend_ree = imsic.toCSR.pendings.slice(1, params.intFilesNum) // extract the | of vector(1,N-1) + // val s_orpend_tee = teeimsic.toCSR.pendings.slice(1, params.intFilesNum) + // notice_pending := Mux(cmode, s_orpend_ree.reduce(_ | _), s_orpend_tee.reduce(_ | _)) + val s_orpend_ree = imsic.toCSR.pendings(params.intFilesNum - 1, 1) // extract the | of vector(1,N-1) + val s_orpend_tee = teeimsic.toCSR.pendings(params.intFilesNum - 1, 1) //bit(params.intFilesNum-1:1) + notice_pending := Mux(cmode, s_orpend_ree.orR, s_orpend_tee.orR) teeimsic.fromCSR := fromCSR teeimsic.fromCSR.addr.valid := cmode & fromCSR.addr.valid // cmode=1,controls tee csr access to interrupt file indirectly teeimsic.fromCSR.wdata.valid := cmode & fromCSR.wdata.valid - teeimsic.fromCSR.claims(0) := false.B // machine interrupts are inactive for tee imsic. + teeimsic.fromCSR.claims(0) := false.B // machine interrupts are inactive for tee imsic. for (i <- 1 until params.privNum) { teeimsic.fromCSR.claims(i) := cmode & fromCSR.claims(i) } imsic.fromCSR.addr.valid := (cmode === false.B) & fromCSR.addr.valid // cmode=1,controls tee csr access to interrupt file indirectly imsic.fromCSR.wdata.valid := (cmode === false.B) & fromCSR.wdata.valid - imsic.fromCSR.claims(0) := fromCSR.claims(0) // machine interrupts are inactive for tee imsic. + imsic.fromCSR.claims(0) := fromCSR.claims(0) // machine interrupts are inactive for tee imsic. for (i <- 1 until params.privNum) { imsic.fromCSR.claims(i) := (cmode === false.B) & fromCSR.claims(i) } @@ -522,16 +550,16 @@ class IMSIC_WRAP( //generate TLIMSIC top module:including TLRegIMSIC_WRAP and IMSIC_WRAP class TLIMSIC( - params: IMSICParams, - beatBytes: Int = 4 -// asyncQueueParams: AsyncQueueParams -)(implicit p: Parameters) extends LazyModule with HasIMSICParameters { - val axireg = LazyModule(new TLRegIMSIC_WRAP(IMSICParams(HasTEEIMSIC = GHasTEEIMSIC), beatBytes)) + params: IMSICParams, + beatBytes: Int = 4 + // asyncQueueParams: AsyncQueueParams + )(implicit p: Parameters) extends LazyModule with HasIMSICParameters { + val axireg = LazyModule(new TLRegIMSIC_WRAP(IMSICParams(HasTEEIMSIC = GHasTEEIMSIC), beatBytes)) lazy val module = new Imp class Imp extends LazyModuleImp(this) { - val toCSR = IO(Output(new IMSICToCSRBundle(params))) - val fromCSR = IO(Input(new CSRToIMSICBundle(params))) + val toCSR = IO(Output(new IMSICToCSRBundle(params))) + val fromCSR = IO(Input(new CSRToIMSICBundle(params))) private val imsic = Module(new IMSIC_WRAP(IMSICParams(HasTEEIMSIC = GHasTEEIMSIC), beatBytes)) toCSR := imsic.toCSR imsic.fromCSR := fromCSR @@ -545,8 +573,8 @@ class TLIMSIC( val soc_reset = IO(Input(Reset())) axireg.module.clock := soc_clock axireg.module.reset := soc_reset - imsic.clock := clock - imsic.reset := reset + imsic.clock := clock + imsic.reset := reset axireg.module.msiio <> imsic.msiio // msi_req/msi_ack interconnect // code will be compiled only when io_sec is not None. io_sec.foreach(iosec => imsic.sec.foreach(imsicsec => imsicsec <> iosec)) @@ -556,14 +584,15 @@ class TLIMSIC( } class AXI4IMSIC( - params: IMSICParams, - beatBytes: Int = 4 -)(implicit p: Parameters) extends LazyModule with HasIMSICParameters { - val axireg = LazyModule(new AXIRegIMSIC_WRAP(IMSICParams(HasTEEIMSIC = GHasTEEIMSIC), beatBytes)) + params: IMSICParams, + beatBytes: Int = 4 + )(implicit p: Parameters) extends LazyModule with HasIMSICParameters { + val axireg = LazyModule(new AXIRegIMSIC_WRAP(IMSICParams(HasTEEIMSIC = GHasTEEIMSIC), beatBytes)) lazy val module = new Imp + class Imp extends LazyModuleImp(this) { - val toCSR = IO(Output(new IMSICToCSRBundle(params))) - val fromCSR = IO(Input(new CSRToIMSICBundle(params))) + val toCSR = IO(Output(new IMSICToCSRBundle(params))) + val fromCSR = IO(Input(new CSRToIMSICBundle(params))) private val imsic = Module(new IMSIC_WRAP(IMSICParams(HasTEEIMSIC = GHasTEEIMSIC), beatBytes)) toCSR := imsic.toCSR imsic.fromCSR := fromCSR @@ -577,8 +606,8 @@ class AXI4IMSIC( val soc_reset = IO(Input(Reset())) axireg.module.clock := soc_clock axireg.module.reset := soc_reset - imsic.clock := clock - imsic.reset := reset + imsic.clock := clock + imsic.reset := reset // code will be compiled only when io_sec is not None. io_sec.foreach(iosec => imsic.sec.foreach(imsicsec => imsicsec <> iosec)) // code will be compiled only when tee_axireg is not None. @@ -590,9 +619,9 @@ class AXI4IMSIC( // code below is for SEC IMSIC spec //generate TLRegIMSIC_WRAP for IMSIC, when HasCVMExtention is supported, IMSIC is instantiated by two times,else only one class TLRegIMSIC_WRAP( - params: IMSICParams, - beatBytes: Int = 4 -)(implicit p: Parameters) extends LazyModule { + params: IMSICParams, + beatBytes: Int = 4 + )(implicit p: Parameters) extends LazyModule { val axireg = LazyModule(new TLRegIMSIC(params, beatBytes)(Parameters.empty)) val tee_axireg = if (params.HasTEEIMSIC) Some(LazyModule(new TLRegIMSIC(params, beatBytes)(Parameters.empty))) else None @@ -602,7 +631,7 @@ class TLRegIMSIC_WRAP( val msiio = IO(Flipped(new MSITransBundle(params))) msiio <> axireg.module.msiio val teemsiio = if (params.HasTEEIMSIC) Some(IO(Flipped(new MSITransBundle(params)))) - else None // backpressure signal for axi4bus, from imsic working on cpu clock + else None // backpressure signal for axi4bus, from imsic working on cpu clock // code below will be compiled only when teeio is not none. teemsiio.foreach(teemsiio => tee_axireg.foreach(tee_axireg => teemsiio <> tee_axireg.module.msiio)) @@ -611,9 +640,9 @@ class TLRegIMSIC_WRAP( //generate AXIRegIMSIC_WRAP for IMSIC, when HasCVMExtention is supported, IMSIC is instantiated by two times,else only one class AXIRegIMSIC_WRAP( - params: IMSICParams, - beatBytes: Int = 4 -)(implicit p: Parameters) extends LazyModule { + params: IMSICParams, + beatBytes: Int = 4 + )(implicit p: Parameters) extends LazyModule { val axireg = LazyModule(new AXIRegIMSIC(params, beatBytes)(Parameters.empty)) // val tee_axireg = if (params.HasTEEIMSIC) Some(LazyModule(new AXIRegIMSIC(IMSICParams(teemode = true), beatBytes)(Parameters.empty))) else None val tee_axireg = @@ -631,10 +660,10 @@ class AXIRegIMSIC_WRAP( } class TLRegIMSIC( - params: IMSICParams, - beatBytes: Int = 4, - seperateBus: Boolean = false -)(implicit p: Parameters) extends LazyModule { + params: IMSICParams, + beatBytes: Int = 4, + seperateBus: Boolean = false + )(implicit p: Parameters) extends LazyModule { val fromMem = Seq.fill(if (seperateBus) 2 else 1)(TLXbar()) // val fromMem = LazyModule(new TLXbar).node private val intfileFromMems = Seq( @@ -650,26 +679,27 @@ class TLRegIMSIC( } lazy val module = new TLRegIMSICImp(this) + class TLRegIMSICImp(outer: LazyModule) extends LazyModuleImp(outer) { - val msiio = IO(Flipped(new MSITransBundle(params))) // backpressure signal for axi4bus, from imsic working on cpu clock + val msiio = IO(Flipped(new MSITransBundle(params))) // backpressure signal for axi4bus, from imsic working on cpu clock private val reggen = Module(new RegGen(params, beatBytes)) // ---- instance sync fifo ----// // --- fifo wdata: {vector_valid,setipnum}, fifo wren: |vector_valid---// val FifoDataWidth = params.MSI_INFO_WIDTH - val fifo_wdata = Wire(Valid(UInt(FifoDataWidth.W))) + val fifo_wdata = Wire(Valid(UInt(FifoDataWidth.W))) // depth:8, data width: FifoDataWidth private val fifo_sync = Module(new Queue(UInt(FifoDataWidth.W), 8)) // define about fifo write - fifo_wdata.bits := reggen.io.seteipnum - fifo_wdata.valid := reggen.io.valid + fifo_wdata.bits := reggen.io.seteipnum + fifo_wdata.valid := reggen.io.valid fifo_sync.io.enq.valid := fifo_wdata.valid - fifo_sync.io.enq.bits := fifo_wdata.bits + fifo_sync.io.enq.bits := fifo_wdata.bits // fifo rd,controlled by msi_vld_ack from imsic working on csr clock. // msi_vld_ack_soc: sync result with soc clock val msi_vld_ack_soc = WireInit(false.B) val msi_vld_ack_cpu = msiio.vld_ack - val msi_vld_req = RegInit(false.B) + val msi_vld_req = RegInit(false.B) when(params.EnableImsicAsyncBridge.B) { msi_vld_ack_soc := AsyncResetSynchronizerShiftReg(msi_vld_ack_cpu, 3, 0) }.otherwise { @@ -678,7 +708,7 @@ class TLRegIMSIC( fifo_sync.io.deq.ready := ~msi_vld_req // generate the msi_vld_req: high if ~empty,low when msi_vld_ack_soc msiio.vld_req := msi_vld_req - val msi_vld_ack_soc_1f = RegNext(msi_vld_ack_soc) + val msi_vld_ack_soc_1f = RegNext(msi_vld_ack_soc) val msi_vld_ack_soc_ris = msi_vld_ack_soc & (~msi_vld_ack_soc_1f) // val fifo_empty = ~fifo_sync.io.deq.valid // msi_vld_req : high when fifo empty is false, low when ack is high. and io.deq.valid := ~empty @@ -692,7 +722,7 @@ class TLRegIMSIC( // get the msi interrupt ID info val msi_id_data = RegInit(0.U(params.MSI_INFO_WIDTH.W)) - val rdata_vld = fifo_sync.io.deq.fire // assign to fifo rdata + val rdata_vld = fifo_sync.io.deq.fire // assign to fifo rdata when(rdata_vld) { // fire: io.deq.valid & io.deq.ready msi_id_data := fifo_sync.io.deq.bits(params.MSI_INFO_WIDTH - 1, 0) }.otherwise { @@ -710,10 +740,10 @@ class TLRegIMSIC( //generate axi42reg for IMSIC class AXIRegIMSIC( - params: IMSICParams, - beatBytes: Int = 4, - seperateBus: Boolean = false -)(implicit p: Parameters) extends LazyModule { + params: IMSICParams, + beatBytes: Int = 4, + seperateBus: Boolean = false + )(implicit p: Parameters) extends LazyModule { val fromMem = Seq.fill(if (seperateBus) 2 else 1)(AXI4Xbar()) val axi4tolite = Seq.fill(if (seperateBus) 2 else 1)(LazyModule(new AXI4ToLite()(Parameters.empty))) fromMem zip axi4tolite.map(_.node) foreach (x => x._1 := x._2) @@ -728,28 +758,29 @@ class AXIRegIMSIC( intfileFromMem := (if (seperateBus) fromMem(i) else fromMem.head) intfileFromMem } - + lazy val module = new AXIRegIMSICImp(this) + class AXIRegIMSICImp(outer: LazyModule) extends LazyModuleImp(outer) { - val msiio = IO(Flipped(new MSITransBundle(params))) // backpressure signal for axi4bus, from imsic working on cpu clock + val msiio = IO(Flipped(new MSITransBundle(params))) // backpressure signal for axi4bus, from imsic working on cpu clock private val reggen = Module(new RegGen(params, beatBytes)) // ---- instance sync fifo ----// // --- fifo wdata: {vector_valid,setipnum}, fifo wren: |vector_valid---// val FifoDataWidth = params.MSI_INFO_WIDTH - val fifo_wdata = Wire(Valid(UInt(FifoDataWidth.W))) + val fifo_wdata = Wire(Valid(UInt(FifoDataWidth.W))) // depth:8, data width: FifoDataWidth private val fifo_sync = Module(new Queue(UInt(FifoDataWidth.W), 8)) // define about fifo write - fifo_wdata.bits := reggen.io.seteipnum - fifo_wdata.valid := reggen.io.valid + fifo_wdata.bits := reggen.io.seteipnum + fifo_wdata.valid := reggen.io.valid fifo_sync.io.enq.valid := fifo_wdata.valid - fifo_sync.io.enq.bits := fifo_wdata.bits + fifo_sync.io.enq.bits := fifo_wdata.bits // fifo rd,controlled by msi_vld_ack from imsic working on csr clock. // msi_vld_ack_soc: sync result with soc clock val msi_vld_ack_soc = WireInit(false.B) val msi_vld_ack_cpu = msiio.vld_ack - val msi_vld_req = RegInit(false.B) + val msi_vld_req = RegInit(false.B) when(params.EnableImsicAsyncBridge.B) { msi_vld_ack_soc := AsyncResetSynchronizerShiftReg(msi_vld_ack_cpu, 3, 0) }.otherwise { @@ -758,7 +789,7 @@ class AXIRegIMSIC( fifo_sync.io.deq.ready := ~msi_vld_req // generate the msi_vld_req: high if ~empty,low when msi_vld_ack_soc msiio.vld_req := msi_vld_req - val msi_vld_ack_soc_1f = RegNext(msi_vld_ack_soc) + val msi_vld_ack_soc_1f = RegNext(msi_vld_ack_soc) val msi_vld_ack_soc_ris = msi_vld_ack_soc & (~msi_vld_ack_soc_1f) // val fifo_empty = ~fifo_sync.io.deq.valid // msi_vld_req : high when fifo empty is false, low when ack is high. and io.deq.valid := ~empty @@ -772,7 +803,7 @@ class AXIRegIMSIC( // get the msi interrupt ID info val msi_id_data = RegInit(0.U(params.MSI_INFO_WIDTH.W)) - val rdata_vld = fifo_sync.io.deq.fire // assign to fifo rdata + val rdata_vld = fifo_sync.io.deq.fire // assign to fifo rdata when(rdata_vld) { // fire: io.deq.valid & io.deq.ready msi_id_data := fifo_sync.io.deq.bits(params.MSI_INFO_WIDTH - 1, 0) }.otherwise { @@ -789,9 +820,9 @@ class AXIRegIMSIC( //integrated for async clock domain,kmh,zhaohong class RegGen( - params: IMSICParams, - beatBytes: Int = 4 -) extends Module { + params: IMSICParams, + beatBytes: Int = 4 + ) extends Module { val regmapIOs = Seq( params.intFileMemWidth, params.intFileMemWidth + log2Ceil(1 + params.geilen) @@ -802,40 +833,42 @@ class RegGen( // define the output reg: seteipnum is the MSI id,vld[],valid flag for interrupt file domains: m,s,vs1~vsgeilen val io = IO(Output(new Bundle { val seteipnum = UInt(params.MSI_INFO_WIDTH.W) - val valid = Bool() + val valid = Bool() })) - val valids = WireInit(VecInit(Seq.fill(params.intFilesNum)(false.B))) - val seteipnums = WireInit(VecInit(Seq.fill(params.intFilesNum)(0.U(params.imsicIntSrcWidth.W)))) + val valids = WireInit(VecInit(Seq.fill(params.intFilesNum)(false.B))) + val seteipnums = WireInit(VecInit(Seq.fill(params.intFilesNum)(0.U(params.imsicIntSrcWidth.W)))) val outseteipnum = RegInit(0.U(params.MSI_INFO_WIDTH.W)) - val outvalids = RegInit(VecInit(Seq.fill(params.intFilesNum)(false.B))) + val outvalids = RegInit(VecInit(Seq.fill(params.intFilesNum)(false.B))) (regmapIOs zip Seq(1, 1 + params.geilen)).zipWithIndex.map { // seq[0]: m interrupt file, seq[1]: s&vs interrupt file - case ((regmapIO: (DecoupledIO[RegMapperInput], DecoupledIO[RegMapperOutput]), intFilesNum: Int), i: Int) => - { - // j: index is 0 for m file for seq[0],index is 0~params.geilen for S intFile for seq[1]: S, G1, G2, ... - val maps = (0 until intFilesNum).map { j => - val flati = i + j // seq[0]:0+0=0;seq[1]:(0~geilen)+1 - val seteipnum = WireInit(0.U.asTypeOf(Valid(UInt(params.imsicIntSrcWidth.W)))); /*for debug*/ - dontTouch(seteipnum) - valids(flati) := seteipnum.valid - seteipnums(flati) := seteipnum.bits - j * pow2(params.intFileMemWidth).toInt -> Seq(RegField( - 32, - 0.U, - RegWriteFn { (valid, data) => - when(valid) { seteipnum.bits := data(params.imsicIntSrcWidth - 1, 0); seteipnum.valid := true.B }; true.B - } - )) - } - regmapIO._2 <> RegMapper(beatBytes, 1, true, regmapIO._1, maps: _*) + case ((regmapIO: (DecoupledIO[RegMapperInput], DecoupledIO[RegMapperOutput]), intFilesNum: Int), i: Int) => { + // j: index is 0 for m file for seq[0],index is 0~params.geilen for S intFile for seq[1]: S, G1, G2, ... + val maps = (0 until intFilesNum).map { j => + val flati = i + j // seq[0]:0+0=0;seq[1]:(0~geilen)+1 + val seteipnum = WireInit(0.U.asTypeOf(Valid(UInt(params.imsicIntSrcWidth.W)))); + /*for debug*/ + dontTouch(seteipnum) + valids(flati) := seteipnum.valid + seteipnums(flati) := seteipnum.bits + j * pow2(params.intFileMemWidth).toInt -> Seq(RegField( + 32, + 0.U, + RegWriteFn { (valid, data) => + when(valid) { + seteipnum.bits := data(params.imsicIntSrcWidth - 1, 0); seteipnum.valid := true.B + }; true.B + } + )) } + regmapIO._2 <> RegMapper(beatBytes, 1, true, regmapIO._1, maps: _*) + } for (i <- 0 until params.intFilesNum) { when(valids(i)) { outseteipnum := Cat(i.U, seteipnums(i)) } } - outvalids := valids + outvalids := valids io.seteipnum := outseteipnum - io.valid := outvalids.reduce(_ | _) + io.valid := outvalids.reduce(_ | _) } } diff --git a/src/main/scala/common.scala b/src/main/scala/common.scala index b45f414..e0303bd 100644 --- a/src/main/scala/common.scala +++ b/src/main/scala/common.scala @@ -97,15 +97,15 @@ class AXI4ToLite()(implicit p: Parameters) extends LazyModule { // val isAccessingValidRegisterAR = (addrAR(11, 2) === 0.U) // Example valid register check for AR val isWAligErr = !((aw_l.size === 2.U) & (w_l.strb === 15.U) & isValidAlignmentAW) // alignment with 4B. - val isWCacheErr = (aw_l.cache(3,1)).orR //non device + val isWCacheErr = false.B//(aw_l.cache(3,1)).orR //non device val isWLockErr = aw_l.lock // AMO access - val isWburstErr = aw_l.burst(1) //0'b10 or 0'b11 : wrap or reserved + val isWburstErr = false.B //aw_l.burst(1) //0'b10 or 0'b11 : wrap or reserved val isWCErr = isWAligErr | isWCacheErr | isWburstErr val isRAligErr = !((ar_l.size === 2.U) & isValidAlignmentAR) - val isRCacheErr = (ar_l.cache(3,1)).orR //non device + val isRCacheErr = false.B//(ar_l.cache(3,1)).orR //non device val isRLockErr = ar_l.lock // AMO access - val isRburstErr = ar_l.burst(1) //0'b10 or 0'b11 : wrap or reserved + val isRburstErr = false.B//ar_l.burst(1) //0'b10 or 0'b11 : wrap or reserved val isRCErr = isRAligErr | isRCacheErr | isRburstErr // val isReservedAreaAccessAW = !(isAccessingValidRegisterAW) // Reserved area for AW // val isReservedAreaAccessAR = !(isAccessingValidRegisterAR) // Reserved area for AR