Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion vadl/main/resources/templates/rtl/CoreTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class CoreTest extends AnyFunSpec with ChiselSim {
if (value.testBit(0)) {
val result = value >> 1
if (result == 0) {
println("RVTEST_PASS")
println(f"RVTEST_PASS: ${file.getName}")
passed += file.getName
} else {
println(f"RVTEST_FAIL $result")
Expand Down Expand Up @@ -186,6 +186,9 @@ class CoreTest extends AnyFunSpec with ChiselSim {
val result = f"passed ${passed.mkString(" ")}\nfailed ${failed.mkString(" ")}\ntimeout ${timeout.mkString(" ")}\n"
if (failed.nonEmpty || timeout.nonEmpty) {
fail(result)
} else {
println(f"All Passed!")
println(f"Tests run: ${passed.mkString(" ")}")
}
}
}
11 changes: 6 additions & 5 deletions vadl/main/resources/templates/rtl/Module.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

[/]import chisel3._
import chisel3.util._
import chisel3.util.experimental.decode._
import VADL._

class [(${name})] extends Module {
Expand Down Expand Up @@ -31,11 +32,11 @@ class [(${name})] extends Module {

[# th:each="con : ${connections}" ][#
th:if="${con.isConditional}" ]when (([(${con.condition})]).asBool) {
[/][(${con.output})][# th:if="${con.isStatement}" ][(${con.statement})][/][#
th:if="${!con.isStatement}" ][#
th:if="${con.biDir}" ] :<>= [/][#
th:if="${!con.biDir}" ] := [/][(${con.input})][/][#
th:if="${con.isConditional}" ]
[/][(${con.output})][# th:if="${con.isStatement}" ][(${con.statement})][/][#
th:if="${!con.isStatement}" ][#
th:if="${con.biDir}" ] :<>= [/][#
th:if="${!con.biDir}" ] := [/][(${con.input})][/][#
th:if="${con.isConditional}" ]
}[/]
[/]
[# th:if="${syncReset}"]}[/]
Expand Down
5 changes: 3 additions & 2 deletions vadl/main/vadl/configuration/DecoderOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
public class DecoderOptions {

/**
* The possible generator strategies to choose from.
* The possible VADL decode tree generator strategies to choose from.
*/
public enum Generator {
REGULAR("Regular decoder generator", "regular"),
IRREGULAR("Irregular decoder generator, default", "irregular");
IRREGULAR("Irregular decoder generator, default", "irregular"),
RTL_TABLE("RTL table based decoder", "rtl-table"),;

private final String selector;
private final String desc;
Expand Down
6 changes: 6 additions & 0 deletions vadl/main/vadl/pass/PassOrders.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package vadl.pass;

import static vadl.configuration.DecoderOptions.Generator.RTL_TABLE;
import static vadl.iss.template.IssDefaultRenderingPass.issDefault;

import com.google.common.collect.Streams;
Expand Down Expand Up @@ -643,6 +644,11 @@ public static PassOrder rtl(RtlConfiguration config) throws IOException {
"mia",
"MiA after mapping and inlining instruction behavior");

if (config.getDecoderOptions().getGenerator() != RTL_TABLE) {
// Prepares and constructs the VDT, which is not used by the rtl-table strategy
addDecodePasses(order, config);
}

if (!config.isDryRun()) {
addRtlEmitPasses(order, config);
}
Expand Down
2 changes: 1 addition & 1 deletion vadl/main/vadl/rtl/ipg/InstructionProgressGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ public InstructionProgressGraph copy(String name) {
SubgraphUtils.MissingSupplier failOnMissing = (from, to, copyFrom) -> {
throw Diagnostic.error("Missing node during IPG copy", to).build();
};
var copyMap = SubgraphUtils.copy(newIpg, getNodes().collect(Collectors.toSet()),
var copyMap = SubgraphUtils.copy(newIpg, new LinkedHashSet<>(getNodes().toList()),
failOnMissing, failOnMissing);

// update new ipg fields
Expand Down
111 changes: 111 additions & 0 deletions vadl/main/vadl/rtl/ipg/nodes/RtlDecodeTreeNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// SPDX-FileCopyrightText : © 2025 TU Wien <vadl@tuwien.ac.at>
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package vadl.rtl.ipg.nodes;

import java.util.List;
import javax.annotation.Nullable;
import vadl.javaannotations.viam.Input;
import vadl.rtl.passes.InstructionProgressGraphLowerPass;
import vadl.types.Type;
import vadl.viam.graph.GraphNodeVisitor;
import vadl.viam.graph.GraphVisitor;
import vadl.viam.graph.Node;
import vadl.viam.graph.dependency.ExpressionNode;

/**
* Node that represents the instruction decoder in the RTL behaviour.
*/
public class RtlDecodeTreeNode extends ExpressionNode {

@Input
@Nullable
protected ExpressionNode instructionWord;

/**
* Initial constructor of RtlDecodeTreeNode. Initially the type is 'void' but will be extended
* by appending result 'signals' to it.
*/
public RtlDecodeTreeNode() {
super(Type.void_()); // Type will be extended once signals are added
}

private RtlDecodeTreeNode(Type type, @Nullable ExpressionNode instructionWord) {
super(type);
this.instructionWord = instructionWord;
}

/**
* Add a new control signal decided by this decode tree node.
*
* @param signal The signal to add (either an is-instruction or one-hot node)
*/
public void addSignal(ExpressionNode signal) {
final int existingWidth = type().isDataType() ? type().asDataType().bitWidth() : 0;
final int newWidth = signal.type().asDataType().bitWidth();
setType(Type.bits(existingWidth + newWidth));
}

/**
* Instruction word input, set by {@link InstructionProgressGraphLowerPass}.
*
* @return instruction word input
*/
@Nullable
public ExpressionNode instructionWord() {
return instructionWord;
}

public void setInstructionWord(@Nullable ExpressionNode instructionWord) {
updateUsageOf(this.instructionWord, instructionWord);
this.instructionWord = instructionWord;
}

@Override
protected void collectInputs(List<Node> collection) {
super.collectInputs(collection);
if (this.instructionWord != null) {
collection.add(instructionWord);
}
}

@Override
protected void applyOnInputsUnsafe(GraphVisitor.Applier<Node> visitor) {
super.applyOnInputsUnsafe(visitor);
instructionWord = visitor.applyNullable(this, instructionWord, ExpressionNode.class);
}

@Override
public ExpressionNode copy() {
return new RtlDecodeTreeNode(type(), instructionWord != null ? instructionWord.copy() : null);
}

@Override
public Node shallowCopy() {
return new RtlDecodeTreeNode(type(), instructionWord);
}

@Override
public <T extends GraphNodeVisitor> void accept(T visitor) {
visitor.visit(this);
}

@Override
public String toString() {
final int width = type().isDataType() ? type().asDataType().bitWidth() : 0;
return "(" + id + ") DecodeTree<" + width + ">";
}
}
85 changes: 85 additions & 0 deletions vadl/main/vadl/rtl/ipg/nodes/RtlInvalidInstructionNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-FileCopyrightText : © 2025 TU Wien <vadl@tuwien.ac.at>
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package vadl.rtl.ipg.nodes;

import java.util.List;
import vadl.javaannotations.viam.Input;
import vadl.types.Type;
import vadl.viam.graph.GraphNodeVisitor;
import vadl.viam.graph.GraphVisitor;
import vadl.viam.graph.Node;
import vadl.viam.graph.dependency.ExpressionNode;

/**
* Node that represents matching none of the instructions in the instruction set.
*/
public class RtlInvalidInstructionNode extends ExpressionNode {

@Input
protected RtlDecodeTreeNode decodeTree;

/**
* Create a new is-invalid-instruction node.
*
* @param decodeTree decode tree input
*/
public RtlInvalidInstructionNode(RtlDecodeTreeNode decodeTree) {
super(Type.bool());
this.decodeTree = decodeTree;
}

/**
* Decode tree deciding this node.
*
* @return the decoder deciding this node
*/
public RtlDecodeTreeNode decodeTree() {
return decodeTree;
}

@Override
protected void applyOnInputsUnsafe(GraphVisitor.Applier<Node> visitor) {
super.applyOnInputsUnsafe(visitor);
decodeTree = visitor.apply(this, decodeTree, RtlDecodeTreeNode.class);
}

@Override
protected void collectInputs(List<Node> collection) {
super.collectInputs(collection);
collection.add(decodeTree);
}

@Override
public ExpressionNode copy() {
return new RtlInvalidInstructionNode(decodeTree.copy(RtlDecodeTreeNode.class));
}

@Override
public Node shallowCopy() {
return new RtlInvalidInstructionNode(decodeTree);
}

@Override
public <T extends GraphNodeVisitor> void accept(T visitor) {
visitor.visit(this);
}

@Override
public String toString() {
return "(" + id + ") InvalidInstruction";
}
}
44 changes: 16 additions & 28 deletions vadl/main/vadl/rtl/ipg/nodes/RtlIsInstructionNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@
package vadl.rtl.ipg.nodes;

import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import vadl.javaannotations.viam.DataValue;
import vadl.javaannotations.viam.Input;
import vadl.types.Type;
Expand All @@ -36,30 +34,29 @@
*
* <p>Used to lower read/write conditions and select-by-instruction nodes. Conditions are extended
* to include the output of an is-instruction node, select-by-instruction nodes are replaced with
* selects that have is-instruction nodes as condition inputs. This moves the information present
* in the IPG (i.e., which nodes are used for which instruction) to graph nodes before inlining the
* IPG into the stages.
* selects that have one-hot nodes as condition inputs (decided by the decode-tree node). This moves
* the information present in the IPG (i.e., which nodes are used for which instruction) to graph
* nodes before inlining the IPG into the stages.
*/
public class RtlIsInstructionNode extends ExpressionNode {

@DataValue
private final Set<Instruction> instructions;

@Input
@Nullable
protected ExpressionNode instruction;
protected RtlDecodeTreeNode decodeTree;

/**
* Create a new is-instruction node for a collection of instructions it should match.
*
* @param instructions collection of instructions
* @param instruction instruction word input
* @param decodeTree decode tree input
*/
public RtlIsInstructionNode(Collection<Instruction> instructions,
@Nullable ExpressionNode instruction) {
RtlDecodeTreeNode decodeTree) {
super(Type.bool());
this.instructions = new LinkedHashSet<>(instructions);
this.instruction = instruction;
this.decodeTree = decodeTree;
}

/**
Expand All @@ -72,32 +69,24 @@ public Set<Instruction> instructions() {
}

/**
* Instruction word input, set by {@link vadl.rtl.passes.InstructionProgressGraphLowerPass}.
* Decode tree deciding this node.
*
* @return instruction word input
* @return the decoder deciding this node
*/
@Nullable
public ExpressionNode instruction() {
return instruction;
}

public void setInstruction(@Nullable ExpressionNode instruction) {
updateUsageOf(this.instruction, instruction);
this.instruction = instruction;
public RtlDecodeTreeNode decodeTree() {
return decodeTree;
}

@Override
protected void applyOnInputsUnsafe(GraphVisitor.Applier<Node> visitor) {
super.applyOnInputsUnsafe(visitor);
instruction = visitor.applyNullable(this, instruction, ExpressionNode.class);
decodeTree = visitor.apply(this, decodeTree, RtlDecodeTreeNode.class);
}

@Override
protected void collectInputs(List<Node> collection) {
super.collectInputs(collection);
if (this.instruction != null) {
collection.add(instruction);
}
collection.add(decodeTree);
}

@Override
Expand All @@ -108,13 +97,12 @@ protected void collectData(List<Object> collection) {

@Override
public ExpressionNode copy() {
return new RtlIsInstructionNode(instructions,
(instruction != null) ? instruction.copy() : null);
return new RtlIsInstructionNode(instructions, decodeTree.copy(RtlDecodeTreeNode.class));
}

@Override
public Node shallowCopy() {
return new RtlIsInstructionNode(instructions, instruction);
return new RtlIsInstructionNode(instructions, decodeTree);
}

@Override
Expand All @@ -124,6 +112,6 @@ public <T extends GraphNodeVisitor> void accept(T visitor) {

@Override
public String toString() {
return "(" + id + ") IsInstruction<Bool, " + instructions.size() + " instructions>";
return "(" + id + ") IsInstruction<" + instructions.size() + " instructions>";
}
}
Loading