xref: /XiangShan/src/main/scala/utils/Trigger.scala (revision 8241cb85f7d34397435cf2810442754e2a0f477d)
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 Mu lan 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 utils
18
19import chisel3._
20import chisel3.util._
21import xiangshan.MatchTriggerIO
22import org.chipsalliance.cde.config.Parameters
23
24
25object TriggerCmpConsecutive {
26  def apply(actual: Vec[UInt], tdata: UInt, matchType: UInt, enable: Bool, VAddrBits: Int) : Vec[Bool] = {
27    // opt: only compare two possible high bits: orig and orig+1
28    val len1 = actual.length
29    val highPos = log2Up(len1)
30    val lowPC = Wire(Vec(len1, UInt(highPos.W)))
31    lowPC.zipWithIndex.map{case (h, i) => h := actual(i)(highPos - 1, 0)}
32    val highPC = actual(0)(VAddrBits - 1, highPos)
33    val highPC1 = actual(0)(VAddrBits - 1, highPos) + 1.U
34    val highTdata = tdata(VAddrBits - 1, highPos)
35
36    val highPCEqual = highPC === highTdata
37    val highPC1Equal = highPC1 === highTdata
38    val highPCGreater = highPC >= highTdata
39    val highPC1Greater = highPC1 >= highTdata
40    val highPCLess = highPC <= highTdata
41    val highPC1Less = highPC1 <= highTdata
42
43    val carry = Wire(Vec(len1, Bool()))
44    carry.zipWithIndex.map{case (c, i) => c := actual(i)(highPos) =/= actual(0)(highPos)}
45
46    val lowPCEqual = Wire(Vec(len1, Bool()))
47    val lowPCGreater = Wire(Vec(len1, Bool()))
48    val lowPCLess = Wire(Vec(len1, Bool()))
49
50    lowPCEqual.zipWithIndex.map{case (l, i) => l := actual(i)(highPos - 1, 0) === tdata(highPos - 1, 0)}
51    lowPCGreater.zipWithIndex.map{case (l, i) => l := actual(i)(highPos - 1, 0) >= tdata(highPos - 1, 0)}
52    lowPCLess.zipWithIndex.map{case (l, i) => l := actual(i)(highPos - 1, 0) <= tdata(highPos - 1, 0)}
53
54    val overallEqual = Wire(Vec(len1, Bool()))
55    val overallGreater = Wire(Vec(len1, Bool()))
56    val overallLess = Wire(Vec(len1, Bool()))
57
58    overallEqual.zipWithIndex.map{case (o, i) => o := lowPCEqual(i) && highPCEqual}
59
60    // greater: 1. highPC > highTdata; 2. highPC == highTdata && lowPC >= lowTdata
61    overallGreater.zipWithIndex.map{case (o, i) => o := highPCGreater || ((!carry(i) || lowPCGreater(i)) && highPCEqual)}
62
63    // less: 1. highPC < highTdata; 2. highPC == highTdata && lowPC <= lowTdata
64    overallLess.zipWithIndex.map{case (o, i) => o := highPCLess || ((!carry(i) && lowPCLess(i)) && highPCEqual)}
65
66    val ret = Wire(Vec(len1, Bool()))
67
68    ret.zipWithIndex.map{case (r, i) => r := MuxLookup(matchType, false.B,
69      Array(0.U -> overallEqual(i),
70        2.U -> overallGreater(i),
71        3.U -> overallLess(i))) && enable}
72    ret
73  }
74}
75
76object ChainCheck {
77  def TimingCheck(prevTiming: Bool, thisTiming: Bool, chain: Bool) = !((prevTiming ^ thisTiming) && chain)
78  def HitCheck(prevHit: Bool, chain: Bool) = prevHit || !chain
79}
80
81object PrintTriggerInfo {
82  def apply(enable: Bool, trigger: MatchTriggerIO)(implicit p: Parameters) = {
83    XSDebug(enable, p"Debug Mode: Match Type is ${trigger.matchType}; select is ${trigger.select};" +
84      p"timing is ${trigger.timing}; action is ${trigger.action}; chain is ${trigger.chain};" +
85      p"tdata2 is ${Hexadecimal(trigger.tdata2)}")
86  }
87}