Skip to content

Chisel tips&tricks

erling edited this page Sep 25, 2019 · 7 revisions

DontTouch

To prevent the FIRRTL compiler to optimize your structures away wrap them in dontTouch()'s

Wrap-around inc/dec/add/sub

object WrapAdd
{
  // "n" is the number of increments, so we wrap at n-1.
  def apply(value: UInt, amt: UInt, n: Int): UInt = {
    if (isPow2(n)) {
      (value + amt)(log2Ceil(n)-1,0)
    } else {
      val sum = Cat(0.U(1.W), value) + Cat(0.U(1.W), amt)
      Mux(sum >= n.U,
          sum - n.U,
          sum)
    }
  }
}

pretty print chisel wires before elaboration

  • enables flat printing of nested bundles (e.g. IO)
def prettyPrintIO(d: Data, depth: Int = 0, indent: String = "  ") : String = {
    val desc = d match {
      case aggregate: Aggregate => aggregate match {
        case vec: Vec[_] => {
          val children = vec.map((d) => s"${indent * (depth + 1)}${prettyPrintIO(d, depth + 1)},\n"
          ).reduce(_+_)
          s"Vec(\n$children${indent * depth})"
        }
        case record: Record => record match {
          case bundle: Bundle => {
            val className = bundle.getClass.getName
            val name = if (className.contains("$")) bundle.className else className
            val children = bundle.elements.toList.reverse.map {
              case (st, d) => s"${indent * (depth + 1)}$st = ${prettyPrintIO(d, depth + 1)}\n"
            }.reduce(_+_)
            s"$name{\n$children${indent * depth}}"
          }
          case _ => record.className
        }
      }
      case element: Element => {
        val widthInfo = s"(${if (element.widthKnown) element.getWidth + ".W" else ""})"
        element match {
          case bool: Bool => "Bool()"
          case uint: UInt => s"UInt($widthInfo)"
          case sint: SInt => s"SInt($widthInfo)"
          case _ => s"${element.getClass.getName}(${if (element.widthKnown) element.getWidth else "?"})"
        }
      }
      case _ => "Data??"
    }
    d.dir match {
      case Chisel.INPUT => s"Input($desc)"
      case Chisel.NODIR => s"$desc"
      case Chisel.OUTPUT => s"Output($desc)"
    }
  }

  println(prettyPrintIO(io))
  • sample output for IO of HellaCacheArbiter
