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 utils 18 19import chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import freechips.rocketchip.tilelink.TLMessages._ 23import freechips.rocketchip.tilelink.TLPermissions._ 24import freechips.rocketchip.tilelink.{TLBundle, TLBundleA, TLBundleB, TLBundleC, TLBundleD, TLBundleE, TLChannel} 25 26trait HasTLDump { 27 28 implicit val p: Parameters 29 30 implicit class TLDump(channel: TLChannel) { 31 def dump = channel match { 32 case a: TLBundleA => 33 printChannelA(a) 34 case b: TLBundleB => 35 printChannelB(b) 36 case c: TLBundleC => 37 printChannelC(c) 38 case d: TLBundleD => 39 printChannelD(d) 40 case e: TLBundleE => 41 printChannelE(e) 42 } 43 } 44 45 def printChannelA(a: TLBundleA): Unit = { 46 switch(a.opcode) { 47 is(PutFullData) { 48 XSDebug(false, true.B, 49 a.channelName + " PutFullData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 50 a.param, a.size, a.source, a.address, a.mask, a.data, a.corrupt 51 ) 52 } 53 54 is(PutPartialData) { 55 XSDebug(false, true.B, 56 a.channelName + " PutPartialData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 57 a.param, a.size, a.source, a.address, a.mask, a.data, a.corrupt 58 ) 59 } 60 61 is(ArithmeticData) { 62 XSDebug(false, true.B, 63 a.channelName + " ArithmeticData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 64 a.param, a.size, a.source, a.address, a.mask, a.data, a.corrupt 65 ) 66 } 67 68 is(LogicalData) { 69 XSDebug(false, true.B, 70 a.channelName + " LogicalData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 71 a.param, a.size, a.source, a.address, a.mask, a.data, a.corrupt 72 ) 73 } 74 75 is(Get) { 76 XSDebug(false, true.B, 77 a.channelName + " Get param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 78 a.param, a.size, a.source, a.address, a.mask, a.data, a.corrupt 79 ) 80 } 81 82 is(Hint) { 83 XSDebug(false, true.B, 84 a.channelName + " Intent param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 85 a.param, a.size, a.source, a.address, a.mask, a.data, a.corrupt 86 ) 87 } 88 89 is(AcquireBlock) { 90 switch(a.param) { 91 is(NtoB) { 92 XSDebug(false, true.B, 93 a.channelName + " AcquireBlock NtoB size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 94 a.size, a.source, a.address, a.mask, a.data, a.corrupt 95 ) 96 } 97 is(NtoT) { 98 XSDebug(false, true.B, 99 a.channelName + " AcquireBlock NtoT size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 100 a.size, a.source, a.address, a.mask, a.data, a.corrupt 101 ) 102 } 103 is(BtoT) { 104 XSDebug(false, true.B, 105 a.channelName + " AcquireBlock BtoT size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 106 a.size, a.source, a.address, a.mask, a.data, a.corrupt 107 ) 108 } 109 } 110 } 111 112 is(AcquirePerm) { 113 switch(a.param) { 114 is(NtoB) { 115 XSDebug(false, true.B, 116 a.channelName + " AcquirePerm NtoB size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 117 a.size, a.source, a.address, a.mask, a.data, a.corrupt 118 ) 119 } 120 is(NtoT) { 121 XSDebug(false, true.B, 122 a.channelName + " AcquirePerm NtoT size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 123 a.size, a.source, a.address, a.mask, a.data, a.corrupt 124 ) 125 } 126 is(BtoT) { 127 XSDebug(false, true.B, 128 a.channelName + " AcquirePerm BtoT size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 129 a.size, a.source, a.address, a.mask, a.data, a.corrupt 130 ) 131 } 132 } 133 } 134 135 } 136 } 137 138 def printChannelB(b: TLBundleB): Unit = { 139 switch(b.opcode) { 140 is(PutFullData) { 141 XSDebug(false, true.B, 142 b.channelName + " PutFullData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 143 b.param, b.size, b.source, b.address, b.mask, b.data, b.corrupt 144 ) 145 } 146 147 is(PutPartialData) { 148 XSDebug(false, true.B, 149 b.channelName + " PutPartialData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 150 b.param, b.size, b.source, b.address, b.mask, b.data, b.corrupt 151 ) 152 } 153 154 is(ArithmeticData) { 155 XSDebug(false, true.B, 156 b.channelName + " ArithmeticData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 157 b.param, b.size, b.source, b.address, b.mask, b.data, b.corrupt 158 ) 159 } 160 161 is(LogicalData) { 162 XSDebug(false, true.B, 163 b.channelName + " LogicalData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 164 b.param, b.size, b.source, b.address, b.mask, b.data, b.corrupt 165 ) 166 } 167 168 is(Get) { 169 XSDebug(false, true.B, 170 b.channelName + " Get param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 171 b.param, b.size, b.source, b.address, b.mask, b.data, b.corrupt 172 ) 173 } 174 175 is(Hint) { 176 XSDebug(false, true.B, 177 b.channelName + " Intent param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 178 b.param, b.size, b.source, b.address, b.mask, b.data, b.corrupt 179 ) 180 } 181 182 is(Probe) { 183 switch(b.param) { 184 is(toN) { 185 XSDebug(false, true.B, 186 b.channelName + " Probe toN size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 187 b.size, b.source, b.address, b.mask, b.data, b.corrupt 188 ) 189 } 190 is(toB) { 191 XSDebug(false, true.B, 192 b.channelName + " Probe toB size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 193 b.size, b.source, b.address, b.mask, b.data, b.corrupt 194 ) 195 } 196 is(toT) { 197 XSDebug(false, true.B, 198 b.channelName + " Probe toT size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n", 199 b.size, b.source, b.address, b.mask, b.data, b.corrupt 200 ) 201 } 202 } 203 } 204 205 } 206 } 207 208 def printChannelC(c: TLBundleC): Unit = { 209 switch(c.opcode) { 210 is(AccessAck) { 211 XSDebug(false, true.B, 212 c.channelName + " AccessAck param: %x size: %x source: %d address: %x data: %x corrupt: %b\n", 213 c.param, c.size, c.source, c.address, c.data, c.corrupt 214 ) 215 } 216 217 is(AccessAckData) { 218 XSDebug(false, true.B, 219 c.channelName + " AccessAckData param: %x size: %x source: %d address: %x data: %x corrupt: %b\n", 220 c.param, c.size, c.source, c.address, c.data, c.corrupt 221 ) 222 } 223 224 is(HintAck) { 225 XSDebug(false, true.B, 226 c.channelName + " HintAck param: %x size: %x source: %d address: %x data: %x corrupt: %b\n", 227 c.param, c.size, c.source, c.address, c.data, c.corrupt 228 ) 229 } 230 231 is(ProbeAck) { 232 switch(c.param) { 233 is(TtoB) { 234 XSDebug(false, true.B, 235 c.channelName + " ProbeAck TtoB size: %x source: %d address: %x data: %x corrupt: %b\n", 236 c.size, c.source, c.address, c.data, c.corrupt 237 ) 238 } 239 is(TtoN) { 240 XSDebug(false, true.B, 241 c.channelName + " ProbeAck TtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 242 c.size, c.source, c.address, c.data, c.corrupt 243 ) 244 } 245 is(BtoN) { 246 XSDebug(false, true.B, 247 c.channelName + " ProbeAck BtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 248 c.size, c.source, c.address, c.data, c.corrupt 249 ) 250 } 251 is(TtoT) { 252 XSDebug(false, true.B, 253 c.channelName + " ProbeAck TtoT size: %x source: %d address: %x data: %x corrupt: %b\n", 254 c.size, c.source, c.address, c.data, c.corrupt 255 ) 256 } 257 is(BtoB) { 258 XSDebug(false, true.B, 259 c.channelName + " ProbeAck BtoB size: %x source: %d address: %x data: %x corrupt: %b\n", 260 c.size, c.source, c.address, c.data, c.corrupt 261 ) 262 } 263 is(NtoN) { 264 XSDebug(false, true.B, 265 c.channelName + " ProbeAck NtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 266 c.size, c.source, c.address, c.data, c.corrupt 267 ) 268 } 269 } 270 } 271 272 is(ProbeAckData) { 273 switch(c.param) { 274 is(TtoB) { 275 XSDebug(false, true.B, 276 c.channelName + " ProbeAckData TtoB size: %x source: %d address: %x data: %x corrupt: %b\n", 277 c.size, c.source, c.address, c.data, c.corrupt 278 ) 279 } 280 is(TtoN) { 281 XSDebug(false, true.B, 282 c.channelName + " ProbeAckData TtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 283 c.size, c.source, c.address, c.data, c.corrupt 284 ) 285 } 286 is(BtoN) { 287 XSDebug(false, true.B, 288 c.channelName + " ProbeAckData BtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 289 c.size, c.source, c.address, c.data, c.corrupt 290 ) 291 } 292 is(TtoT) { 293 XSDebug(false, true.B, 294 c.channelName + " ProbeAckData TtoT size: %x source: %d address: %x data: %x corrupt: %b\n", 295 c.size, c.source, c.address, c.data, c.corrupt 296 ) 297 } 298 is(BtoB) { 299 XSDebug(false, true.B, 300 c.channelName + " ProbeAckData BtoB size: %x source: %d address: %x data: %x corrupt: %b\n", 301 c.size, c.source, c.address, c.data, c.corrupt 302 ) 303 } 304 is(NtoN) { 305 XSDebug(false, true.B, 306 c.channelName + " ProbeAckData NtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 307 c.size, c.source, c.address, c.data, c.corrupt 308 ) 309 } 310 } 311 } 312 313 is(Release) { 314 switch(c.param) { 315 is(TtoB) { 316 XSDebug(false, true.B, 317 c.channelName + " Release TtoB size: %x source: %d address: %x data: %x corrupt: %b\n", 318 c.size, c.source, c.address, c.data, c.corrupt 319 ) 320 } 321 is(TtoN) { 322 XSDebug(false, true.B, 323 c.channelName + " Release TtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 324 c.size, c.source, c.address, c.data, c.corrupt 325 ) 326 } 327 is(BtoN) { 328 XSDebug(false, true.B, 329 c.channelName + " Release BtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 330 c.size, c.source, c.address, c.data, c.corrupt 331 ) 332 } 333 is(TtoT) { 334 XSDebug(false, true.B, 335 c.channelName + " Release TtoT size: %x source: %d address: %x data: %x corrupt: %b\n", 336 c.size, c.source, c.address, c.data, c.corrupt 337 ) 338 } 339 is(BtoB) { 340 XSDebug(false, true.B, 341 c.channelName + " Release BtoB size: %x source: %d address: %x data: %x corrupt: %b\n", 342 c.size, c.source, c.address, c.data, c.corrupt 343 ) 344 } 345 is(NtoN) { 346 XSDebug(false, true.B, 347 c.channelName + " Release NtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 348 c.size, c.source, c.address, c.data, c.corrupt 349 ) 350 } 351 } 352 } 353 354 is(ReleaseData) { 355 switch(c.param) { 356 is(TtoB) { 357 XSDebug(false, true.B, 358 c.channelName + " ReleaseData TtoB size: %x source: %d address: %x data: %x corrupt: %b\n", 359 c.size, c.source, c.address, c.data, c.corrupt 360 ) 361 } 362 is(TtoN) { 363 XSDebug(false, true.B, 364 c.channelName + " ReleaseData TtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 365 c.size, c.source, c.address, c.data, c.corrupt 366 ) 367 } 368 is(BtoN) { 369 XSDebug(false, true.B, 370 c.channelName + " ReleaseData BtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 371 c.size, c.source, c.address, c.data, c.corrupt 372 ) 373 } 374 is(TtoT) { 375 XSDebug(false, true.B, 376 c.channelName + " ReleaseData TtoT size: %x source: %d address: %x data: %x corrupt: %b\n", 377 c.size, c.source, c.address, c.data, c.corrupt 378 ) 379 } 380 is(BtoB) { 381 XSDebug(false, true.B, 382 c.channelName + " ReleaseData BtoB size: %x source: %d address: %x data: %x corrupt: %b\n", 383 c.size, c.source, c.address, c.data, c.corrupt 384 ) 385 } 386 is(NtoN) { 387 XSDebug(false, true.B, 388 c.channelName + " ReleaseData NtoN size: %x source: %d address: %x data: %x corrupt: %b\n", 389 c.size, c.source, c.address, c.data, c.corrupt 390 ) 391 } 392 } 393 } 394 395 } 396 } 397 398 def printChannelD(d: TLBundleD): Unit = { 399 switch(d.opcode) { 400 is(AccessAck) { 401 XSDebug(false, true.B, 402 d.channelName + " AccessAck param: %x size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n", 403 d.param, d.size, d.source, d.sink, d.denied, d.data, d.corrupt 404 ) 405 } 406 407 is(AccessAckData) { 408 XSDebug(false, true.B, 409 d.channelName + " AccessAckData param: %x size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n", 410 d.param, d.size, d.source, d.sink, d.denied, d.data, d.corrupt 411 ) 412 } 413 414 is(HintAck) { 415 XSDebug(false, true.B, 416 d.channelName + " HintAck param: %x size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n", 417 d.param, d.size, d.source, d.sink, d.denied, d.data, d.corrupt 418 ) 419 } 420 421 is(Grant) { 422 switch(d.param) { 423 is(toT) { 424 XSDebug(false, true.B, 425 d.channelName + " Grant toT size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n", 426 d.size, d.source, d.sink, d.denied, d.data, d.corrupt 427 ) 428 } 429 is(toB) { 430 XSDebug(false, true.B, 431 d.channelName + " Grant toB size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n", 432 d.size, d.source, d.sink, d.denied, d.data, d.corrupt 433 ) 434 } 435 is(toN) { 436 XSDebug(false, true.B, 437 d.channelName + " Grant toN size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n", 438 d.size, d.source, d.sink, d.denied, d.data, d.corrupt 439 ) 440 } 441 } 442 } 443 444 is(GrantData) { 445 switch(d.param) { 446 is(toT) { 447 XSDebug(false, true.B, 448 d.channelName + " GrantData toT size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n", 449 d.size, d.source, d.sink, d.denied, d.data, d.corrupt 450 ) 451 } 452 is(toB) { 453 XSDebug(false, true.B, 454 d.channelName + " GrantData toB size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n", 455 d.size, d.source, d.sink, d.denied, d.data, d.corrupt 456 ) 457 } 458 is(toN) { 459 XSDebug(false, true.B, 460 d.channelName + " GrantData toN size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n", 461 d.size, d.source, d.sink, d.denied, d.data, d.corrupt 462 ) 463 } 464 } 465 } 466 467 is(ReleaseAck) { 468 XSDebug(false, true.B, 469 d.channelName + " ReleaseAck param: %x size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n", 470 d.param, d.size, d.source, d.sink, d.denied, d.data, d.corrupt 471 ) 472 } 473 474 } 475 } 476 477 def printChannelE(e: TLBundleE): Unit = { 478 XSDebug(false, true.B, e.channelName + "GrantAck sink: %d\n", e.sink) 479 } 480 481} 482