summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests/Harness.scala
blob: d4330cd6dd6f4e3925b82f45bfe40e3ac38337bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// SPDX-License-Identifier: Apache-2.0

package chiselTests

import java.io.File

class HarnessSpec extends ChiselPropSpec {

  def makeTrivialVerilog: (File => File) = makeHarness((prefix: String) => s"""
module ${prefix};
  initial begin
    $$display("$prefix!");
    $$finish;
  end
endmodule
""", ".v") _

  def makeFailingVerilog: (File => File) = makeHarness(
    (prefix: String) => s"""
module $prefix;
  initial begin
    assert (1 == 0) else $$error("My specific, expected error message!");
    $$display("$prefix!");
    $$finish;
  end
endmodule
""",
    ".v"
  ) _

  def makeCppHarness: (File => File) = makeHarness(
    (prefix: String) => s"""
#include "V$prefix.h"
#include "verilated.h"

vluint64_t main_time = 0;
double sc_time_stamp () { return main_time; }

int main(int argc, char **argv, char **env) {
    Verilated::commandArgs(argc, argv);
    V${prefix}* top = new V${prefix};
    while (!Verilated::gotFinish()) { top->eval(); }
    delete top;
    exit(0);
}

void vl_finish(const char* filename, int linenum, const char* hier) {
  Verilated::flushCall();
  exit(0);
}
""",
    ".cpp"
  ) _

  /** Compiles a C++ emulator from Verilog and returns the path to the
    * executable and the executable filename as a tuple.
    */
  def simpleHarnessBackend(make: File => File): (File, String) = {
    val target = "test"
    val path = createTestDirectory(target)
    val fname = new File(path, target)

    val cppHarness = makeCppHarness(fname)

    make(fname)
    verilogToCpp(target, path, Seq(), cppHarness).!
    cppToExe(target, path).!
    (path, target)
  }

  property("Test making trivial verilog harness and executing") {
    val (path, target) = simpleHarnessBackend(makeTrivialVerilog)

    assert(executeExpectingSuccess(target, path))
  }

  property("Test that assertion failues in Verilog are caught") {
    val (path, target) = simpleHarnessBackend(makeFailingVerilog)

    assert(!executeExpectingSuccess(target, path))
    assert(executeExpectingFailure(target, path))
    assert(executeExpectingFailure(target, path, "My specific, expected error message!"))
    assert(!executeExpectingFailure(target, path, "A string that doesn't match any test output"))
  }
}