1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 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 device 18 19import chisel3._ 20import chisel3.util._ 21import org.chipsalliance.cde.config.Parameters 22import freechips.rocketchip.diplomacy.AddressSet 23import utils._ 24import utility._ 25 26// we support 256 interrupt bits by default 27class IntrGenIO extends Bundle { 28 val intrVec = Output(UInt(64.W)) 29} 30 31class AXI4IntrGenerator 32( 33 address: Seq[AddressSet] 34)(implicit p: Parameters) 35 extends AXI4SlaveModule(address, executable = false, _extra = new IntrGenIO) 36{ 37 38 override lazy val module = new AXI4SlaveModuleImp(this){ 39 40 val intrGenRegs = RegInit(VecInit(Seq.fill(8)(0.U(32.W)))) 41 42 // 0x0 - 0x8 43 val intrReg = VecInit(intrGenRegs.take(2)) 44 // 0x8 - 0x10 45 val randEnable = VecInit(intrGenRegs.slice(2, 4)) 46 // 0x10 47 val randMask = intrGenRegs(4) 48 val randCounter = intrGenRegs(5) 49 val randThres = intrGenRegs(6) 50 51 val randomPosition = LFSR64()(5, 0) 52 val randomCondition = randCounter === randThres && randEnable(randomPosition(5))(randomPosition(4, 0)) 53 randCounter := randCounter + 1.U 54 when (randomCondition) { 55 intrGenRegs(randomPosition(5)) := intrReg(randomPosition(5)) | UIntToOH(randomPosition(4, 0)) 56 } 57 58 io.extra.get.intrVec := Cat(intrReg.reverse) 59 60 // Delay the intr gen for 1000 cycles. 61 val delayCycles = 1000 62 var w_fire = in.w.fire && in.w.bits.data =/= 0.U 63 for (i <- 0 until delayCycles) { 64 w_fire = RegNext(w_fire, init=false.B) 65 } 66 val dataWidth = in.w.bits.data.getWidth 67 val w_data = 68 if (dataWidth == 32) 69 in.w.bits.data 70 else { 71 val addrCandidate = waddr(log2Ceil(dataWidth / 8) - 1, 2) 72 Mux1H( 73 Seq.tabulate(dataWidth / 32)( 74 i => (addrCandidate === i.U, in.w.bits.data(i * 32 + 31, i * 32)) 75 ) 76 ) 77 } 78 val w_data_delayed = DelayN(w_data, delayCycles) 79 when (w_fire) { 80 intrGenRegs(DelayN(waddr(4, 2), delayCycles)) := w_data_delayed 81 } 82 // Clear takes effect immediately 83 when (in.w.fire && in.w.bits.data === 0.U) { 84 intrGenRegs(waddr(4, 2)) := 0.U 85 } 86 // write resets the threshold and counter 87 when (in.w.fire && in.w.bits.data === 0.U || w_fire) { 88 randThres := LFSR64() & randMask 89 randCounter := 0.U 90 } 91 92 in.r.bits.data := intrReg(raddr) 93 } 94} 95