You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/0041-fixed-point.md
+19-14Lines changed: 19 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,35 +27,38 @@ TODO
27
27
28
28
This RFC proposes a library addition `amaranth.lib.fixed` with the following contents:
29
29
30
+
### `fixed.Shape`
31
+
30
32
`fixed.Shape` is a `ShapeCastable` subclass.
31
33
The following operations are defined on it:
32
34
33
-
-`fixed.Shape(f_width, /, *, signed)`: Create a `fixed.Shape` with zero integer bits and `f_width` fractional bits.
34
-
-`fixed.Shape(i_width, f_width, /, *, signed)`: Create a `fixed.Shape` with `i_width` integer bits and `f_width` fractional bits.
35
-
- The sign bit is not included in `i_width` or `f_width`, so a `fixed.Shape(7, 8, signed=True)` will be 16 bits wide.
36
-
-`fixed.Shape.cast(shape, f_width=0)`: Cast `shape` to a `fixed.Shape` instance.
37
-
-`.i_width`, `.f_width`, `.signed`: Width and signedness properties.
35
+
-`fixed.Shape(shape, f_bits)`: Create a `fixed.Shape` with underlying storage `shape` and `f_bits` fractional bits.
36
+
- The signedness is inherited from `shape`, so a `fixed.Shape(signed(16), 12)` would be a signed fixed-point number, 16 bits wide with 12 fractional bits.
37
+
- A `fixed.Shape` may be constructed using the following aliases:
38
+
-`SQ(i_bits, f_bits)` is an alias for `fixed.Shape(signed(i_bits + f_bits), f_bits)`.
39
+
-`UQ(i_bits, f_bits)` is an alias for `fixed.Shape(unsigned(i_bits + f_bits), f_bits)`.
40
+
-`fixed.Shape.cast(shape, f_bits=0)`: Cast `shape` to a `fixed.Shape` instance.
41
+
-`.i_bits`, `.f_bits`, `.signed`: Width and signedness properties of the `fixed.Shape`.
42
+
-`.i_bits` includes the sign bit. That is, for `fixed.Shape(signed(16), 12)`, `.i_bits == 4`.
38
43
-`.const(value)`: Create a `fixed.Const` from `value`.
39
44
-`.as_shape()`: Return the underlying `Shape`.
40
45
-`.__call__(target)`: Create a `fixed.Value` over `target`.
41
46
42
-
`SQ(*args)` is an alias for `fixed.Shape(*args, signed=True)`.
43
-
44
-
`UQ(*args)` is an alias for `fixed.Shape(*args, signed=False)`.
47
+
### `fixed.Value`
45
48
46
49
`fixed.Value` is a `ValueCastable` subclass.
47
50
The following operations are defined on it:
48
51
49
52
-`fixed.Value(shape, target)`: Create a `fixed.Value` with `shape` over `target`.
50
-
-`fixed.Value.cast(value, f_width=0)`: Cast `value` to a `fixed.Value`.
51
-
-`.i_width`, `.f_width`, `.signed`: Width and signedness properties.
53
+
-`fixed.Value.cast(value, f_bits=0)`: Cast `value` to a `fixed.Value`.
54
+
-`.i_bits`, `.f_bits`, `.signed`: Width and signedness properties.
52
55
-`.shape()`: Return the `fixed.Shape` this was created from.
53
56
-`.as_value()`: Return the underlying value.
54
57
-`.eq(value)`: Assign `value`.
55
58
- If `value` is a `Value`, it'll be assigned directly to the underlying `Value`.
56
59
- If `value` is an `int` or `float`, it'll be cast to a `fixed.Const` first.
57
60
- If `value` is a `fixed.Value`, the precision will be extended or rounded as required.
58
-
-`.round(f_width=0)`: Return a new `fixed.Value` with precision changed to `f_width`, rounding as required.
61
+
-`.round(f_bits=0)`: Return a new `fixed.Value` with precision changed to `f_bits`, rounding as required.
The following additional operations are defined on it:
70
75
@@ -93,9 +98,9 @@ TBD
93
98
Multiplying an integer with a fixedpoint constant and rounding the result back to an integer is a reasonable and likely common thing to want to do.
94
99
95
100
- There's two slightly different [Q notation](https://en.wikipedia.org/wiki/Q_(number_format)) definitions, namely whether the bit counts includes the sign bit or not.
96
-
Not having the sign bit included seems more common, and has the advantage that a number has the same fractional precision whether `i_width` is 0 or not.
97
-
98
-
- While Q notation names the signed type `Q`, it's more consistent for Amaranth to use `SQ` since other Amaranth types defaults to unsigned.
101
+
-Not having the sign bit included seems more common, and has the advantage that a number has the same fractional precision whether `i_bits` is 0 or not.
102
+
- Having the sign bit included is the dominant notation in the audio ASIC world (citation needed, comment from samimia-swks@). As of now, this RFC uses this notation as it is also a little simpler to reason about the size of underlying storage on constructing an `SQ`.
103
+
- While Q notation names the signed type `Q`, it's more consistent for Amaranth to use `SQ` since other Amaranth types defaults to unsigned.
0 commit comments