Skip to content

Commit 1923558

Browse files
tpwrulesjfng
authored andcommitted
csr.bus: elaborate Multiplexer connections deterministically
Python sets have non-deterministic iteration, however dicts iterate in insertion order. Ensuring the Shadow range set is iterated in a deterministic order causes chunks to be built in a deterministic order and thus chunks/registers to be processed in a deterministic order inside `elaborate()`. If they are processed non-deterministically, then the Case ordering and various temporary variable names are produced non-deterministically, causing a non-deterministic final RTLIL output, which is undesirable. Determinism is one of those things that's rather hard to prove true, but this nonetheless fixes a tested design's RTLIL output to be deterministic across all (several dozen) tested runs rather than be different almost every run.
1 parent fe75f40 commit 1923558

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

amaranth_soc/csr/bus.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,10 @@ def prepare(self):
472472
registers = defaultdict(list)
473473
balanced = True
474474

475-
for reg_range in self._ranges:
475+
# sort ranges in an arbitrary but nice fashion so that we build registers and so create
476+
# chunks and elaborate their connections deterministically
477+
ranges = sorted(self._ranges, key=lambda r: (r.start, r.stop, r.step))
478+
for reg_range in ranges:
476479
for chunk_addr in reg_range:
477480
chunk_offset = self.decode_address(chunk_addr, reg_range)
478481
if len(registers[chunk_offset]) > self.overlaps:

0 commit comments

Comments
 (0)