1 /* 2 * Copyright (c) 2020 Helmut Neemann. 3 * Use of this source code is governed by the GPL v3 license 4 * that can be found in the LICENSE file. 5 */ 6 package de.neemann.digital.testing.parser; 7 8 import de.neemann.digital.core.Model; 9 import de.neemann.digital.core.Node; 10 import de.neemann.digital.core.Signal; 11 import de.neemann.digital.core.memory.DataField; 12 import de.neemann.digital.core.memory.ProgramMemory; 13 import de.neemann.digital.core.memory.RAMInterface; 14 import de.neemann.digital.lang.Lang; 15 import de.neemann.digital.testing.TestingDataException; 16 17 import java.util.ArrayList; 18 import java.util.List; 19 20 /** 21 * Is prepared by the test data parser and then used to initialize the 22 * model for the test. 23 */ 24 public class ModelInitializer { 25 private final ArrayList<ModelInit> inits; 26 ModelInitializer()27 ModelInitializer() { 28 this.inits = new ArrayList<>(); 29 } 30 initSignal(String name, long value)31 void initSignal(String name, long value) { 32 inits.add(new InitSignal(name, value)); 33 } 34 initProgramMemory(DataField memory)35 void initProgramMemory(DataField memory) { 36 inits.add(new InitProgramMemory(memory)); 37 } 38 initMemory(String ramName, int addr, long value)39 void initMemory(String ramName, int addr, long value) { 40 inits.add(new InitMemory(ramName, addr, value)); 41 } 42 43 /** 44 * Aplies the init steps to the given model 45 * 46 * @param model the model to initialize 47 * @throws TestingDataException TestingDataException 48 */ init(Model model)49 public void init(Model model) throws TestingDataException { 50 for (ModelInit mi : inits) 51 mi.init(model); 52 } 53 54 private interface ModelInit { init(Model model)55 void init(Model model) throws TestingDataException; 56 } 57 58 private static final class InitSignal implements ModelInit { 59 private final String name; 60 private final long value; 61 InitSignal(String name, long value)62 private InitSignal(String name, long value) { 63 this.name = name; 64 this.value = value; 65 } 66 67 @Override init(Model model)68 public void init(Model model) throws TestingDataException { 69 Signal.Setter s = model.getSignalSetter(name); 70 if (s == null) 71 throw new TestingDataException(Lang.get("err_testSignal_N_notFound", name)); 72 s.set(value, 0); 73 } 74 } 75 76 private static final class InitProgramMemory implements ModelInit { 77 private final DataField dataField; 78 InitProgramMemory(DataField dataField)79 private InitProgramMemory(DataField dataField) { 80 this.dataField = dataField; 81 } 82 83 @Override init(Model model)84 public void init(Model model) throws TestingDataException { 85 List<Node> nodes = model.findNode(n -> n instanceof ProgramMemory && ((ProgramMemory) n).isProgramMemory()); 86 switch (nodes.size()) { 87 case 0: 88 throw new TestingDataException(Lang.get("err_noRomFound")); 89 case 1: 90 ((ProgramMemory) nodes.get(0)).setProgramMemory(dataField); 91 break; 92 default: 93 throw new TestingDataException(Lang.get("err_multipleRomsFound")); 94 } 95 } 96 } 97 98 private static final class InitMemory implements ModelInit { 99 private final String memoryName; 100 private final int addr; 101 private final long value; 102 InitMemory(String memoryName, int addr, long value)103 private InitMemory(String memoryName, int addr, long value) { 104 this.memoryName = memoryName; 105 this.addr = addr; 106 this.value = value; 107 } 108 109 @Override init(Model model)110 public void init(Model model) throws TestingDataException { 111 List<Node> nodes = model.findNode(n -> n instanceof RAMInterface && ((RAMInterface) n).getLabel().equals(memoryName)); 112 switch (nodes.size()) { 113 case 0: 114 throw new TestingDataException(Lang.get("err_noMemoryFound", memoryName)); 115 case 1: 116 ((RAMInterface) nodes.get(0)).getMemory().setData(addr, value); 117 break; 118 default: 119 throw new TestingDataException(Lang.get("err_multipleMemoriesFound", memoryName)); 120 } 121 } 122 } 123 } 124