1package xiangshan.backend.fu 2 3import chisel3._ 4import chisel3.util._ 5import xiangshan._ 6import utils._ 7import xiangshan.backend._ 8import xiangshan.backend.fu.FunctionUnit._ 9 10class MulDivCtrl extends Bundle{ 11 val sign = Bool() 12 val isW = Bool() 13 val isHi = Bool() // return hi bits of result ? 14} 15 16class MulDivOutput extends XSBundle { 17 val data = UInt(XLEN.W) 18 val uop = new MicroOp 19} 20 21class MulDivIO(val len: Int) extends XSBundle { 22 val in = Flipped(DecoupledIO(new Bundle() { 23 val src1, src2 = UInt(len.W) 24 val ctrl = new MulDivCtrl 25 })) 26 val out = DecoupledIO(new MulDivOutput) 27 val redirect = Flipped(ValidIO(new Redirect)) 28} 29 30abstract class Multiplier 31( 32 val len: Int, 33 latency: Int = 3 34) extends FunctionUnit(cfg = mulCfg, extIn = new MulDivCtrl, latency = latency) 35 with HasPipelineReg[MulDivCtrl, Null] 36{ 37 38 val (src1, src2) = (io.in.bits.src(0), io.in.bits.src(1)) 39 40} 41 42//trait HasPipelineReg { this: ArrayMultiplier => 43// 44// val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B)) 45// val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready 46// val ctrlVec = io.in.bits.ctrl +: Array.fill(latency)(Reg(new MulDivCtrl)) 47// val flushVec = ctrlVec.zip(validVec).map(x => x._2 && x._1.uop.needFlush(io.redirect)) 48// 49// for(i <- 0 until latency){ 50// rdyVec(i) := !validVec(i+1) || rdyVec(i+1) 51// } 52// 53// for(i <- 1 to latency){ 54// when(flushVec(i-1) || rdyVec(i) && !validVec(i-1)){ 55// validVec(i) := false.B 56// }.elsewhen(rdyVec(i-1) && validVec(i-1) && !flushVec(i-1)){ 57// validVec(i) := validVec(i-1) 58// ctrlVec(i) := ctrlVec(i-1) 59// } 60// } 61// 62// io.in.ready := rdyVec(0) 63// io.out.valid := validVec.last && !flushVec.last 64// io.out.bits.uop := ctrlVec.last.uop 65// 66// def PipelineReg[T<:Data](i: Int)(next: T) = RegEnable( 67// next, 68// enable = validVec(i-1) && rdyVec(i-1) && !flushVec(i-1) 69// ) 70// 71// def S1Reg[T<:Data](next: T):T = PipelineReg[T](1)(next) 72// def S2Reg[T<:Data](next: T):T = PipelineReg[T](2)(next) 73// def S3Reg[T<:Data](next: T):T = PipelineReg[T](3)(next) 74// def S4Reg[T<:Data](next: T):T = PipelineReg[T](4)(next) 75// def S5Reg[T<:Data](next: T):T = PipelineReg[T](5)(next) 76//} 77 78class ArrayMultiplier 79( 80 len: Int, 81 latency: Int = 3, 82 realArray: Boolean = false 83) extends Multiplier(len, latency) { 84 85 val mulRes = src1.asSInt() * src2.asSInt() 86 87 var dataVec = Seq(mulRes.asUInt()) 88 var ctrlVec = Seq(io.in.bits.ext.get) 89 90 for(i <- 1 to latency){ 91 dataVec = dataVec :+ PipelineReg(i)(dataVec(i-1)) 92 ctrlVec = ctrlVec :+ PipelineReg(i)(ctrlVec(i-1)) 93 } 94 95 val xlen = io.out.bits.data.getWidth 96 val res = Mux(ctrlVec.last.isHi, dataVec.last(2*xlen-1, xlen), dataVec.last(xlen-1,0)) 97 io.out.bits.data := Mux(ctrlVec.last.isW, SignExt(res(31,0),xlen), res) 98 99 XSDebug(p"validVec:${Binary(Cat(validVec))} flushVec:${Binary(Cat(flushVec))}\n")(this.name) 100 101 // printf(p"t=${GTimer()} in: v${io.in.valid} r:${io.in.ready}\n") 102 // printf(p"t=${GTimer()} out: v:${io.out.valid} r:${io.out.ready} vec:${Binary(Cat(validVec))}\n") 103}