diff --git a/src/slang_frontend.cc b/src/slang_frontend.cc index 264369b..7761a0b 100644 --- a/src/slang_frontend.cc +++ b/src/slang_frontend.cc @@ -1470,7 +1470,7 @@ struct PopulateNetlist : public TimingPatternInterpretor, public ast::ASTVisitor // TODO: check for non-constant load values and warn about sim/synth mismatch } - if (aloads.size() > 1) { + if (aloads.size() > 2) { netlist.add_diag(diag::AloadOne, timed.timing.sourceRange); return; } @@ -1549,7 +1549,30 @@ struct PopulateNetlist : public TimingPatternInterpretor, public ast::ASTVisitor transfer_attrs(symbol, cell); } } - } else { + } else if (aloads.size() == 2) { + VariableBits dffsr_q; + for (int i = 0; i < driven_chunk.bitwidth(); i++) { + dffsr_q.append(driven_chunk[i]); + } + for (auto driven_chunk2 : dffsr_q.chunks()) { + for (auto [named_chunk, name] : generate_subfield_names(driven_chunk2, type)) { + auto set = netlist.Mux(RTLIL::SigSpec(0, named_chunk.bitwidth()), + RTLIL::SigSpec(-1, named_chunk.bitwidth()), aloads[1].trigger); + auto clr = netlist.Mux(RTLIL::SigSpec(0, named_chunk.bitwidth()), + RTLIL::SigSpec(-1, named_chunk.bitwidth()), aloads[0].trigger); + cell = netlist.canvas->addDffsr(netlist.canvas->uniquify("$driver$" + RTLIL::unescape_id(netlist.id(*named_chunk.variable.get_symbol())) + name), + timing.triggers[0].signal, + set, + clr, + assigned.extract(named_chunk.base - driven_chunk.base, named_chunk.bitwidth()), + netlist.convert_static(named_chunk), + timing.triggers[0].edge_polarity, + aloads[1].trigger_polarity, + aloads[0].trigger_polarity); + transfer_attrs(symbol, cell); + } + } + } else { log_abort(); } } diff --git a/tests/unit/rs_trigger.ys b/tests/unit/rs_trigger.ys new file mode 100644 index 0000000..33ea645 --- /dev/null +++ b/tests/unit/rs_trigger.ys @@ -0,0 +1,88 @@ +read_slang <