Merge branch 'master' of https://github.com/PeterAaser/TDT4255_EX2
This commit is contained in:
commit
2e37f0b8d7
17 changed files with 478 additions and 260 deletions
|
@ -8,7 +8,7 @@ import chisel3.util.ListLookup
|
|||
* This module is mostly done, but you will have to fill in the blanks in opcodeMap.
|
||||
* You may want to add more signals to be decoded in this module depending on your
|
||||
* design if you so desire.
|
||||
*
|
||||
*
|
||||
* In the "classic" 5 stage decoder signals such as op1select and immType
|
||||
* are not included, however I have added them to my design, and similarily you might
|
||||
* find it useful to add more
|
||||
|
@ -36,23 +36,23 @@ class Decoder() extends Module {
|
|||
val Y = 1.asUInt(1.W)
|
||||
|
||||
/**
|
||||
* In scala we sometimes (ab)use the `->` operator to create tuples.
|
||||
* In scala we sometimes (ab)use the `->` operator to create tuples.
|
||||
* The reason for this is that it serves as convenient sugar to make maps.
|
||||
*
|
||||
*
|
||||
* This doesn't matter to you, just fill in the blanks in the style currently
|
||||
* used, I just want to demystify some of the scala magic.
|
||||
*
|
||||
*
|
||||
* `a -> b` == `(a, b)` == `Tuple2(a, b)`
|
||||
*/
|
||||
val opcodeMap: Array[(BitPat, List[UInt])] = Array(
|
||||
|
||||
// signal memToReg, regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
||||
LW -> List(Y, Y, Y, N, N, N, branchType.DC, rs1, imm, ITYPE, ALUOps.ADD),
|
||||
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
||||
LW -> List(Y, Y, N, N, N, branchType.DC, rs1, imm, ITYPE, ALUOps.ADD),
|
||||
|
||||
SW -> List(N, N, N, Y, N, N, branchType.DC, rs1, imm, STYPE, ALUOps.ADD),
|
||||
SW -> List(N, N, Y, N, N, branchType.DC, rs1, imm, STYPE, ALUOps.ADD),
|
||||
|
||||
ADD -> List(N, Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.ADD),
|
||||
SUB -> List(N, Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SUB),
|
||||
ADD -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.ADD),
|
||||
SUB -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SUB),
|
||||
|
||||
/**
|
||||
TODO: Fill in the blanks
|
||||
|
@ -60,23 +60,22 @@ class Decoder() extends Module {
|
|||
)
|
||||
|
||||
|
||||
val NOP = List(N, N, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.DC)
|
||||
val NOP = List(N, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.DC)
|
||||
|
||||
val decodedControlSignals = ListLookup(
|
||||
io.instruction.asUInt(),
|
||||
NOP,
|
||||
opcodeMap)
|
||||
|
||||
io.controlSignals.memToReg := decodedControlSignals(0)
|
||||
io.controlSignals.regWrite := decodedControlSignals(1)
|
||||
io.controlSignals.memRead := decodedControlSignals(2)
|
||||
io.controlSignals.memWrite := decodedControlSignals(3)
|
||||
io.controlSignals.branch := decodedControlSignals(4)
|
||||
io.controlSignals.jump := decodedControlSignals(5)
|
||||
io.controlSignals.regWrite := decodedControlSignals(0)
|
||||
io.controlSignals.memRead := decodedControlSignals(1)
|
||||
io.controlSignals.memWrite := decodedControlSignals(2)
|
||||
io.controlSignals.branch := decodedControlSignals(3)
|
||||
io.controlSignals.jump := decodedControlSignals(4)
|
||||
|
||||
io.branchType := decodedControlSignals(6)
|
||||
io.op1Select := decodedControlSignals(7)
|
||||
io.op2Select := decodedControlSignals(8)
|
||||
io.immType := decodedControlSignals(9)
|
||||
io.ALUop := decodedControlSignals(10)
|
||||
io.branchType := decodedControlSignals(5)
|
||||
io.op1Select := decodedControlSignals(6)
|
||||
io.op2Select := decodedControlSignals(7)
|
||||
io.immType := decodedControlSignals(8)
|
||||
io.ALUop := decodedControlSignals(9)
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ object Instruction {
|
|||
|
||||
|
||||
class ControlSignals extends Bundle(){
|
||||
val memToReg = Bool()
|
||||
val regWrite = Bool()
|
||||
val memRead = Bool()
|
||||
val memWrite = Bool()
|
||||
|
@ -51,7 +50,6 @@ class ControlSignals extends Bundle(){
|
|||
object ControlSignals {
|
||||
def nop: ControlSignals = {
|
||||
val b = Wire(new ControlSignals)
|
||||
b.memToReg := false.B
|
||||
b.regWrite := false.B
|
||||
b.memRead := false.B
|
||||
b.memWrite := false.B
|
||||
|
|
|
@ -19,7 +19,7 @@ import LogParser._
|
|||
|
||||
object Manifest {
|
||||
|
||||
val singleTest = "forward2.s"
|
||||
val singleTest = "addi.s"
|
||||
|
||||
val nopPadded = false
|
||||
|
||||
|
@ -96,3 +96,30 @@ class AllTests extends FlatSpec with Matchers {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Not tested at all
|
||||
*/
|
||||
class AllTestsWindows extends FlatSpec with Matchers {
|
||||
it should "just werk" in {
|
||||
val werks = getAllWindowsTestNames.filterNot(_ == "convolution.s").map{testname =>
|
||||
say(s"testing $testname")
|
||||
val opts = Manifest.allTestOptions(testname)
|
||||
(testname, TestRunner.run(opts))
|
||||
}
|
||||
if(werks.foldLeft(true)(_ && _._2))
|
||||
say(Console.GREEN + "All tests successful!" + Console.RESET)
|
||||
else {
|
||||
val success = werks.map(x => if(x._2) 1 else 0).sum
|
||||
val total = werks.size
|
||||
say(s"$success/$total tests successful")
|
||||
werks.foreach{ case(name, success) =>
|
||||
val msg = if(success) Console.GREEN + s"$name successful" + Console.RESET
|
||||
else Console.RED + s"$name failed" + Console.RESET
|
||||
say(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ case class TestOptions(
|
|||
printVMtrace : Boolean,
|
||||
printVMfinal : Boolean,
|
||||
printMergedTrace : Boolean,
|
||||
printBinary : Boolean,
|
||||
nopPadded : Boolean,
|
||||
breakPoints : List[Int], // Not implemented
|
||||
testName : String,
|
||||
|
@ -35,7 +36,8 @@ case class TestResult(
|
|||
program : String,
|
||||
vmTrace : String,
|
||||
vmFinal : String,
|
||||
sideBySide : String
|
||||
sideBySide : String,
|
||||
binary : String
|
||||
)
|
||||
|
||||
object TestRunner {
|
||||
|
@ -50,7 +52,8 @@ object TestRunner {
|
|||
binary.toList.sortBy(_._1.value).map(_._2),
|
||||
program.settings,
|
||||
finalVM.pc,
|
||||
testOptions.maxSteps)
|
||||
testOptions.maxSteps,
|
||||
testOptions.testName)
|
||||
} yield {
|
||||
val traces = mergeTraces(trace, chiselTrace).map(x => printMergedTraces((x), program))
|
||||
|
||||
|
@ -58,6 +61,7 @@ object TestRunner {
|
|||
val vmTraceString = printVMtrace(trace, program)
|
||||
val vmFinalState = finalVM.regs.show
|
||||
val traceString = printLogSideBySide(trace, chiselTrace, program)
|
||||
val binaryString = printBinary(binary)
|
||||
|
||||
val regError = compareRegs(trace, chiselTrace)
|
||||
val memError = compareMem(trace, chiselTrace)
|
||||
|
@ -68,7 +72,8 @@ object TestRunner {
|
|||
programString,
|
||||
vmTraceString,
|
||||
vmFinalState.toString,
|
||||
traceString)
|
||||
traceString,
|
||||
binaryString)
|
||||
}
|
||||
|
||||
testResults.left.foreach{ error =>
|
||||
|
@ -78,15 +83,16 @@ object TestRunner {
|
|||
testResults.map{ testResults =>
|
||||
val successful = List(testResults.regError, testResults.memError).flatten.headOption.map(_ => false).getOrElse(true)
|
||||
if(successful)
|
||||
say(s"${testOptions.testName} succesful")
|
||||
sayGreen(s"${testOptions.testName} succesful")
|
||||
else
|
||||
say(s"${testOptions.testName} failed")
|
||||
sayRed(s"${testOptions.testName} failed")
|
||||
|
||||
if(testOptions.printIfSuccessful && successful){
|
||||
if(testOptions.printParsedProgram) say(testResults.program)
|
||||
if(testOptions.printVMtrace) say(testResults.vmTrace)
|
||||
if(testOptions.printVMfinal) say(testResults.vmFinal)
|
||||
if(testOptions.printMergedTrace) say(testResults.sideBySide)
|
||||
if(testOptions.printBinary) say(testResults.binary)
|
||||
}
|
||||
else{
|
||||
if(testOptions.printErrors){
|
||||
|
@ -97,6 +103,7 @@ object TestRunner {
|
|||
if(testOptions.printVMtrace) say(testResults.vmTrace)
|
||||
if(testOptions.printVMfinal) say(testResults.vmFinal)
|
||||
if(testOptions.printMergedTrace) say(testResults.sideBySide)
|
||||
if(testOptions.printBinary) say(testResults.binary)
|
||||
}
|
||||
successful
|
||||
}.toOption.getOrElse(false)
|
||||
|
|
|
@ -159,12 +159,18 @@ object ChiselTestRunner {
|
|||
binary : List[Int],
|
||||
settings : List[TestSetting],
|
||||
terminalAddress : Addr,
|
||||
maxSteps : Int): Either[String, (Option[String], List[CircuitTrace])] = {
|
||||
maxSteps : Int,
|
||||
testName : String): Either[String, (Option[String], List[CircuitTrace])] = {
|
||||
|
||||
var sideEffectExtravaganza: Option[(Option[String], List[CircuitTrace])] = None
|
||||
|
||||
val error: Either[String, Boolean] = scala.util.Try {
|
||||
chisel3.iotesters.Driver(() => new Tile(), "treadle") { c =>
|
||||
chisel3.iotesters.Driver.execute(Array(
|
||||
"--generate-vcd-output", "on",
|
||||
"--backend-name", "treadle",
|
||||
"--target-dir", "waveforms",
|
||||
"--top-name", testName
|
||||
), () => new Tile) { c =>
|
||||
new PeekPokeTester(c) {
|
||||
val testRunner = new ChiselTestRunner(
|
||||
binary,
|
||||
|
|
|
@ -61,7 +61,10 @@ object fileUtils {
|
|||
def getAllTests: List[File] = getListOfFilesRecursive(getTestDir.getPath)
|
||||
.filter( f => f.getPath.endsWith(".s") )
|
||||
|
||||
def getAllTestNames: List[String] = getAllTests.map(_.toString.split("/").takeRight(1).mkString)
|
||||
def getAllTestNames: List[String] = getAllTests.map(_.toString.split("/").takeRight(1).mkString)
|
||||
|
||||
// Not tested.
|
||||
def getAllWindowsTestNames: List[String] = getAllTests.map(_.toString.split("\\\\").takeRight(1).mkString)
|
||||
|
||||
def clearTestResults = {
|
||||
try {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue