xref: /XiangShan/src/main/scala/xiangshan/mem/vector/VfofBuffer.scala (revision 640977d3c524e813e64d3cb3995dd02b77e00d71)
1df3b4b92SAnzooooo/***************************************************************************************
2df3b4b92SAnzooooo * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3df3b4b92SAnzooooo * Copyright (c) 2020-2021 Peng Cheng Laboratory
4df3b4b92SAnzooooo *
5df3b4b92SAnzooooo * XiangShan is licensed under Mulan PSL v2.
6df3b4b92SAnzooooo * You can use this software according to the terms and conditions of the Mulan PSL v2.
7df3b4b92SAnzooooo * You may obtain a copy of Mulan PSL v2 at:
8df3b4b92SAnzooooo *          http://license.coscl.org.cn/MulanPSL2
9df3b4b92SAnzooooo *
10df3b4b92SAnzooooo * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11df3b4b92SAnzooooo * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12df3b4b92SAnzooooo * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13df3b4b92SAnzooooo *
14df3b4b92SAnzooooo * See the Mulan PSL v2 for more details.
15df3b4b92SAnzooooo ***************************************************************************************/
16df3b4b92SAnzooooo
17df3b4b92SAnzooooopackage xiangshan.mem
18df3b4b92SAnzooooo
19df3b4b92SAnzoooooimport org.chipsalliance.cde.config.Parameters
20df3b4b92SAnzoooooimport chisel3._
21df3b4b92SAnzoooooimport chisel3.util._
22df3b4b92SAnzoooooimport utils._
23df3b4b92SAnzoooooimport utility._
24df3b4b92SAnzoooooimport xiangshan._
25df3b4b92SAnzoooooimport xiangshan.backend.rob.RobPtr
26df3b4b92SAnzoooooimport xiangshan.backend.Bundles._
27df3b4b92SAnzoooooimport xiangshan.mem._
28df3b4b92SAnzoooooimport xiangshan.backend.fu.vector.Bundles._
29df3b4b92SAnzooooo
30df3b4b92SAnzooooo
31df3b4b92SAnzoooooclass VfofDataBundle(implicit p: Parameters) extends VLSUBundle{
32df3b4b92SAnzooooo  val uop              = new DynInst
33df3b4b92SAnzooooo  val vl               = UInt(elemIdxBits.W)
34412b33bfSAnzooooo  val hasException     = Bool()
35df3b4b92SAnzooooo}
36df3b4b92SAnzooooo
37df3b4b92SAnzooooo
38df3b4b92SAnzoooooclass VfofBuffer(implicit p: Parameters) extends VLSUModule{
39df3b4b92SAnzooooo  val io = IO(new VfofDataBuffIO())
40df3b4b92SAnzooooo
41df3b4b92SAnzooooo  val entries = RegInit(0.U.asTypeOf(new VfofDataBundle()))
42df3b4b92SAnzooooo  val valid   = RegInit(false.B)
43df3b4b92SAnzooooo
44df3b4b92SAnzooooo  val entriesIsFixVl = entries.uop.vpu.lastUop && entries.uop.vpu.isVleff
45df3b4b92SAnzooooo
46df3b4b92SAnzooooo  //Enq
47df3b4b92SAnzooooo  io.in.map(_.ready := true.B)
48df3b4b92SAnzooooo  val enqIsfof = io.in.map { x =>
49df3b4b92SAnzooooo    x.valid && x.bits.uop.vpu.isVleff
50df3b4b92SAnzooooo  }
51df3b4b92SAnzooooo
52df3b4b92SAnzooooo  val enqValid = enqIsfof.reduce(_ || _)
53df3b4b92SAnzooooo  val enqBits  = ParallelPriorityMux(enqIsfof, io.in.map(_.bits))
54df3b4b92SAnzooooo  val enqNeedCancel = enqBits.uop.robIdx.needFlush(io.redirect)
55df3b4b92SAnzooooo  val enqIsFixVl = enqBits.uop.vpu.isVleff && enqBits.uop.vpu.lastUop
56df3b4b92SAnzooooo
57412b33bfSAnzooooo  XSError(entries.uop.robIdx.value =/= enqBits.uop.robIdx.value && valid && enqValid, "There should be no new fof instrction coming in!\n")
58412b33bfSAnzooooo  XSError(entriesIsFixVl && valid && enqValid, "There should not new uop enqueue!\n")
59df3b4b92SAnzooooo
60df3b4b92SAnzooooo  when(enqValid && !enqNeedCancel) {
61df3b4b92SAnzooooo    when(!valid){
62df3b4b92SAnzooooo      entries.uop           := enqBits.uop
63412b33bfSAnzooooo      entries.vl            := enqBits.src_vl.asTypeOf(VConfig()).vl
64412b33bfSAnzooooo      entries.hasException  := false.B
65df3b4b92SAnzooooo    }.elsewhen(valid && enqIsFixVl){
66df3b4b92SAnzooooo      entries.uop     := enqBits.uop
67df3b4b92SAnzooooo    }
68df3b4b92SAnzooooo  }
69df3b4b92SAnzooooo
70df3b4b92SAnzooooo  //Control Signal
71df3b4b92SAnzooooo  val needRedirect = entries.uop.robIdx.needFlush(io.redirect)
72df3b4b92SAnzooooo
73*640977d3SAnzooooo
74*640977d3SAnzooooo  when(io.uopWriteback.fire) {
75*640977d3SAnzooooo    valid := false.B  //Deq
76df3b4b92SAnzooooo  }.elsewhen(needRedirect) {
77df3b4b92SAnzooooo    valid := false.B //Redirect
78*640977d3SAnzooooo  }.elsewhen(enqValid && !enqNeedCancel) {
79*640977d3SAnzooooo    valid := true.B //Enq
80df3b4b92SAnzooooo  }
81df3b4b92SAnzooooo
82*640977d3SAnzooooo
83df3b4b92SAnzooooo  //Gather writeback information
84412b33bfSAnzooooo  val wbIsfof = io.mergeUopWriteback.map{ x => x.valid && x.bits.uop.robIdx === entries.uop.robIdx }
85df3b4b92SAnzooooo
86df3b4b92SAnzooooo  def getOldest(valid: Seq[Bool], bits: Seq[DynInst]): DynInst = {
87df3b4b92SAnzooooo    def getOldest_recursion[T <: Data](valid: Seq[Bool], bits: Seq[DynInst]): (Seq[Bool], Seq[DynInst]) = {
88df3b4b92SAnzooooo      assert(valid.length == bits.length)
89df3b4b92SAnzooooo      if (valid.length == 1) {
90df3b4b92SAnzooooo        (valid, bits)
91df3b4b92SAnzooooo      } else if (valid.length == 2) {
92df3b4b92SAnzooooo        val res = Seq.fill(2)(Wire(ValidIO(chiselTypeOf(bits(0)))))
93df3b4b92SAnzooooo        for (i <- res.indices) {
94df3b4b92SAnzooooo          res(i).valid := valid(i)
95df3b4b92SAnzooooo          res(i).bits := bits(i)
96df3b4b92SAnzooooo        }
97412b33bfSAnzooooo        val withExcep0 = bits(0).exceptionVec.asUInt.orR
98412b33bfSAnzooooo        val withExcep1 = bits(1).exceptionVec.asUInt.orR
992d1596c2SAnzooooo        XSError(this.valid && withExcep0 && withExcep1 && valid(0) && valid(1), "Writeback to multiple Uop with exceptions at the same time!\n")
100df3b4b92SAnzooooo        val oldest = Mux(
101412b33bfSAnzooooo          valid(0) && valid(1),
102412b33bfSAnzooooo          Mux((bits(1).vpu.vl > bits(0).vpu.vl || withExcep0) && !withExcep1, res(0), res(1)),
103412b33bfSAnzooooo          Mux(valid(0) && !valid(1), res(0), res(1))
104df3b4b92SAnzooooo        )
105df3b4b92SAnzooooo        (Seq(oldest.valid), Seq(oldest.bits))
106df3b4b92SAnzooooo      } else {
107df3b4b92SAnzooooo        val left = getOldest_recursion(valid.take(valid.length / 2), bits.take(valid.length / 2))
108df3b4b92SAnzooooo        val right = getOldest_recursion(valid.drop(valid.length / 2), bits.drop(valid.length / 2))
109df3b4b92SAnzooooo        getOldest_recursion(left._1 ++ right._1, left._2 ++ right._2)
110df3b4b92SAnzooooo      }
111df3b4b92SAnzooooo    }
112df3b4b92SAnzooooo    getOldest_recursion(valid, bits)._2.head
113df3b4b92SAnzooooo  }
114df3b4b92SAnzooooo
115df3b4b92SAnzooooo  //Update uop vl
116df3b4b92SAnzooooo  io.mergeUopWriteback.map{_.ready := true.B}
117412b33bfSAnzooooo  val wbBits          = getOldest(wbIsfof, io.mergeUopWriteback.map(_.bits.uop))
118412b33bfSAnzooooo  val wbValid         = wbIsfof.reduce(_ || _)
119412b33bfSAnzooooo  val wbHasException  = wbBits.exceptionVec.asUInt.orR
120412b33bfSAnzooooo  val wbUpdateValid = wbValid && (wbBits.vpu.vl < entries.vl || wbHasException) && valid && !needRedirect && !entries.hasException
121412b33bfSAnzooooo
122412b33bfSAnzooooo  XSError(wbValid && wbHasException && valid && entries.hasException, "The same instruction triggers an exception multiple times!\n")
123df3b4b92SAnzooooo
12441c5202dSAnzooooo  when(wbUpdateValid) {
125412b33bfSAnzooooo    entries.vl                    := wbBits.vpu.vl
126412b33bfSAnzooooo    entries.hasException          := wbHasException
12741c5202dSAnzooooo  }
128df3b4b92SAnzooooo
129df3b4b92SAnzooooo  //Deq
130df3b4b92SAnzooooo  io.uopWriteback.bits                  := 0.U.asTypeOf(new MemExuOutput(isVector = true))
131df3b4b92SAnzooooo  io.uopWriteback.bits.uop              := entries.uop
132412b33bfSAnzooooo  io.uopWriteback.bits.uop.exceptionVec := 0.U.asTypeOf(ExceptionVec())
133df3b4b92SAnzooooo  io.uopWriteback.bits.data             := entries.vl
134df3b4b92SAnzooooo  io.uopWriteback.bits.uop.vpu.vl       := entries.vl
135df3b4b92SAnzooooo  io.uopWriteback.bits.mask.get         := Fill(VLEN, 1.U)
136df3b4b92SAnzooooo  io.uopWriteback.bits.uop.vpu.vmask    := Fill(VLEN, 1.U)
137df3b4b92SAnzooooo  io.uopWriteback.valid                 := valid && entries.uop.vpu.lastUop && entries.uop.vpu.isVleff && !needRedirect
138df3b4b92SAnzooooo
139df3b4b92SAnzooooo
140df3b4b92SAnzooooo}
141