-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTesting.bsv
More file actions
141 lines (108 loc) · 3.46 KB
/
Copy pathTesting.bsv
File metadata and controls
141 lines (108 loc) · 3.46 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*****************************************************************************
Testing
=======
Alex Horsman, Sept 2012
This library provides modules to help with implementing test suites. It
provides a special module type TestModule, which uses ModuleCollect to
store a series of tests, and then run them all in sequence, reporting the
results. A test is an RStmt returning a Bool, indicating
whether the test passed. Tests are added with the module addTest, and the
tests within a TestModule can be run using runTests.
The general usage pattern is:
//Some module definition.
module mkMyMod(MyModIfc);
...
endmodule
//TestModule for MyMod.
module [TestModule] testMyMod(Empty);
//Necessary state definitions, presumably including
//at least one instance of MyMod.
addTest("Test 1 name",seq
...
return <result>;
endseq);
...
addTest("Test N name,...);
endmodule
//Synthesizable module to run the above TestModule.
module [Module] testRunner(Empty);
runTests(testMyMod);
endmodule
This library also allows randomised tests, using addFuzzTest. This module
takes a function returning a test as an argument, and a number of random
tests to run.
Warning!: This module creates large unrolled FSMs to implement various
features and as a result, can take a long time to compile.
*****************************************************************************/
import List::*;
import StmtFSM::*;
import ModuleCollect::*;
import StmtUtils::*;
typedef RStmt#(Bool) TestStmt;
typedef Tuple2#(String,TestStmt) NamedTest;
typedef ModuleCollect#(NamedTest) TestModule;
module [TestModule] addTest#(String name, TestStmt test)(Empty);
addToCollection(tuple2(name,test));
endmodule
module [Module] runTests#(TestModule#(Empty) tm)(Empty);
let {_, tests} <- getCollection(tm);
Reg#(Bool) passed <- mkRegU;
Reg#(int) failCount <- mkReg(0);
module foldTest#(Stmt acc, NamedTest nt)(Stmt);
let {name,test} = nt;
function stalled(trigger) = seq
await(trigger);
test;
endseq;
FSMServer#(Bool,Bool) fsm <- mkFSMServer(stalled);
return seq
acc;
$write("Running test \"%s\"... ",name);
passed <- callServer(fsm,True);
if (passed) seq
$display("Passed");
endseq else seq
$display("FAILED");
failCount <= failCount + 1;
endseq
endseq;
endmodule
Stmt testSequence <- foldlM(foldTest,seq endseq,tests);
mkAutoFSM(seq
$display("Starting tests");
testSequence;
if (failCount == 0)
$display("All tests passed");
else
$display("%d tests failed!",failCount);
endseq);
endmodule
import Randomizable::*;
typedef (function TestStmt f(a x)) InputTest#(type a);
module [TestModule] addFuzzTest#(Integer times, String name, InputTest#(a) test)(Empty)
provisos(Bits#(a,_),Eq#(a),Bounded#(a));
Randomize#(a) random <- mkGenericRandomizer;
Reg#(a) in <- mkRegU;
FSMServer#(a,Bool) testSeq <- mkFSMServer(test);
Reg#(Bool) passed <- mkRegU;
addTest(name,seq
random.cntrl.init();
repeat(fromInteger(times)) seq
storeAV(random.next(),in);
passed <- callServer(testSeq,in);
if (!passed) break;
endseq
return passed;
endseq);
endmodule
module [TestModule] testTesting(Empty);
addTest("Should Pass",seq return True; endseq);
addTest("Should Fail",seq return False; endseq);
function TestStmt f(bit x) = (seq return True; endseq);
addFuzzTest(10,"Should Pass",f);
function TestStmt g(bit x) = (seq return False; endseq);
addFuzzTest(10,"Should Fail",g);
endmodule
module [Module] test(Empty);
runTests(testTesting);
endmodule