PartitionedSignal nmigen-aware Cat

Concatenation of Signals is ordinarily straightforward: reduce to the bitlevel and create a sequence. The contributors to that sequence may be of arbitrary length.

However for a PartitionedSignal unless all contributors are also PartitionedSignals, the results cannot be guaranteed to match, at all partition sizes.

Take two PartitionedSignals:

partition:      p    p    p       (3 bits)
a        :  AAA3 AAA2 AAA1 AAA0  (32 bits)
b        :  BBB3 BBB2 BBB1 BBB0  (32 bits)

When the partitions are 32-bit, the output is:

partition:           p         p         p           (3 bits)
out      :  AAA3 AAA2 AAA1 AAA0 BBB3 BBB2 BBB1 BBB0  (64 bits)

When 2x16, the top 2 halves of A and B are Catted together, and likewise the lower:

partition:           p         p         p           (3 bits)
out      :  AAA3 AAA2 BBB3 BBB2 AAA1 AAA0 BBB1 BBB0  (64 bits)

Finally when 4x8, each byte is concatenated:

partition:           p         p         p           (3 bits)
out      :  AAA3 BBB3 AAA2 BBB2 AAA1 BBB1 AAA0 BBB0  (64 bits)

This then generalises regardless of the number of PartitionedSignals being Concatenated, and regardless of whether the length of any individual PartitionedSignal is of differing length. Bearing in mind that Partitions may only be on equal sized points (4x 4-bit, not 3x 3-bit plus one 5-bit):

To confirm that let us assume that A is 16-bit and B is 32-bit:

partition:      p    p    p       (3 bits)
a        :    A3   A2   A1   A0  (16 bits)
b        :  BBB3 BBB2 BBB1 BBB0  (32 bits)

Output will always be 48 bits, and the partitions we need to confirm but assume will be 4+8=12 bits. When the partitions are 1x, the output is:

partition:          0       0       0         (3 bits)
out      :  A3 A2 A1 A0 BBB3 BBB2 BBB1 BBB0  (48 bits)

When 2x:

partition:          0      1        0         (3 bits)
out      :  A3 A2 BBB3 BBB2 A1 A0 BBB1 BBB0  (48 bits)

Finally when 4x:

partition:         1       1       1           (3 bits)
out      :  A3 BBB3 A2 BBB2 A1 BBB1 A0 BBB0  (48 bits)

By a lucky coincidence the lengths match up. In the 1x case, the result is a single 48-bit quantity. In the 2x case, the result is two 24-bit quantities. Finally in the 4x case, the result is four 12-bit quantities.

The reason this works is down to the requirement that Partitions be of equal sizes. 4x 4-bit to be Concatenated with 4x 8-bit, in the last example.

Table for 2-way concatenation, divided by partition:

partition o3 o2 o1 o0
000 a3 a2 a1 a0 b3 b2 b1 b0
001 a3 a2 a1 b3 b2 b1 a0 b0
010 a3 a2 b3 b2 a1 a0 b1 b0
011 a3 a2 b3 b2 a1 b1 a0 b0
100 a3 b3 a2 a1 a0 b2 b1 b0
101 a3 b3 a2 a1 b2 b1 a0 b0
110 a3 b3 a2 b2 a1 a0 b1 b0
111 a3 b3 a2 b2 a1 b1 a0 b0

Table for 3-way concatenation, divided by partition:

partition o3 o2 o1 o0
000 a3 a2 a1 a0 b3 b2 b1 b0 c3 c2 c1 c0
001 a3 a2 a1 b3 b2 b1 c3 c2 c1 a0 b0 c0
010 a3 a2 b3 b2 c3 c2 a1 a0 b1 b0 c1 c0
011 a3 a2 b3 b2 c3 c2 a1 b1 c1 a0 b0 c0
100 a3 b3 c3 a2 a1 a0 b2 b1 b0 c2 c1 c0
101 a3 b3 c3 a2 a1 b2 b1 c2 c1 a0 b0 c0
110 a3 b3 c3 a2 b2 c2 a1 a0 b1 b0 c1 c0
111 a3 b3 c3 a2 b2 c2 a1 b1 c1 a0 b0 c0