Skip to content

Commit

Permalink
Support banks with multiports in modes
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardalee committed Oct 7, 2024
1 parent 9614b9d commit 11b4ff5
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 15 deletions.
61 changes: 48 additions & 13 deletions core/src/main/java/org/lflang/generator/c/CGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -656,33 +656,68 @@ protected String getConflictingConnectionsInModalReactorsBody(VarRef sourceRef,
WidthSpec sourceWidth = sourceAsPort.getWidthSpec();
WidthSpec destWidth = destAsPort.getWidthSpec();

// FIXME: Support banks (for the containers)
// If the source or dest is a port of a bank, we need to iterate over it.
var isBank = false;
Instantiation bank = null;
var sourceContainerRef = "";
if (sourceContainer != null) {
sourceContainerRef = sourceContainer.getName() + ".";
bank = sourceContainer;
if (bank.getWidthSpec() != null) {
isBank = true;
sourceContainerRef = sourceContainer.getName() + "[j].";
}
}
var sourceIndex = isBank ? "i" : "count";
var source =
(sourceContainer != null ? sourceContainer.getName() + "." : "")
sourceContainerRef
+ sourceAsPort.getName()
+ ((sourceWidth != null) ? "[i]" : "");
+ ((sourceWidth != null) ? "[" + sourceIndex + "]" : "");
var destContainerRef = "";
var destIndex = "count";
if (destContainer != null) {
destIndex = "i";
destContainerRef = destContainer.getName() + ".";
if (bank == null) {
bank = destContainer;
if (bank.getWidthSpec() != null) {
isBank = true;
destContainerRef = destContainer.getName() + "[j].";
}
}
}
var dest =
(destContainer != null ? destContainer.getName() + "." : "")
destContainerRef
+ destAsPort.getName()
+ ((destWidth != null) ? "[i]" : "");
+ ((destWidth != null) ? "[" + destIndex + "]" : "");
var result = new StringBuilder();
result.append("{ int count = 0; SUPPRESS_UNUSED_WARNING(count); ");
// If either side is a bank (only one side should be), iterate over it.
if (isBank) {
var width = new StringBuilder();
for (var term : bank.getWidthSpec().getTerms()) {
if (!width.isEmpty()) width.append(" + ");
if (term.getCode() != null) width.append(term.getCode().getBody());
else if (term.getParameter() != null) width.append("self->" + term.getParameter());
else width.append(term.getWidth());
}
result.append("for(int j = 0; j < " + width.toString() + "; j++) { ");
}
// If either side is a multiport, iterate.
// Note that one side could be a multiport of width 1 and the other an ordinary port.
var result = new StringBuilder();
if (sourceWidth != null || destWidth != null) {
var width =
(sourceAsPort.getWidthSpec() != null)
? ((sourceContainer != null)
? sourceContainer.getName() + "." + sourceAsPort.getName()
: sourceAsPort.getName())
: ((destContainer != null)
? destContainer.getName() + "." + destAsPort.getName()
: destAsPort.getName());
? sourceContainerRef + sourceAsPort.getName()
: destContainerRef + destAsPort.getName();
result.append("for(int i = 0; i < " + width + "_width; i++) { ");
}
result.append("lf_set(" + dest + ", " + source + "->value);");
result.append("lf_set(" + dest + ", " + source + "->value); count++; ");
if (sourceWidth != null || destAsPort.getWidthSpec() != null) {
result.append(" }");
}
if (isBank) result.append(" }");
result.append(" }");
return result.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,9 @@ public static int maxContainedReactorBankWidth(
nestedBreadcrumbs.add(mainDef);
}
int result = max;
Reactor parent = containedReactor.eContainer() instanceof Mode?
(Reactor) containedReactor.eContainer().eContainer()
Reactor parent =
containedReactor.eContainer() instanceof Mode
? (Reactor) containedReactor.eContainer().eContainer()
: (Reactor) containedReactor.eContainer();
if (parent == ASTUtils.toDefinition(mainDef.getReactorClass())) {
// The parent is main, so there can't be any other instantiations of it.
Expand Down
67 changes: 67 additions & 0 deletions test/C/src/modal_models/ModalMultiportBank.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
target C {
timeout: 1 ms
}

reactor Destination(n_inputs: int = 2) {
input[n_inputs] req: int
output[n_inputs] rsp: int

reaction(req) -> rsp {=
for (int i = 0; i < self->n_inputs; ++i) {
if (req[i]->is_present) {
lf_set (rsp[i], req[i]->value);
}
}
=}
}

reactor Source(n_ports: int = 4) {
output[n_ports] req: int
input[n_ports] rsp: int
timer t(0, 1 ms)

reaction(t) -> req {=
for (int i = 0; i < self->n_ports; ++i) {
lf_set (req[i], i);
}
=}

reaction(rsp) {=
for (int i = 0; i < self->n_ports; ++i) {
lf_print("Received response:%d", rsp[i]->value);
if (rsp[i]->value != i) {
lf_print_error_and_exit("Expected %d", i);
}
}
=}
}

reactor Selector(n_ports: int = 4) {
input[n_ports] in_req: int
output[n_ports] out_rsp: int

initial mode DST_1 {
dst1 = new[2] Destination()

in_req -> dst1.req
dst1.rsp -> out_rsp
reaction(startup) -> reset(DST_2) {=
lf_set_mode(DST_2);
=}
}

mode DST_2 {
dst2 = new[2] Destination()

in_req -> dst2.req
dst2.rsp -> out_rsp
}
}

main reactor {
src = new Source()
sel = new Selector()

src.req -> sel.in_req
sel.out_rsp -> src.rsp
}

0 comments on commit 11b4ff5

Please sign in to comment.