1package xiangshan.frontend 2 3import chisel3._ 4import chisel3.util._ 5import chisel3.core.{withReset} 6import device.RAMHelper 7import xiangshan._ 8 9trait HasIFUConst { this: XSModule => 10 val resetVector = 0x80000000L//TODO: set reset vec 11 12 val groupAlign = log2Up(FetchWidth * 4) 13 def groupPC(pc: UInt): UInt = Cat(pc(VAddrBits-1, groupAlign), 0.U(groupAlign.W)) 14 15} 16 17sealed abstract IFUBundle extends XSBundle with HasIFUConst 18sealed abstract IFUModule extends XSModule with HasIFUConst with NeedImpl 19 20 21 22class IFUIO extends IFUBundle 23{ 24 val fetchPacket = DecoupledIO(new FetchPacket) 25 val redirect = Flipped(ValidIO(new Redirect)) 26 val icacheReq = DecoupledIO(UInt(VAddrBits.W) 27 val icacheResp = Flipped(DecoupledIO(new FakeIcacheResp)) 28} 29 30 31 32class IFU(implicit val p: XSConfig) extends IFUModule 33{ 34 val io = IO(new IFUIO) 35 val bpu = Module(new BPU) 36 37 //------------------------- 38 // IF1 PC update 39 //------------------------- 40 //local 41 val if1_npc = WireInit(0.U(VAddrBits.W)) 42 val if1_valid = WireInit(false.B) 43 val if1_pc = RegInit(resetVector.U(VAddrBits.W)) 44 //next 45 val if2_ready = WireInit(false.B) 46 val if1_ready = bpu.io.in.ready && if2_ready 47 48 //pipe fire 49 val if1_fire = if1_valid && if1_ready 50 val if1_pcUpdate = io.redirect.valid || if1_fire 51 52 when(RegNext(reset.asBool) && !reset.asBool) 53 { 54 if1_npc := resetVector 55 if1_valid := true.B 56 } 57 58 when(if1_pcUpdate) 59 { 60 if1_pc := if1_npc 61 } 62 63 bpu.io.in.valid := if1_valid 64 bpu.io.in.pc := if1_npc 65 66 //------------------------- 67 // IF2 btb resonse 68 // icache visit 69 //------------------------- 70 //local 71 val if2_flush = WireInit(false.B) 72 val if2_update = if1_fire && !if2_flush 73 val if2_valid = RegNext(if2_update) 74 val if2_pc = if1_pc 75 val if2_btb_taken = bpu.io.btbOut.valid 76 val if2_btb_insMask = bpu.io.btbOut.bits.instrValid 77 val if2_btb_target = bpu.io.btbOut.bits.target 78 val if2_snpc = Cat(if2_pc(VAddrBits-1, groupAlign) + 1.U, 0.U(groupAlign.W)) 79 val if2_flush = WireInit(false.B) 80 81 //next 82 val if3_ready = WireInit(false.B) 83 84 //pipe fire 85 val if2_fire = if2_valid && if3_ready 86 val if2_ready = (if2_fire && io.icacheReq.fire()) || !if2_valid 87 88 io.icacheReq.valid := if2_fire 89 io.icacheReq.bits := groupPC(if2_pc) 90 91 when(if2_valid && if2_btb_taken) 92 { 93 if1_npc := if2_btb_target 94 } .otherwise 95 { 96 if1_npc := if2_snpc 97 } 98 99 //------------------------- 100 // IF3 icache hit check 101 //------------------------- 102 //local 103 val if3_flush = WireInit(false.B) 104 val if3_update = if2_fire && !if3_flush 105 val if3_valid = RegNext(if3_update) 106 val if3_pc = RegEnable(if2_pc,if3_update) 107 val if3_btb_target = RegEnable(if2_btb_target,if3_update) 108 val if3_btb_taken = RegEnable(if2_btb_taken,if3_update) 109 110 //next 111 val if4_ready = WireInit(false.B) 112 113 //pipe fire 114 val if3_fire = if3_valid && if4_ready 115 val if3_ready = if3_fire || !if3_valid 116 117 //------------------------- 118 // IF4 icache resonse 119 // RAS result 120 // taget generate 121 //------------------------- 122 val if4_flush = WireInit(false.B) 123 val if4_update = if3_fire && !if4_flush 124 val if4_valid = RegNext(if4_update) 125 val if4_pc = RegEnable(if3_pc,if4_update) 126 val if4_btb_target = RegEnable(if3_btb_target,if4_update) 127 val if4_btb_taken = RegEnable(if3_btb_taken,if4_update) 128 129 130 131 when(if4_valid && io.icacheResp.fire()) 132 { 133 if1_npc := if4_btb_target 134 } 135 136 137 //redirect 138 when(io.redirect.valid){ 139 if1_npc := io.redirect.bits.target 140 if2_flush := true.B 141 if3_flush := true.B 142 if4_flush := true.B 143 } 144 145 146 //Output -> iBuffer 147 if4_ready := io.fetchPacket.ready 148 io.fetchPacket.valid := if4_valid && !if4_flush 149 io.fetchPacket.instrs := io.icacheResp.bits.icacheOut 150 io.fetchPacket.mask := Fill(FetchWidth*2, 1.U(1.W)) << if4_pc(2+log2Up(FetchWidth)-1, 1) 151 io.fetchPacket.pc := if4_pc 152 153 //to BPU 154 bpu.io.predecode.valid := if4_valid 155 bpu.io.predecode.bits <> io.icacheResp.bits.predecode 156 bpu.io.predecode.bits.mask := ? 157 158 159 160} 161 162