Skip to content

Commit f0f5755

Browse files
committed
proc_mux: add comments
1 parent 3887be1 commit f0f5755

File tree

1 file changed

+53
-31
lines changed

1 file changed

+53
-31
lines changed

passes/proc/proc_mux.cc

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@
2828
USING_YOSYS_NAMESPACE
2929
PRIVATE_NAMESPACE_BEGIN
3030

31+
/**
32+
* Actions are assignments in cases of switches.
33+
* Snippets are non-overlapping slices of signals on the left-hand side
34+
* of actions. For example, if you have these two actions for r[7:0]:
35+
* r = a; r[1:2] = 2'b0;
36+
* you will arrive at three snippets:
37+
* r[0], r[2:1], r[7:3]
38+
* For each snippet, multiplexers ($mux or $pmux) are emitted
39+
* based on the full switch.
40+
* $pmux are only emitted when legal based on whether the cases can be
41+
* evaluated in parallel.
42+
* In that case, instead of a $pmux, you get a chain of $mux.
43+
* Nested switches build branching trees of muxes.
44+
*/
45+
3146
using SnippetSourceMap = std::vector<dict<const RTLIL::CaseRule*, const Const*>>;
3247
struct SnippetSourceMapBuilder {
3348
SnippetSourceMap map;
@@ -202,6 +217,7 @@ struct MuxGenCtx {
202217
int current_snippet;
203218
pool<std::string>& snippet_sources;
204219

220+
// Returns signal for the select input of a mux
205221
RTLIL::SigSpec gen_cmp() {
206222
std::stringstream sstr;
207223
sstr << "$procmux$" << (autoidx++);
@@ -408,6 +424,38 @@ bool is_simple_parallel_case(RTLIL::SwitchRule* sw, dict<RTLIL::SwitchRule*, boo
408424
return ret;
409425
}
410426

427+
std::vector<int> parallel_groups(MuxTreeContext ctx, RTLIL::SwitchRule* sw)
428+
{
429+
std::vector<int> pgroups(sw->cases.size());
430+
if (!is_simple_parallel_case(sw, ctx.swpara)) {
431+
BitPatternPool pool(sw->signal.size());
432+
bool extra_group_for_next_case = false;
433+
for (size_t i = 0; i < sw->cases.size(); i++) {
434+
RTLIL::CaseRule *cs2 = sw->cases[i];
435+
if (i != 0) {
436+
pgroups[i] = pgroups[i-1];
437+
if (extra_group_for_next_case) {
438+
pgroups[i] = pgroups[i-1]+1;
439+
extra_group_for_next_case = false;
440+
}
441+
for (auto pat : cs2->compare)
442+
if (!pat.is_fully_const() || !pool.has_all(pat))
443+
pgroups[i] = pgroups[i-1]+1;
444+
if (cs2->compare.empty())
445+
pgroups[i] = pgroups[i-1]+1;
446+
if (pgroups[i] != pgroups[i-1])
447+
pool = BitPatternPool(sw->signal.size());
448+
}
449+
for (auto pat : cs2->compare)
450+
if (!pat.is_fully_const())
451+
extra_group_for_next_case = true;
452+
else if (!ctx.ifxmode)
453+
pool.take(pat);
454+
}
455+
}
456+
return pgroups;
457+
}
458+
411459
RTLIL::SigSpec signal_to_mux_tree(MuxTreeContext ctx)
412460
{
413461
RTLIL::SigSpec result = ctx.defval;
@@ -422,36 +470,9 @@ RTLIL::SigSpec signal_to_mux_tree(MuxTreeContext ctx)
422470
if (!ctx.swcache.check(sw))
423471
continue;
424472

425-
// detect groups of parallel cases
426-
std::vector<int> pgroups(sw->cases.size());
473+
// Detect groups of parallel cases
474+
std::vector<int> pgroups = parallel_groups(ctx, sw);
427475
pool<std::string> case_sources;
428-
429-
if (!is_simple_parallel_case(sw, ctx.swpara)) {
430-
BitPatternPool pool(sw->signal.size());
431-
bool extra_group_for_next_case = false;
432-
for (size_t i = 0; i < sw->cases.size(); i++) {
433-
RTLIL::CaseRule *cs2 = sw->cases[i];
434-
if (i != 0) {
435-
pgroups[i] = pgroups[i-1];
436-
if (extra_group_for_next_case) {
437-
pgroups[i] = pgroups[i-1]+1;
438-
extra_group_for_next_case = false;
439-
}
440-
for (auto pat : cs2->compare)
441-
if (!pat.is_fully_const() || !pool.has_all(pat))
442-
pgroups[i] = pgroups[i-1]+1;
443-
if (cs2->compare.empty())
444-
pgroups[i] = pgroups[i-1]+1;
445-
if (pgroups[i] != pgroups[i-1])
446-
pool = BitPatternPool(sw->signal.size());
447-
}
448-
for (auto pat : cs2->compare)
449-
if (!pat.is_fully_const())
450-
extra_group_for_next_case = true;
451-
else if (!ctx.ifxmode)
452-
pool.take(pat);
453-
}
454-
}
455476
// Create sources for default cases
456477
for (auto cs2 : sw -> cases) {
457478
if (cs2->compare.empty()) {
@@ -466,7 +487,8 @@ RTLIL::SigSpec signal_to_mux_tree(MuxTreeContext ctx)
466487
result[i] = State::Sx;
467488

468489
RTLIL::SigSpec initial_val = result;
469-
MuxGenCtx mux_gen_ctx {ctx.mod,
490+
MuxGenCtx mux_gen_ctx {
491+
ctx.mod,
470492
sw->signal,
471493
nullptr,
472494
nullptr,
@@ -477,7 +499,7 @@ RTLIL::SigSpec signal_to_mux_tree(MuxTreeContext ctx)
477499
ctx.swcache.current_snippet,
478500
case_sources
479501
};
480-
// evaluate in reverse order to give the first entry the top priority
502+
// Evaluate in reverse order to give the first entry the top priority
481503
for (size_t i = 0; i < sw->cases.size(); i++) {
482504
int case_idx = sw->cases.size() - i - 1;
483505
MuxTreeContext new_ctx = ctx;

0 commit comments

Comments
 (0)