diff --git a/vadl/main/vadl/rtl/analysis/HazardAnalysis.java b/vadl/main/vadl/rtl/analysis/HazardAnalysis.java index df24005d1..898f29b88 100644 --- a/vadl/main/vadl/rtl/analysis/HazardAnalysis.java +++ b/vadl/main/vadl/rtl/analysis/HazardAnalysis.java @@ -40,9 +40,10 @@ public class HazardAnalysis extends DefinitionExtension { * @param effect stage the read takes effect * @param condition stage, in which the condition is known * @param address stage, in which the address is known + * @param forwarding MiA spec enables forwarding to this read */ public record ReadAnalysis(ReadResourceNode node, Stage effect, Stage condition, - @Nullable Stage address) { + @Nullable Stage address, boolean forwarding) { } /** diff --git a/vadl/main/vadl/rtl/passes/ForwardingLogicPass.java b/vadl/main/vadl/rtl/passes/ForwardingLogicPass.java index 6c8898234..2dff41684 100644 --- a/vadl/main/vadl/rtl/passes/ForwardingLogicPass.java +++ b/vadl/main/vadl/rtl/passes/ForwardingLogicPass.java @@ -73,10 +73,9 @@ protected Object execute(PassResults passResults, Specification viam, .orElseGet(() -> new Logic.Forwarding(mia.identifier.append("bypass"))); var behavior = forwarding.behavior(); - // no forwarding to instruction fetch and pc read in fetch + // no forwarding to instruction fetch var ignore = Stream.of( inline.mapping().ipg().fetch() - // inline.mapping().ipg().pcRead() ) .map(inline.inlineMap()::get).toList(); @@ -91,7 +90,16 @@ protected Object execute(PassResults passResults, Specification viam, if (!isa.registerTensors().contains(res) && !isa.ownMemories().contains(res)) { continue; } + var analysis = res.expectExtension(HazardAnalysis.class); + + var ipgRead = inline.inlineMap().inverse().get(read.asReadNode()); + var hazardRd = analysis.reads().stream() + .filter(rd -> rd.node().equals(ipgRead) && rd.forwarding()).findFirst(); + if (hazardRd.isEmpty()) { + continue; // no forwarding to this read + } + var hazardWr = analysis.writes().stream() .filter(wr -> isAfter(stage, wr.effect())).toList(); if (!hazardWr.isEmpty()) { diff --git a/vadl/main/vadl/rtl/passes/HazardAnalysisPass.java b/vadl/main/vadl/rtl/passes/HazardAnalysisPass.java index 6c65834fd..1d42e6d22 100644 --- a/vadl/main/vadl/rtl/passes/HazardAnalysisPass.java +++ b/vadl/main/vadl/rtl/passes/HazardAnalysisPass.java @@ -90,7 +90,8 @@ public Object execute(PassResults passResults, Specification viam) throws IOExce .map(read -> new HazardAnalysis.ReadAnalysis( read, stage(mapping, read), condition(mapping, read), - stage(mapping, read.indices()) + stage(mapping, read.indices()), + forwardToActive(mapping, read.resourceDefinition(), stage(mapping, read)) )) .collect(Collectors.toCollection(LinkedHashSet::new)); var writes = ipg.getNodes(WriteResourceNode.class) @@ -160,7 +161,7 @@ private Stream forward(MiaMapping mapping, // add forward from write stage (always possible) result.add(new HazardAnalysis.ForwardAnalysis(write, analysis.effect(), stage, new ArrayList<>(conditions), address, value, - forwardActive(mapping, write.resourceDefinition(), stage))); + forwardFromActive(mapping, write.resourceDefinition(), stage))); // stop if we passed the stage where address or condition are available var stop = Stream.of(analysis.condition(), analysis.address()).filter(Objects::nonNull) @@ -175,14 +176,27 @@ private Stream forward(MiaMapping mapping, } result.add(new HazardAnalysis.ForwardAnalysis(write, analysis.effect(), stage, new ArrayList<>(conditions), address, value, - forwardActive(mapping, write.resourceDefinition(), stage))); + forwardFromActive(mapping, write.resourceDefinition(), stage))); stage = stage.prev(); } return result.stream(); } - private boolean forwardActive(MiaMapping mapping, Resource resource, Stage stage) { + private boolean forwardToActive(MiaMapping mapping, Resource resource, Stage stage) { + if (mapping.mia().logic().stream().noneMatch(Logic.Forwarding.class::isInstance)) { + return true; // MiA does not define forwarding paths + } + if (Objects.requireNonNull(mapping.mia().isa().pc()).registerTensor().equals(resource)) { + return true; // always forward to PC read (can not be specified) + } + // TODO this does not support multiple forwarding logic elements + return stage.behavior().getNodes(MiaBuiltInCall.class) + .anyMatch(call -> call.builtIn().equals(BuiltInTable.INSTRUCTION_READ_OR_FORWARD) + && call.matchResource(resource)); + } + + private boolean forwardFromActive(MiaMapping mapping, Resource resource, Stage stage) { if (mapping.mia().logic().stream().noneMatch(Logic.Forwarding.class::isInstance)) { return true; // MiA does not define forwarding paths }