add code-comments
[ieee754fpu.git] / src / ieee754 / part / layout_experiment.py
1 #!/usr/bin/env python3
2 # SPDX-License-Identifier: LGPL-3-or-later
3 # See Notices.txt for copyright information
4 """
5 Links:
6 * https://libre-soc.org/3d_gpu/architecture/dynamic_simd/shape/
7 * https://bugs.libre-soc.org/show_bug.cgi?id=713#c20
8 * https://bugs.libre-soc.org/show_bug.cgi?id=713#c30
9 """
10
11 from nmigen import Signal, Module, Elaboratable, Mux, Cat, Shape, Repl
12 from nmigen.back.pysim import Simulator, Delay, Settle
13 from nmigen.cli import rtlil
14
15 from collections.abc import Mapping
16 from pprint import pprint
17
18 from ieee754.part_mul_add.partpoints import PartitionPoints
19
20
21 # main fn
22 def layout(elwid, signed, part_counts, lane_shapes):
23 # identify if the lane_shapes is a mapping (dict, etc.)
24 # if not, then assume that it is an integer (width) that
25 # needs to be requested across all partitions
26 if not isinstance(lane_shapes, Mapping):
27 lane_shapes = {i: lane_shapes for i in part_counts}
28 # compute a set of partition widths
29 part_wid = -min(-lane_shapes[i] // c for i, c in part_counts.items())
30 part_count = max(part_counts.values())
31 # calculate the minumum width required
32 width = part_wid * part_count
33 # create the breakpoints dictionary
34 points = {}
35 for i, c in part_counts.items():
36 def add_p(p):
37 points[p] = points.get(p, False) | (elwid == i)
38 for start in range(0, part_count, c):
39 add_p(start * part_wid) # start of lane
40 add_p(start * part_wid + lane_shapes[i]) # start of padding
41 # do not need the breakpoints at the very start or the very end
42 points.pop(0, None)
43 points.pop(width, None)
44 return (PartitionPoints(points), width, lane_shapes,
45 part_wid, part_count)
46
47 if __name__ == '__main__':
48 part_counts = {
49 0: 1,
50 1: 1,
51 2: 2,
52 3: 4,
53 }
54
55 for i in range(4):
56 pprint((i, layout(i, True, part_counts, 3)))
57
58 l = {0: 5, 1: 6, 2: 12, 3: 24}
59 for i in range(4):
60 pprint((i, layout(i, False, part_counts, l)))
61
62 # https://bugs.libre-soc.org/show_bug.cgi?id=713#c30
63 elwid = Signal(2)
64 pp,b,c,d,e = layout(elwid, False, part_counts, l)
65 pprint ((pp,b,c,d,e))
66
67 m = Module()
68 def process():
69 for i in range(4):
70 yield elwid.eq(i)
71 yield Settle()
72 ppt = []
73 for pval in list(pp.values()):
74 val = yield pval # get nmigen to evaluate pp
75 ppt.append(val)
76 pprint((i, (ppt,b,c,d,e)))
77 sim = Simulator(m)
78 sim.add_process(process)
79 sim.run()