- Set<String> usedNames = declaration.getIOPorts().stream().map(IOPort::getName).collect(Collectors.toCollection(HashSet::new));
-
- for (Wire wire : internalWires)
- if (!usedNames.add(wire.getName()))
- throw new IllegalArgumentException("Name occurs twice: " + wire.getName());
-
- for (Assign assign : assigns)
- if (!allSignals.contains(assign.getSource()) || !allSignals.contains(assign.getTarget()))
- throw new IllegalArgumentException("Referenced an unknown signal: " + assign.getSource());
-
- for (ComponentReference subcomponent : subcomponents)
- if (!usedNames.add(subcomponent.getName()))
- throw new IllegalArgumentException("Name occurs twice: " + subcomponent.getName());
- else if (!subcomponent.getArguments().stream().filter(s -> s.getType() != Type.CONSTANT).allMatch(allSignals::contains))
- {
- List<Signal> unknownSignals = new ArrayList<>(subcomponent.getArguments());
- unknownSignals.removeAll(allSignals);
- // we know this list contains at least one element
- throw new IllegalArgumentException("Assigning a signal not in the component: " + unknownSignals.get(0));
- }
+ // do two passes, a signal may be referenced before it is defined
+ for (Statement statement : statements)
+ if (!allSignals.containsAll(statement.getReferencedSignals()))
+ throw new IllegalArgumentException("Referenced an unknown signal: "
+ + statement.getReferencedSignals().stream().filter(s -> !allSignals.contains(s)).findAny().get());