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}