xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/NewPipelineConnect.scala (revision bd6e2c2e9942ad83d84c8210707b1a7431a41717)
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.backend.datapath
18
19import chisel3._
20import chisel3.util._
21
22class NewPipelineConnectPipe[T <: Data](gen: T) extends Module {
23  val io = IO(new Bundle() {
24    val in = Flipped(DecoupledIO(gen.cloneType))
25    val out = DecoupledIO(gen.cloneType)
26    val rightOutFire = Input(Bool())
27    val isFlush = Input(Bool())
28  })
29
30  NewPipelineConnect.connect(io.in, io.out, io.rightOutFire, io.isFlush)
31}
32
33object NewPipelineConnect {
34  def connect[T <: Data](
35                          left: DecoupledIO[T],
36                          right: DecoupledIO[T],
37                          rightOutFire: Bool,
38                          isFlush: Bool
39                        ): T = {
40    val valid = RegInit(false.B)
41
42    left.ready := right.ready || !valid
43    val leftFire = left.valid && left.ready
44    val data = RegEnable(left.bits, leftFire)
45
46    when (rightOutFire) { valid := false.B }
47    when (leftFire) { valid := true.B }
48    when (isFlush) { valid := false.B }
49
50    right.bits := data
51    right.valid := valid
52
53    data
54  }
55
56  def apply[T <: Data](
57                        left: DecoupledIO[T],
58                        right: DecoupledIO[T],
59                        rightOutFire: Bool,
60                        isFlush: Bool,
61                        moduleName: Option[String] = None
62                      ): Option[T] = {
63    if (moduleName.isDefined) {
64      val pipeline = Module(new NewPipelineConnectPipe(left.bits))
65      pipeline.suggestName(moduleName.get)
66      pipeline.io.in <> left
67      pipeline.io.rightOutFire := rightOutFire
68      pipeline.io.isFlush := isFlush
69      pipeline.io.out <> right
70      pipeline.io.out.ready := right.ready
71      None
72    }
73    else {
74      // do not use module here to please DCE
75      Some(connect(left, right, rightOutFire, isFlush))
76    }
77  }
78}