xref: /XiangShan/src/main/scala/xiangshan/backend/datapath/NewPipelineConnect.scala (revision 7f8233d5a8887332319d249b84f17f57e5c5dd26)
1bd6e2c2eSfdy/***************************************************************************************
2bd6e2c2eSfdy * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3bd6e2c2eSfdy * Copyright (c) 2020-2021 Peng Cheng Laboratory
4bd6e2c2eSfdy *
5bd6e2c2eSfdy * XiangShan is licensed under Mulan PSL v2.
6bd6e2c2eSfdy * You can use this software according to the terms and conditions of the Mulan PSL v2.
7bd6e2c2eSfdy * You may obtain a copy of Mulan PSL v2 at:
8bd6e2c2eSfdy *          http://license.coscl.org.cn/MulanPSL2
9bd6e2c2eSfdy *
10bd6e2c2eSfdy * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11bd6e2c2eSfdy * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12bd6e2c2eSfdy * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13bd6e2c2eSfdy *
14bd6e2c2eSfdy * See the Mulan PSL v2 for more details.
15bd6e2c2eSfdy ***************************************************************************************/
16bd6e2c2eSfdy
17bd6e2c2eSfdypackage xiangshan.backend.datapath
18bd6e2c2eSfdy
19bd6e2c2eSfdyimport chisel3._
20bd6e2c2eSfdyimport chisel3.util._
21bd6e2c2eSfdy
22bd6e2c2eSfdyclass NewPipelineConnectPipe[T <: Data](gen: T) extends Module {
23bd6e2c2eSfdy  val io = IO(new Bundle() {
24bd6e2c2eSfdy    val in = Flipped(DecoupledIO(gen.cloneType))
25bd6e2c2eSfdy    val out = DecoupledIO(gen.cloneType)
26bd6e2c2eSfdy    val rightOutFire = Input(Bool())
27bd6e2c2eSfdy    val isFlush = Input(Bool())
28bd6e2c2eSfdy  })
29bd6e2c2eSfdy
30bd6e2c2eSfdy  NewPipelineConnect.connect(io.in, io.out, io.rightOutFire, io.isFlush)
31bd6e2c2eSfdy}
32bd6e2c2eSfdy
33bd6e2c2eSfdyobject NewPipelineConnect {
34bd6e2c2eSfdy  def connect[T <: Data](
35bd6e2c2eSfdy                          left: DecoupledIO[T],
36bd6e2c2eSfdy                          right: DecoupledIO[T],
37bd6e2c2eSfdy                          rightOutFire: Bool,
38bd6e2c2eSfdy                          isFlush: Bool
39bd6e2c2eSfdy                        ): T = {
40bd6e2c2eSfdy    val valid = RegInit(false.B)
41bd6e2c2eSfdy
42bd6e2c2eSfdy    left.ready := right.ready || !valid
43*7f8233d5SHaojin Tang    val data = RegEnable(left.bits, left.fire)
44bd6e2c2eSfdy
45bd6e2c2eSfdy    when (rightOutFire) { valid := false.B }
46*7f8233d5SHaojin Tang    when (left.fire) { valid := true.B }
47bd6e2c2eSfdy    when (isFlush) { valid := false.B }
48bd6e2c2eSfdy
49bd6e2c2eSfdy    right.bits := data
50bd6e2c2eSfdy    right.valid := valid
51bd6e2c2eSfdy
52bd6e2c2eSfdy    data
53bd6e2c2eSfdy  }
54bd6e2c2eSfdy
55bd6e2c2eSfdy  def apply[T <: Data](
56bd6e2c2eSfdy                        left: DecoupledIO[T],
57bd6e2c2eSfdy                        right: DecoupledIO[T],
58bd6e2c2eSfdy                        rightOutFire: Bool,
59bd6e2c2eSfdy                        isFlush: Bool,
60bd6e2c2eSfdy                        moduleName: Option[String] = None
61bd6e2c2eSfdy                      ): Option[T] = {
62bd6e2c2eSfdy    if (moduleName.isDefined) {
63bd6e2c2eSfdy      val pipeline = Module(new NewPipelineConnectPipe(left.bits))
64bd6e2c2eSfdy      pipeline.suggestName(moduleName.get)
65bd6e2c2eSfdy      pipeline.io.in <> left
66bd6e2c2eSfdy      pipeline.io.rightOutFire := rightOutFire
67bd6e2c2eSfdy      pipeline.io.isFlush := isFlush
68bd6e2c2eSfdy      pipeline.io.out <> right
69bd6e2c2eSfdy      pipeline.io.out.ready := right.ready
70bd6e2c2eSfdy      None
71bd6e2c2eSfdy    }
72bd6e2c2eSfdy    else {
73bd6e2c2eSfdy      // do not use module here to please DCE
74bd6e2c2eSfdy      Some(connect(left, right, rightOutFire, isFlush))
75bd6e2c2eSfdy    }
76bd6e2c2eSfdy  }
77bd6e2c2eSfdy}