[Libre-soc-bugs] [Bug 708] New: PartitionedSignal API design
bugzilla-daemon at libre-soc.org
bugzilla-daemon at libre-soc.org
Thu Sep 23 22:06:32 BST 2021
https://bugs.libre-soc.org/show_bug.cgi?id=708
Bug ID: 708
Summary: PartitionedSignal API design
Product: Libre-SOC's first SoC
Version: unspecified
Hardware: Other
OS: Linux
Status: CONFIRMED
Severity: enhancement
Priority: ---
Component: Source Code
Assignee: programmerjake at gmail.com
Reporter: programmerjake at gmail.com
CC: libre-soc-bugs at lists.libre-soc.org
Blocks: 458
NLnet milestone: ---
I think what we need to do is have the entire PartitionedSignal (and related)
API be more like SIMT -- where basically all operations operate in-parallel and
independently on each partition, including Cat, Mux, slicing, +, If, Switch,
Case, conversion from Signal (which I think should only happen explicitly via a
splat function/static-method, otherwise mixing PartitionedSignal and Signal
results in a type error), conversion from int, etc.
Essentially we treat a PartitionedSignal conceptually as a list of Signals
where all normal operations operate element-wise on each signal in the list.
I think this makes the code waay more readable and consistent.
There would be specially designated methods for converting the whole
PartitionedSignal from/to their underlying Signals (think of conceptually
concatenating all signals in a list together, or splitting a signal into a list
of signals).
PartitionedSignal would essentially end up being a list of Signals (not
literally, they would be pieces of a Signal), where the Signals could be either
dynamically sized or statically sized, the size would be chosen at runtime by
combinatorial logic (basically a small lookup table) based on a layout enum.
that layout enum (with the combinatorial logic) replaces PartitionPoints. This
allows things like:
class FPULayoutEnum(Enum):
F16x4 = ...
F32x2 = ...
F64x1 = ...
exponent_field_layout = { # probably in a FP layout class
FPULayoutEnum.F16x4: 5,
FPULayoutEnum.F32x2: 8,
FPULayoutEnum.F64x1: 11
}
exponent_field_slice = { # probably in a FP layout class
FPULayoutEnum.F16x4: slice(10,16),
FPULayoutEnum.F32x2: slice(23,32),
FPULayoutEnum.F64x1: slice(52,64)
}
float_layout = { # probably next to FPULayoutEnum
FPULayoutEnum.F16x4: 16,
FPULayoutEnum.F32x2: 32,
FPULayoutEnum.F64x1: 64
}
class MyFPUStage:
def __init__(self):
self.fpu_layout = Signal(FPULayoutEnum)
with PartitionedSignal.layout_scope(self.fpu_layout):
self.float_bits = PartitionedSignal(float_layout)
self.exponent_field = PartitionedSignal(exponent_field_layout)
def elaborate(self, ...):
m = Module()
with PartitionedSignal.layout_scope(self.fpu_layout):
# generic over all float types! easy to read/think about!
m.d.comb += exponent_field.eq(float_bits[exponent_field_slice])
# do stuff with exponent_field...
return m
This means PartitionedSignal would sometimes be partitioned in a more complex
way, such as if all partitions always have 5 bits (conceptually like [Signal(5)
for _ in ...]) -- there would need to be gaps in some cases.
For all examples:
a, b, and c are PartitionedSignal,
s is a Signal
v is a Python variable
Examples:
v = a + b # adding PartitionedSignal
conceptual equivalent:
v = [i + j for i, j in zip(a, b)]
v = a + splat(s)
conceptual equivalent:
v = [i + s for i in a]
v = a + s # adding PartitionedSignal and Signal
conceptual equivalent:
raise TypeError()
v = splat(s)
conceptual equivalent:
v = [s] * len(partitions)
v = Cat(a, b, c)
conceptual equivalent:
v = [Cat(i, j, k) for i, j, k in zip(a, b, c)]
v = Cat(a, s) # `Cat`ting PartitionedSignal and Signal
conceptual equivalent:
raise TypeError()
v = a[3:5]
conceptual equivalent:
v = [i[3:5] for i in a]
with m.Switch(a):
with m.Case(3, 10, '--101'):
m.d.comb += b.eq(23)
with m.Default():
m.d.comb += b.eq(45)
conceptual equivalent:
for i, j in zip(a, b):
with m.Switch(i):
with m.Case(3, 10, '--101'):
m.d.comb += j.eq(23)
with m.Default():
m.d.comb += j.eq(45)
v = PartitionedSignal(underlying=s, partitions=...)
conceptual equivalent:
v = list(s.partitions()) # more or less...
v = a.underlying
conceptual equivalent:
v = Cat(*a) # more or less...
Referenced Bugs:
https://bugs.libre-soc.org/show_bug.cgi?id=458
[Bug 458] PartitionedSignal needs nmigen constructs "m.If", Switch etc
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the libre-soc-bugs
mailing list