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