Bundle{
  mem = freechips.rocketchip.rocket.HellaCacheIO{
    clock_enabled = Input(Bool())
    keep_clock_enabled = Output(Bool())
    perf = freechips.rocketchip.rocket.HellaCachePerfEvents{
      blocked = Input(Bool())
      tlbMiss = Input(Bool())
      grant = Input(Bool())
      release = Input(Bool())
      acquire = Input(Bool())
    }
    ordered = Input(Bool())
    s2_xcpt = freechips.rocketchip.rocket.HellaCacheExceptions{
      ae = freechips.rocketchip.rocket.AlignmentExceptions{
        st = Input(Bool())
        ld = Input(Bool())
      }
      pf = freechips.rocketchip.rocket.AlignmentExceptions{
        st = Input(Bool())
        ld = Input(Bool())
      }
      ma = freechips.rocketchip.rocket.AlignmentExceptions{
        st = Input(Bool())
        ld = Input(Bool())
      }
    }
    replay_next = Input(Bool())
    resp = chisel3.util.Valid{
      bits = freechips.rocketchip.rocket.HellaCacheResp{
        store_data = Input(UInt((64.W)))
        data_raw = Input(UInt((64.W)))
        data_word_bypass = Input(UInt((64.W)))
        has_data = Input(Bool())
        replay = Input(Bool())
        data = Input(UInt((64.W)))
        typ = Input(UInt((3.W)))
        cmd = Input(UInt((5.W)))
        tag = Input(UInt((7.W)))
        addr = Input(UInt((40.W)))
      }
      valid = Input(Bool())
    }
    s2_kill = Output(Bool())
    s2_nack_cause_raw = Input(Bool())
    s2_nack = Input(Bool())
    s1_data = freechips.rocketchip.rocket.HellaCacheWriteData{
      mask = Output(UInt((8.W)))
      data = Output(UInt((64.W)))
    }
    s1_kill = Output(Bool())
    req = chisel3.util.DecoupledIO{
      bits = freechips.rocketchip.rocket.HellaCacheReq{
        data = Output(UInt((64.W)))
        phys = Output(Bool())
        typ = Output(UInt((3.W)))
        cmd = Output(UInt((5.W)))
        tag = Output(UInt((7.W)))
        addr = Output(UInt((40.W)))
      }
      valid = Output(Bool())
      ready = Input(Bool())
    }
  }
  requestor = Vec(
    freechips.rocketchip.rocket.HellaCacheIO{
      clock_enabled = Output(Bool())
      keep_clock_enabled = Input(Bool())
      perf = freechips.rocketchip.rocket.HellaCachePerfEvents{
        blocked = Output(Bool())
        tlbMiss = Output(Bool())
        grant = Output(Bool())
        release = Output(Bool())
        acquire = Output(Bool())
      }
      ordered = Output(Bool())
      s2_xcpt = freechips.rocketchip.rocket.HellaCacheExceptions{
        ae = freechips.rocketchip.rocket.AlignmentExceptions{
          st = Output(Bool())
          ld = Output(Bool())
        }
        pf = freechips.rocketchip.rocket.AlignmentExceptions{
          st = Output(Bool())
          ld = Output(Bool())
        }
        ma = freechips.rocketchip.rocket.AlignmentExceptions{
          st = Output(Bool())
          ld = Output(Bool())
        }
      }
      replay_next = Output(Bool())
      resp = chisel3.util.Valid{
        bits = freechips.rocketchip.rocket.HellaCacheResp{
          store_data = Output(UInt((64.W)))
          data_raw = Output(UInt((64.W)))
          data_word_bypass = Output(UInt((64.W)))
          has_data = Output(Bool())
          replay = Output(Bool())
          data = Output(UInt((64.W)))
          typ = Output(UInt((3.W)))
          cmd = Output(UInt((5.W)))
          tag = Output(UInt((7.W)))
          addr = Output(UInt((40.W)))
        }
        valid = Output(Bool())
      }
      s2_kill = Input(Bool())
      s2_nack_cause_raw = Output(Bool())
      s2_nack = Output(Bool())
      s1_data = freechips.rocketchip.rocket.HellaCacheWriteData{
        mask = Input(UInt((8.W)))
        data = Input(UInt((64.W)))
      }
      s1_kill = Input(Bool())
      req = chisel3.util.DecoupledIO{
        bits = freechips.rocketchip.rocket.HellaCacheReq{
          data = Input(UInt((64.W)))
          phys = Input(Bool())
          typ = Input(UInt((3.W)))
          cmd = Input(UInt((5.W)))
          tag = Input(UInt((7.W)))
          addr = Input(UInt((40.W)))
        }
        valid = Input(Bool())
        ready = Output(Bool())
      }
    },
    freechips.rocketchip.rocket.HellaCacheIO{
      clock_enabled = Output(Bool())
      keep_clock_enabled = Input(Bool())
      perf = freechips.rocketchip.rocket.HellaCachePerfEvents{
        blocked = Output(Bool())
        tlbMiss = Output(Bool())
        grant = Output(Bool())
        release = Output(Bool())
        acquire = Output(Bool())
      }
      ordered = Output(Bool())
      s2_xcpt = freechips.rocketchip.rocket.HellaCacheExceptions{
        ae = freechips.rocketchip.rocket.AlignmentExceptions{
          st = Output(Bool())
          ld = Output(Bool())
        }
        pf = freechips.rocketchip.rocket.AlignmentExceptions{
          st = Output(Bool())
          ld = Output(Bool())
        }
        ma = freechips.rocketchip.rocket.AlignmentExceptions{
          st = Output(Bool())
          ld = Output(Bool())
        }
      }
      replay_next = Output(Bool())
      resp = chisel3.util.Valid{
        bits = freechips.rocketchip.rocket.HellaCacheResp{
          store_data = Output(UInt((64.W)))
          data_raw = Output(UInt((64.W)))
          data_word_bypass = Output(UInt((64.W)))
          has_data = Output(Bool())
          replay = Output(Bool())
          data = Output(UInt((64.W)))
          typ = Output(UInt((3.W)))
          cmd = Output(UInt((5.W)))
          tag = Output(UInt((7.W)))
          addr = Output(UInt((40.W)))
        }
        valid = Output(Bool())
      }
      s2_kill = Input(Bool())
      s2_nack_cause_raw = Output(Bool())
      s2_nack = Output(Bool())
      s1_data = freechips.rocketchip.rocket.HellaCacheWriteData{
        mask = Input(UInt((8.W)))
        data = Input(UInt((64.W)))
      }
      s1_kill = Input(Bool())
      req = chisel3.util.DecoupledIO{
        bits = freechips.rocketchip.rocket.HellaCacheReq{
          data = Input(UInt((64.W)))
          phys = Input(Bool())
          typ = Input(UInt((3.W)))
          cmd = Input(UInt((5.W)))
          tag = Input(UInt((7.W)))
          addr = Input(UInt((40.W)))
        }
        valid = Input(Bool())
        ready = Output(Bool())
      }
    },
  )
}
Clone this wiki locally