From 96dd446ab936b4db82d0bd94f90e20442a4d86af Mon Sep 17 00:00:00 2001 From: Fabian Stemmler Date: Mon, 30 Sep 2019 02:32:39 +0200 Subject: [PATCH] ActiveInstructionChangedListener moved to Machine and updated The listener is now only called on the rising edge of the clock cycle. Fixed a stupid bug in innerHighlight, creating Optionals of potential null values with of() --- .../logic/model/am2900/components/Am2900.json | 2 +- .../model/am2900/machine/Am2900Machine.java | 47 +++++++++++++++++++ .../src/net/mograsim/machine/Machine.java | 11 +++++ .../mi/AssignableMicroInstructionMemory.java | 35 +------------- .../machine/mi/MicroInstructionMemory.java | 11 ----- .../mi/StandardMicroInstructionMemory.java | 31 ------------ .../CoreMicroInstructionMemory.java | 1 - .../plugin/editors/SimulationViewEditor.java | 7 ++- ...tiveInstructionPreviewContentProvider.java | 38 +++++++++------ .../plugin/tables/mi/InstructionView.java | 18 ++++--- .../plugin/tables/mi/RowHighlighter.java | 31 ++++-------- .../plugin/util/SingleSWTRequest.java | 29 ++++++++++++ 12 files changed, 139 insertions(+), 122 deletions(-) create mode 100644 plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/util/SingleSWTRequest.java diff --git a/plugins/net.mograsim.logic.model.am2900/components/net/mograsim/logic/model/am2900/components/Am2900.json b/plugins/net.mograsim.logic.model.am2900/components/net/mograsim/logic/model/am2900/components/Am2900.json index b1522942..a83e7ad8 100644 --- a/plugins/net.mograsim.logic.model.am2900/components/net/mograsim/logic/model/am2900/components/Am2900.json +++ b/plugins/net.mograsim.logic.model.am2900/components/net/mograsim/logic/model/am2900/components/Am2900.json @@ -4159,7 +4159,7 @@ "compName": "WireCrossPoint#43", "pinName": "" }, - "name": "unnamedWire#163", + "name": "wire_mpm_address", "path": [ { "x": 205.0, diff --git a/plugins/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java b/plugins/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java index ac1b2373..f705e74e 100644 --- a/plugins/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java +++ b/plugins/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900Machine.java @@ -1,5 +1,8 @@ package net.mograsim.logic.model.am2900.machine; +import java.util.HashSet; +import java.util.Set; + import net.mograsim.logic.core.components.CoreClock; import net.mograsim.logic.core.timeline.Timeline; import net.mograsim.logic.core.types.BitVector; @@ -31,6 +34,9 @@ public class Am2900Machine implements Machine private AssignableMainMemory mainMemory; private AssignableMicroInstructionMemory instMemory; private CoreClock clock; + private long activeInstructionAddress; + + private final Set amicListeners; public Am2900Machine(LogicModelModifiable model, Am2900MachineDefinition am2900MachineDefinition) { @@ -38,6 +44,8 @@ public class Am2900Machine implements Machine this.logicModel = model; this.am2900 = IndirectModelComponentCreator.createComponent(logicModel, "resloader:Am2900Loader:jsonres:net/mograsim/logic/model/am2900/components/Am2900.json", "Am2900"); + this.amicListeners = new HashSet<>(); + CoreModelParameters params = new CoreModelParameters(); params.gateProcessTime = 50; params.wireTravelTime = 10; @@ -48,6 +56,15 @@ public class Am2900Machine implements Machine am2900.setHighLevelState("ram.memory_binding", mainMemory); am2900.setHighLevelState("mpm.memory_binding", instMemory); clock = logicModel.getComponentBySubmodelPath("Am2900.Clock#0", ModelClock.class).getClock(); + clock.registerObserver(c -> + { + if (clock.isOn()) + { + long oldAddress = activeInstructionAddress; + activeInstructionAddress = getCurrentMicroInstructionAddress(); + notifyActiveMicroInstructionChangedListeners(oldAddress, activeInstructionAddress); + } + }); } @Override @@ -115,4 +132,34 @@ public class Am2900Machine implements Machine { return instMemory; } + + @Override + public long getActiveMicroInstructionAddress() + { + return activeInstructionAddress; + } + + private long getCurrentMicroInstructionAddress() + { + // TODO: replace with highlevelstate + BitVector vector = logicModel.getWireBySubmodelPath("Am2900.wire_mpm_address").getWireValues(); + return vector.isBinary() ? vector.getUnsignedValueLong() : -1; + } + + @Override + public void addActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener listener) + { + amicListeners.add(listener); + } + + @Override + public void removeActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener listener) + { + amicListeners.remove(listener); + } + + private void notifyActiveMicroInstructionChangedListeners(long oldAddress, long newAddress) + { + amicListeners.forEach(l -> l.instructionChanged(oldAddress, newAddress)); + } } \ No newline at end of file diff --git a/plugins/net.mograsim.machine/src/net/mograsim/machine/Machine.java b/plugins/net.mograsim.machine/src/net/mograsim/machine/Machine.java index df99984a..8325068d 100644 --- a/plugins/net.mograsim.machine/src/net/mograsim/machine/Machine.java +++ b/plugins/net.mograsim.machine/src/net/mograsim/machine/Machine.java @@ -26,4 +26,15 @@ public interface Machine AssignableMainMemory getMainMemory(); AssignableMicroInstructionMemory getMicroInstructionMemory(); + + void addActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener listener); + + void removeActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener listener); + + long getActiveMicroInstructionAddress(); + + public interface ActiveMicroInstructionChangedListener + { + public void instructionChanged(long oldAddress, long newAddress); + } } \ No newline at end of file diff --git a/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/AssignableMicroInstructionMemory.java b/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/AssignableMicroInstructionMemory.java index a366ae0a..623d632d 100644 --- a/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/AssignableMicroInstructionMemory.java +++ b/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/AssignableMicroInstructionMemory.java @@ -4,14 +4,12 @@ import java.util.HashSet; import java.util.Set; import net.mograsim.machine.Memory.MemoryCellModifiedListener; -import net.mograsim.machine.mi.MicroInstructionMemory.ActiveMicroInstructionChangedListener; -public class AssignableMicroInstructionMemory - implements MicroInstructionMemory, MemoryCellModifiedListener, ActiveMicroInstructionChangedListener +public class AssignableMicroInstructionMemory implements MicroInstructionMemory, MemoryCellModifiedListener { private Set observers = new HashSet<>(); - private Set activeInstructionListeners = new HashSet<>(); + private Set reassignmentListeners = new HashSet<>(); private MicroInstructionMemory real = null; @@ -54,28 +52,11 @@ public class AssignableMicroInstructionMemory observers.remove(ob); } - @Override - public void registerActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob) - { - activeInstructionListeners.add(ob); - } - - @Override - public void deregisterActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob) - { - activeInstructionListeners.remove(ob); - } - private void notifyMemoryChanged(long address) { observers.forEach(o -> o.update(address)); } - private void notifyActiveInstructionChanged(long address) - { - activeInstructionListeners.forEach(o -> o.activeMicroInstructionChanged(address)); - } - @Override public MicroInstructionMemoryDefinition getDefinition() { @@ -88,18 +69,6 @@ public class AssignableMicroInstructionMemory notifyMemoryChanged(address); } - @Override - public void setActiveInstruction(long address) - { - real.setActiveInstruction(address); - } - - @Override - public void activeMicroInstructionChanged(long address) - { - notifyActiveInstructionChanged(address); - } - public void registerMemoryReassignedListener(MIMemoryReassignedListener listener) { reassignmentListeners.add(listener); diff --git a/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/MicroInstructionMemory.java b/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/MicroInstructionMemory.java index abfed465..6409f78d 100644 --- a/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/MicroInstructionMemory.java +++ b/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/MicroInstructionMemory.java @@ -6,15 +6,4 @@ public interface MicroInstructionMemory extends Memory { @Override public MicroInstructionMemoryDefinition getDefinition(); - - public void registerActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob); - - public void deregisterActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob); - - public void setActiveInstruction(long address); - - public static interface ActiveMicroInstructionChangedListener - { - public void activeMicroInstructionChanged(long address); - } } diff --git a/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroInstructionMemory.java b/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroInstructionMemory.java index 94905a5b..c8866fdd 100644 --- a/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroInstructionMemory.java +++ b/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroInstructionMemory.java @@ -1,7 +1,6 @@ package net.mograsim.machine.mi; import java.util.HashSet; -import java.util.Set; import net.mograsim.machine.standard.memory.MemoryException; @@ -10,8 +9,6 @@ public class StandardMicroInstructionMemory implements MicroInstructionMemory private MicroInstruction[] data; private MicroInstructionMemoryDefinition definition; private HashSet observers = new HashSet<>(); - private Set activeInstructionListeners = new HashSet<>(); - private long activeInstruction = -1; public StandardMicroInstructionMemory(MicroInstructionMemoryDefinition definition) { @@ -55,42 +52,14 @@ public class StandardMicroInstructionMemory implements MicroInstructionMemory observers.remove(ob); } - @Override - public void registerActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob) - { - activeInstructionListeners.add(ob); - } - - @Override - public void deregisterActiveMicroInstructionChangedListener(ActiveMicroInstructionChangedListener ob) - { - activeInstructionListeners.remove(ob); - } - private void notifyMemoryChanged(long address) { observers.forEach(ob -> ob.update(address)); } - private void notifyActiveInstructionChanged(long address) - { - activeInstructionListeners.forEach(o -> o.activeMicroInstructionChanged(address)); - } - @Override public MicroInstructionMemoryDefinition getDefinition() { return definition; } - - @Override - public void setActiveInstruction(long address) - { - if (address != activeInstruction) - { - activeInstruction = address; - notifyActiveInstructionChanged(address); - } - } - } diff --git a/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/components/CoreMicroInstructionMemory.java b/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/components/CoreMicroInstructionMemory.java index b01802c0..96ac46c7 100644 --- a/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/components/CoreMicroInstructionMemory.java +++ b/plugins/net.mograsim.machine/src/net/mograsim/machine/mi/components/CoreMicroInstructionMemory.java @@ -77,7 +77,6 @@ public class CoreMicroInstructionMemory extends BasicCoreComponent return e -> data.feedSignals(Bit.U.toVector(data.width()));// TODO don't always feed U, but decide to feed X or U. long addressed = address.getValues().getUnsignedValueLong(); BitVector storedData = memory.getCell(addressed).toBitVector(); - memory.setActiveInstruction(addressed); return e -> data.feedSignals(storedData); } } \ No newline at end of file diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/editors/SimulationViewEditor.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/editors/SimulationViewEditor.java index cb8e688c..651852ed 100644 --- a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/editors/SimulationViewEditor.java +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/editors/SimulationViewEditor.java @@ -159,6 +159,9 @@ public class SimulationViewEditor extends EditorPart canvasParent.layout(); + // update preview + ((ActiveInstructionPreviewContentProvider) instPreview.getTableViewer().getContentProvider()).setMachine(machine); + // initialize executer exec = new LogicExecuter(machine.getTimeline()); updateSpeedFactorFromInput(simSpeedInput.getValue()); @@ -300,7 +303,9 @@ public class SimulationViewEditor extends EditorPart { instPreview = new InstructionTable(parent, new DisplaySettings(), getSite().getWorkbenchWindow().getWorkbench().getThemeManager()); instPreview.getTableViewer().getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - instPreview.setContentProvider(new ActiveInstructionPreviewContentProvider(instPreview.getTableViewer())); + ActiveInstructionPreviewContentProvider cProv; + instPreview.setContentProvider(cProv = new ActiveInstructionPreviewContentProvider(instPreview.getTableViewer())); + cProv.setMachine(machine); } private static void setPauseText(Button pauseButton, boolean hovered) diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/ActiveInstructionPreviewContentProvider.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/ActiveInstructionPreviewContentProvider.java index 604c2859..d3a14ec7 100644 --- a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/ActiveInstructionPreviewContentProvider.java +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/ActiveInstructionPreviewContentProvider.java @@ -3,14 +3,24 @@ package net.mograsim.plugin.tables.mi; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; +import net.mograsim.machine.Machine; +import net.mograsim.machine.Machine.ActiveMicroInstructionChangedListener; import net.mograsim.machine.mi.MicroInstructionMemory; -import net.mograsim.machine.mi.MicroInstructionMemory.ActiveMicroInstructionChangedListener; +import net.mograsim.plugin.util.SingleSWTRequest; -public class ActiveInstructionPreviewContentProvider implements InstructionTableContentProvider, ActiveMicroInstructionChangedListener +public class ActiveInstructionPreviewContentProvider implements InstructionTableContentProvider { private TableViewer viewer; private MicroInstructionMemory memory; private InstructionTableRow activeRow; + private Machine machine; + private SingleSWTRequest requester = new SingleSWTRequest(); + + private ActiveMicroInstructionChangedListener instChanged = (oldAddress, newAddress) -> + { + activeRow = new InstructionTableRow(Long.max(0, newAddress), memory); + requester.request(() -> updateElement(0)); + }; public ActiveInstructionPreviewContentProvider(TableViewer viewer) { @@ -18,13 +28,6 @@ public class ActiveInstructionPreviewContentProvider implements InstructionTable viewer.setItemCount(1); } - @Override - public void activeMicroInstructionChanged(long address) - { - this.activeRow = new InstructionTableRow(address, memory); - viewer.refresh(); - } - @Override public void update(long address) { @@ -34,14 +37,19 @@ public class ActiveInstructionPreviewContentProvider implements InstructionTable @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - if (oldInput != null) - ((MicroInstructionMemory) oldInput).deregisterActiveMicroInstructionChangedListener(this); - memory = (MicroInstructionMemory) newInput; - if (memory != null) + } + + public void setMachine(Machine newMachine) + { + if (machine != null) + machine.removeActiveMicroInstructionChangedListener(instChanged); + + machine = newMachine; + if (machine != null) { - activeMicroInstructionChanged(0); - memory.registerActiveMicroInstructionChangedListener(this); + instChanged.instructionChanged(-1, 0); + machine.addActiveMicroInstructionChangedListener(instChanged); } } diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/InstructionView.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/InstructionView.java index e354c8f6..93a76327 100644 --- a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/InstructionView.java +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/InstructionView.java @@ -17,10 +17,10 @@ import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.EditorPart; +import net.mograsim.machine.Machine.ActiveMicroInstructionChangedListener; import net.mograsim.machine.Memory.MemoryCellModifiedListener; import net.mograsim.machine.mi.AssignableMicroInstructionMemory.MIMemoryReassignedListener; import net.mograsim.machine.mi.MicroInstructionMemory; -import net.mograsim.machine.mi.MicroInstructionMemory.ActiveMicroInstructionChangedListener; import net.mograsim.machine.mi.MicroInstructionMemoryParseException; import net.mograsim.machine.mi.MicroInstructionMemoryParser; import net.mograsim.plugin.nature.MachineContext; @@ -44,8 +44,10 @@ public class InstructionView extends EditorPart table.refresh(); }; - private ActiveMicroInstructionChangedListener activeInstructionChangedListener = address -> highlight( - (int) (address - memory.getDefinition().getMinimalAddress())); + private ActiveMicroInstructionChangedListener instChangeListener = (oldAddress, newAddress) -> + { + highlight((int) (newAddress - memory.getDefinition().getMinimalAddress())); + }; private MIMemoryReassignedListener reassignedListener = newAssignee -> { @@ -99,6 +101,7 @@ public class InstructionView extends EditorPart m.getMicroInstructionMemory().registerMemoryReassignedListener(reassignedListener); context.addActiveMachineListener(activeMachineListener); m.getMicroInstructionMemory().bind(memory); + m.addActiveMicroInstructionChangedListener(instChangeListener); })); } @@ -107,13 +110,11 @@ public class InstructionView extends EditorPart if (this.memory != null) { this.memory.deregisterCellModifiedListener(cellModifiedListener); - this.memory.deregisterActiveMicroInstructionChangedListener(activeInstructionChangedListener); } this.memory = memory; if (memory != null) { this.memory.registerCellModifiedListener(cellModifiedListener); - this.memory.registerActiveMicroInstructionChangedListener(activeInstructionChangedListener); } if (table != null) table.bindMicroInstructionMemory(memory); @@ -229,9 +230,12 @@ public class InstructionView extends EditorPart @Override public void dispose() { - memory.deregisterActiveMicroInstructionChangedListener(activeInstructionChangedListener); memory.deregisterCellModifiedListener(cellModifiedListener); - context.getActiveMachine().ifPresent(m -> m.getMicroInstructionMemory().deregisterMemoryReassignedListener(reassignedListener)); + context.getActiveMachine().ifPresent(m -> + { + m.removeActiveMicroInstructionChangedListener(instChangeListener); + m.getMicroInstructionMemory().deregisterMemoryReassignedListener(reassignedListener); + }); context.removeActiveMachineListener(activeMachineListener); super.dispose(); } diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/RowHighlighter.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/RowHighlighter.java index 17b2cd22..03cb37cc 100644 --- a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/RowHighlighter.java +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/mi/RowHighlighter.java @@ -1,19 +1,18 @@ package net.mograsim.plugin.tables.mi; import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; -import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Table; import net.mograsim.plugin.tables.LazyTableViewer; +import net.mograsim.plugin.util.SingleSWTRequest; public class RowHighlighter { - private int highlighted = -1, toHighlight; + private int highlighted = -1; private LazyTableViewer viewer; - private AtomicBoolean waiting = new AtomicBoolean(); private ColorProvider cProv; + private SingleSWTRequest requester = new SingleSWTRequest(); public RowHighlighter(LazyTableViewer viewer, ColorProvider cProv) { @@ -23,23 +22,11 @@ public class RowHighlighter public void highlight(int row) { - synchronized (waiting) + requester.request(() -> { - toHighlight = row; - if (!waiting.get()) - { - waiting.set(true); - Display.getDefault().asyncExec(() -> - { - synchronized (waiting) - { - waiting.set(false); - if (!viewer.getTable().isDisposed()) - innerHighlight(toHighlight); - } - }); - } - } + if (!viewer.getTable().isDisposed()) + innerHighlight(row); + }); } private void innerHighlight(int row) @@ -50,10 +37,10 @@ public class RowHighlighter { table.showItem(table.getItem(Math.min(table.getItemCount(), row + 2))); table.showItem(table.getItem(row)); - Optional.of(table.getItem(row).getData()).ifPresent(d -> viewer.update(d, null)); + Optional.ofNullable(table.getItem(row).getData()).ifPresent(d -> viewer.update(d, null)); } if (highlighted != -1) - Optional.of(table.getItem(highlighted).getData()).ifPresent(d -> viewer.update(d, null)); + Optional.ofNullable(table.getItem(highlighted).getData()).ifPresent(d -> viewer.update(d, null)); highlighted = row; } } diff --git a/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/util/SingleSWTRequest.java b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/util/SingleSWTRequest.java new file mode 100644 index 00000000..fa4d5583 --- /dev/null +++ b/plugins/net.mograsim.plugin.core/src/net/mograsim/plugin/util/SingleSWTRequest.java @@ -0,0 +1,29 @@ +package net.mograsim.plugin.util; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.eclipse.swt.widgets.Display; + +public class SingleSWTRequest +{ + private AtomicBoolean waiting = new AtomicBoolean(); + + public void request(Runnable request) + { + synchronized (waiting) + { + if (!waiting.get()) + { + waiting.set(true); + Display.getDefault().asyncExec(() -> + { + synchronized (waiting) + { + waiting.set(false); + request.run(); + } + }); + } + } + } +} -- 2.17.1