xref: /XiangShan/src/main/scala/xiangshan/frontend/Composer.scala (revision bb2f3f51dd67f6e16e0cc1ffe43368c9fc7e4aef)
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 xiangshan.frontend
18
19import org.chipsalliance.cde.config.Parameters
20import chisel3._
21import chisel3.util._
22import xiangshan._
23import utils._
24import utility._
25
26class Composer(implicit p: Parameters) extends BasePredictor with HasBPUConst with HasPerfEvents {
27  val (components, resp) = getBPDComponents(io.in.bits.resp_in(0), p)
28  io.out := resp
29  // shorter path for s1 pred
30  val all_fast_pred = components.filter(_.is_fast_pred)
31  require(all_fast_pred.length <= 1)
32  if (all_fast_pred.length == 1) {
33    val fast_pred = all_fast_pred(0)
34    println("[composer] bypassing output of fast pred: " + fast_pred.name)
35    io.out.s1 := fast_pred.io.out.s1
36  }
37
38  var metas = 0.U(1.W)
39  var meta_sz = 0
40  for (c <- components) {
41    c.io.reset_vector        := io.reset_vector
42    c.io.in.valid            := io.in.valid
43    c.io.in.bits.s0_pc       := io.in.bits.s0_pc
44    c.io.in.bits.folded_hist := io.in.bits.folded_hist
45    c.io.in.bits.s1_folded_hist := io.in.bits.s1_folded_hist
46    c.io.in.bits.ghist       := io.in.bits.ghist
47
48    c.io.s0_fire := io.s0_fire
49    c.io.s1_fire := io.s1_fire
50    c.io.s2_fire := io.s2_fire
51    c.io.s3_fire := io.s3_fire
52
53    c.io.s2_redirect := io.s2_redirect
54    c.io.s3_redirect := io.s3_redirect
55
56    c.io.redirect := io.redirect
57    c.io.ctrl := DelayN(io.ctrl, 1)
58    c.io.redirectFromIFU := io.redirectFromIFU
59
60    if (c.meta_size > 0) {
61      metas = (metas << c.meta_size) | c.io.out.last_stage_meta(c.meta_size-1,0)
62    }
63    meta_sz = meta_sz + c.meta_size
64  }
65  println(s"total meta size: $meta_sz\n\n")
66
67
68  io.in.ready := components.map(_.io.s1_ready).reduce(_ && _)
69
70  io.s1_ready := components.map(_.io.s1_ready).reduce(_ && _)
71  io.s2_ready := components.map(_.io.s2_ready).reduce(_ && _)
72
73  require(meta_sz <= MaxMetaLength)
74  io.out.last_stage_meta := metas
75
76  var update_meta = io.update.bits.meta
77  for (c <- components.reverse) {
78    c.io.update := io.update
79    c.io.update.bits.meta := update_meta
80    update_meta = update_meta >> c.meta_size
81  }
82
83  def extractMeta(meta: UInt, idx: Int): UInt = {
84    var update_meta = meta
85    var metas: Seq[UInt] = Nil
86    for (c <- components.reverse) {
87      metas = metas :+ update_meta
88      update_meta = update_meta >> c.meta_size
89    }
90    metas(idx)
91  }
92
93  override def getFoldedHistoryInfo = Some(components.map(_.getFoldedHistoryInfo.getOrElse(Set())).reduce(_++_))
94
95  override val perfEvents = components.map(_.getPerfEvents).reduce(_++_)
96  generatePerfEvent()
97}
98