Skip to content

Commit 9ff0970

Browse files
committed
decoder: RTL decoder improvements
- improve structure of the hdl decision tree by moving default assignments to the top - for now use big-endian byte order to be compatible with the existing RTL description - Always decode/match all ISA instructions, even if no output signal depends on them (as we don't want to fall back to 'invalid' in this case) - Fix/run the test suite (locally) with all 3 decoder versions and the rv43im spec. - Use wildcards in the rtl-table output patterns
1 parent 73a7cc7 commit 9ff0970

File tree

5 files changed

+50
-62
lines changed

5 files changed

+50
-62
lines changed

vadl/main/resources/templates/rtl/CoreTest.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class CoreTest extends AnyFunSpec with ChiselSim {
150150
if (value.testBit(0)) {
151151
val result = value >> 1
152152
if (result == 0) {
153-
println("RVTEST_PASS")
153+
println(f"RVTEST_PASS: ${file.getName}")
154154
passed += file.getName
155155
} else {
156156
println(f"RVTEST_FAIL $result")
@@ -186,6 +186,9 @@ class CoreTest extends AnyFunSpec with ChiselSim {
186186
val result = f"passed ${passed.mkString(" ")}\nfailed ${failed.mkString(" ")}\ntimeout ${timeout.mkString(" ")}\n"
187187
if (failed.nonEmpty || timeout.nonEmpty) {
188188
fail(result)
189+
} else {
190+
println(f"All Passed!")
191+
println(f"Tests run: ${passed.mkString(" ")}")
189192
}
190193
}
191194
}

vadl/main/vadl/rtl/template/HdlBehavior.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,13 @@ String handle(RtlDecodeTreeNode decodeTreeNode) {
328328
cacheExprOrSig.put(usage, signal.simpleName());
329329
}
330330

331+
final var isa = module.context().viam().isa().orElse(null);
332+
ViamError.ensureNonNull(isa, "The ISA must not be null.");
333+
334+
// Include ISA instructions without signals so they're not decoded as 'invalid' insns.
335+
isa.ownInstructions()
336+
.forEach(i -> decisionMap.computeIfAbsent(i, x -> new HashMap<>()));
337+
331338
ViamError.ensureNonNull(decodeTreeNode.instructionWord(),
332339
"The instruction word of the RtlDecodeTreeNode must not be null.");
333340

vadl/main/vadl/vdt/passes/VdtInputPreparationPass.java

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
import java.io.IOException;
2424
import java.nio.ByteOrder;
2525
import java.util.ArrayList;
26-
import java.util.Collection;
2726
import java.util.HashSet;
28-
import java.util.LinkedHashSet;
2927
import java.util.List;
3028
import java.util.Set;
3129
import java.util.function.Predicate;
@@ -35,7 +33,6 @@
3533
import vadl.pass.Pass;
3634
import vadl.pass.PassName;
3735
import vadl.pass.PassResults;
38-
import vadl.rtl.ipg.nodes.RtlDecodeTreeNode;
3936
import vadl.rtl.passes.InstructionProgressGraphExtension;
4037
import vadl.types.BuiltInTable;
4138
import vadl.vdt.impl.irregular.model.DecodeEntry;
@@ -91,21 +88,17 @@ public Object execute(PassResults passResults, Specification viam) throws IOExce
9188
return null;
9289
}
9390

94-
final Collection<Instruction> relevantInstructions;
91+
// TODO: get the byte order from the VADL specification -> Implement memory annotations
92+
final ByteOrder bo;
9593
if (isa.hasExtension(InstructionProgressGraphExtension.class)) {
96-
// For RTL lowering, we might only want to consider a subset of instructions for the VDT.
97-
final var ipg = isa.expectExtension(InstructionProgressGraphExtension.class).ipg();
98-
relevantInstructions = ipg.getNodes(RtlDecodeTreeNode.class).findAny()
99-
.map(d -> ipg.getContext(d).instructions())
100-
.orElse(new LinkedHashSet<>(isa.ownInstructions()));
94+
// For now, the HDL assumes big-endian representation of the instruction word
95+
bo = ByteOrder.BIG_ENDIAN;
10196
} else {
102-
relevantInstructions = isa.ownInstructions();
97+
bo = ByteOrder.LITTLE_ENDIAN;
10398
}
10499

105-
// TODO: get the byte order from the VADL specification -> Implement memory annotations
106-
final ByteOrder bo = ByteOrder.LITTLE_ENDIAN;
107-
108-
return relevantInstructions.stream()
100+
return isa.ownInstructions()
101+
.stream()
109102
.map(i -> {
110103

111104
final var pattern = toFixedBitPattern(i, bo);

vadl/main/vadl/vdt/target/rtl/RtlTableDecoderGenerator.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ public String generate() {
8888
for (Map.Entry<Instruction, Map<Signal, ConstantNode>> decision : decisionMap.entrySet()) {
8989

9090
var insn = decision.getKey();
91-
var pattern = toFixedBitPattern(insn, ByteOrder.LITTLE_ENDIAN);
91+
92+
// TODO: get the byte order from the VADL specification -> Implement memory annotations
93+
var pattern = toFixedBitPattern(insn, ByteOrder.BIG_ENDIAN);
9294

9395
appendable
9496
.append("BitPat(\"").append(toChiselPattern(pattern, true)).append("\")")
@@ -102,6 +104,8 @@ public String generate() {
102104
var value = decision.getValue().get(signal);
103105
if (value != null) {
104106
appendable.append(value.constant().asVal().asString("", 2, true));
107+
} else if (isInvalid(signal)) {
108+
appendable.append("0");
105109
} else {
106110
appendable.append(getDefaultValue(signal));
107111
}
@@ -173,6 +177,6 @@ private static CharSequence getDefaultValue(Signal signal) {
173177
throw new ViamError("Signal type not supported: %s", signal.type());
174178
}
175179

176-
return "0".repeat(signal.type().asDataType().bitWidth());
180+
return "?".repeat(signal.type().asDataType().bitWidth());
177181
}
178182
}

vadl/main/vadl/vdt/target/rtl/RtlVdtDecoderGenerator.java

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ public String generate(Node tree) {
8282
// The template engine only indents the first line, so to format everything nicely, add an extra
8383
// indent level, and remove the initial indent at the end.
8484
appendable.indent();
85+
86+
// Initialize signals with default values
87+
for (Signal signal : signals) {
88+
89+
appendable
90+
.append(signal.simpleName())
91+
.append(" := ")
92+
.appendLn(getDefaultValue(signal));
93+
}
94+
95+
appendable.newLine();
96+
8597
tree.accept(this);
8698
appendable.unindent();
8799
return appendable.toString().stripLeading();
@@ -131,18 +143,9 @@ public Void handle(InnerNodeImpl node) {
131143

132144
appendable.appendLn("// Invalid");
133145

134-
for (Signal signal : signals) {
135-
136-
appendable
137-
.append(signal.simpleName())
138-
.append(" := ");
139-
140-
if (isInvalid(signal)) {
141-
appendable.appendLn("true.B");
142-
} else {
143-
appendable.appendLn(getDefaultValue(signal));
144-
}
145-
}
146+
appendable
147+
.append(invalidInsn.simpleName())
148+
.appendLn(" := true.B");
146149

147150
}
148151

@@ -189,18 +192,9 @@ public Void handle(MultiDecisionNode node) {
189192
.indent()
190193
.appendLn("// Invalid");
191194

192-
for (Signal signal : signals) {
193-
194-
appendable
195-
.append(signal.simpleName())
196-
.append(" := ");
197-
198-
if (isInvalid(signal)) {
199-
appendable.appendLn("true.B");
200-
} else {
201-
appendable.appendLn(getDefaultValue(signal));
202-
}
203-
}
195+
appendable
196+
.append(invalidInsn.simpleName())
197+
.appendLn(" := true.B");
204198

205199
appendable.unindent()
206200
.appendLn("}");
@@ -241,17 +235,10 @@ public Void handle(SingleDecisionNode node) {
241235
node.getOtherChild().accept(this);
242236
} else {
243237
// If we don't have an 'other' option, fall back to 'invalid'
244-
appendable.appendLn("// Invalid");
245-
for (Signal signal : signals) {
246-
appendable
247-
.append(signal.simpleName())
248-
.append(" := ");
249-
if (isInvalid(signal)) {
250-
appendable.appendLn("true.B");
251-
} else {
252-
appendable.appendLn(getDefaultValue(signal));
253-
}
254-
}
238+
appendable
239+
.appendLn("// Invalid")
240+
.append(invalidInsn.simpleName())
241+
.appendLn(" := true.B");
255242
}
256243

257244
appendable.unindent()
@@ -292,27 +279,21 @@ public Void visit(LeafNode node) {
292279

293280
for (Signal signal : signals) {
294281

295-
appendable
296-
.append(signal.simpleName())
297-
.append(" := ");
298-
299282
var value = decision == null ? null : decision.get(signal);
300283

301284
if (value == null) {
302-
appendable.appendLn(getDefaultValue(signal));
303285
continue;
304286
}
305287

306-
appendable.appendLn(toChiselValue(value.constant()));
288+
appendable
289+
.append(signal.simpleName())
290+
.append(" := ")
291+
.appendLn(toChiselValue(value.constant()));
307292
}
308293

309294
return null;
310295
}
311296

312-
private boolean isInvalid(Signal signal) {
313-
return signal.identifier.equals(invalidInsn.identifier);
314-
}
315-
316297
private static CharSequence toChiselValue(Constant constant) {
317298

318299
if (constant.type().isTrivialCastTo(Type.bool())) {

0 commit comments

Comments
 (0)