summaryrefslogtreecommitdiff
path: root/docs/src/explanations/printing.md
blob: 71a6f5cfdfc847a13426aa958c0006bff0bc6dce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
---
layout: docs
title:  "Printing"
section: "chisel3"
---

# Printing in Chisel

Chisel provides the `printf` function for debugging purposes. It comes in two flavors:

* [Scala-style](#scala-style)
* [C-style](#c-style)

### Scala-style

Chisel also supports printf in a style similar to [Scala's String Interpolation](http://docs.scala-lang.org/overviews/core/string-interpolation.html). Chisel provides a custom string interpolator `cf` which follows C-style format specifiers (see section [C-style](#c-style) below). Here's a few examples of using the `cf` interpolator:

```scala mdoc:invisible
import chisel3._
```
```scala mdoc:compile-only
val myUInt = 33.U
printf(cf"myUInt = $myUInt") // myUInt = 33
```

Note that when concatenating `cf"..."` strings, you need to start with a `cf"..."` string:

```scala mdoc:compile-only
// Does not interpolate the second string
val myUInt = 33.U
printf("my normal string" + cf"myUInt = $myUInt")
```

#### Simple formatting

Other formats are available as follows:

```scala mdoc:compile-only
val myUInt = 33.U
// Hexadecimal
printf(cf"myUInt = 0x$myUInt%x") // myUInt = 0x21
// Binary
printf(cf"myUInt = $myUInt%b") // myUInt = 100001
// Character
printf(cf"myUInt = $myUInt%c") // myUInt = !
```

#### Aggregate data-types

Chisel provides default custom "pretty-printing" for Vecs and Bundles. The default printing of a Vec is similar to printing a Seq or List in Scala while printing a Bundle is similar to printing a Scala Map.

```scala mdoc:compile-only
val myVec = VecInit(5.U, 10.U, 13.U)
printf(cf"myVec = $myVec") // myVec = Vec(5, 10, 13)

val myBundle = Wire(new Bundle {
  val foo = UInt()
  val bar = UInt()
})
myBundle.foo := 3.U
myBundle.bar := 11.U
printf(cf"myBundle = $myBundle") // myBundle = Bundle(a -> 3, b -> 11)
```

#### Custom Printing

Chisel also provides the ability to specify _custom_ printing for user-defined Bundles.

```scala mdoc:compile-only
class Message extends Bundle {
  val valid = Bool()
  val addr = UInt(32.W)
  val length = UInt(4.W)
  val data = UInt(64.W)
  override def toPrintable: Printable = {
    val char = Mux(valid, 'v'.U, '-'.U)
    cf"Message:\n" +
    cf"  valid  : $char%c\n" +
    cf"  addr   : $addr%x\n" +
    cf"  length : $length\n" +
    cf"  data   : $data%x\n"
  }
}

val myMessage = Wire(new Message)
myMessage.valid := true.B
myMessage.addr := "h1234".U
myMessage.length := 10.U
myMessage.data := "hdeadbeef".U

printf(cf"$myMessage")
```

Which prints the following:

```
Message:
  valid  : v
  addr   : 0x00001234
  length : 10
  data   : 0x00000000deadbeef
```

Notice the use of `+` between `cf` interpolated "strings". The results of `cf` interpolation can be concatenated by using the `+` operator.

### C-Style

Chisel provides `printf` in a similar style to its C namesake. It accepts a double-quoted format string and a variable number of arguments which will then be printed on rising clock edges. Chisel supports the following format specifiers:

| Format Specifier | Meaning |
| :-----: | :-----: |
| `%d` | decimal number |
| `%x` | hexadecimal number |
| `%b` | binary number |
| `%c` | 8-bit ASCII character |
| `%%` | literal percent |

It also supports a small set of escape characters:

| Escape Character | Meaning |
| :-----: | :-----: |
| `\n` | newline |
| `\t` | tab |
| `\"` | literal double quote |
| `\'` | literal single quote |
| `\\` | literal backslash |

Note that single quotes do not require escaping, but are legal to escape.

Thus printf can be used in a way very similar to how it is used in C:

```scala mdoc:compile-only
val myUInt = 32.U
printf("myUInt = %d", myUInt) // myUInt = 32
```