-
Notifications
You must be signed in to change notification settings - Fork 1
/
TestCompletionBuf.bsv
104 lines (91 loc) · 3.48 KB
/
TestCompletionBuf.bsv
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
import EthUtils :: *;
import FIFOF :: *;
import CompletionBuf :: *;
import Randomizable :: *;
typedef Bit#(32) CBufData;
typedef 7 CBUF_SIZE;
(* synthesize *)
module mkTestCompletionBuf();
Integer caseNum = 8192;
Integer maxCycle = 20000;
Reg#(Bit#(16)) inputCount <- mkReg(0);
Reg#(Bit#(16)) outputCount <- mkReg(0);
Reg#(Bit#(16)) cycle <- mkReg(0);
Randomize#(CBufData) dataRand <- mkGenericRandomizer;
Randomize#(Bool) completeRand <- mkGenericRandomizer;
Randomize#(Bool) deqRand <- mkGenericRandomizer;
CompletionBuf#(CBUF_SIZE, CBufData) cBuf <- mkCompletionBuf;
FIFOF#(CBufData) refBuf <- mkSizedFIFOF(valueOf(CBUF_SIZE));
FIFOF#(Tuple2#(CBufIndex#(CBUF_SIZE), CBufData)) completeBuf <- mkFIFOF;
FIFOF#(Tuple2#(CBufIndex#(CBUF_SIZE), CBufData)) reorderBuf <- mkSizedFIFOF(valueOf(CBUF_SIZE));
rule test;
if (cycle == 0) begin
dataRand.cntrl.init;
completeRand.cntrl.init;
deqRand.cntrl.init;
end
cycle <= cycle + 1;
$display("\nCycle %d -----------------------------------",cycle);
immAssert(
cycle != fromInteger(maxCycle),
"Testbench timeout assertion @ mkTestCompletionBuf",
$format("Cycle count can't overflow %d", maxCycle)
);
endrule
rule reserveCBuf if (inputCount < fromInteger(caseNum));
let data <- dataRand.next;
let token <- cBuf.reserve;
refBuf.enq(data);
completeBuf.enq(tuple2(token, data));
$display("Reserve CBuf %d: token=%d data=%d", inputCount, token, data);
endrule
rule completeCBuf;
let completeSelect <- completeRand.next;
if (completeSelect) begin
if (completeBuf.notEmpty) begin
let tokenAndData = completeBuf.first;
completeBuf.deq;
reorderBuf.enq(tokenAndData);
end
if (reorderBuf.notEmpty) begin
let tokenAndData = reorderBuf.first;
reorderBuf.deq;
cBuf.complete(tokenAndData);
$display("Complete CBuf: index=%d data=%d", tpl_1(tokenAndData), tpl_2(tokenAndData));
end
end
else begin
if (completeBuf.notEmpty) begin
let tokenAndData = completeBuf.first;
completeBuf.deq;
cBuf.complete(tokenAndData);
$display("Complete CBuf: index=%d data=%d", tpl_1(tokenAndData), tpl_2(tokenAndData));
end
if (reorderBuf.notEmpty) begin
let tokenAndData = reorderBuf.first;
reorderBuf.deq;
reorderBuf.enq(tokenAndData);
end
end
endrule
rule deqCBuf if (outputCount < fromInteger(caseNum));
let idDeq <- deqRand.next;
if (idDeq) begin
let dutData = cBuf.first;
cBuf.deq;
let refData = refBuf.first;
refBuf.deq;
$display("CBuf Output %d: dut data=%x ref data=%x", outputCount, dutData, refData);
outputCount <= outputCount + 1;
immAssert(
refData == dutData,
"check output of completion buf and reference buf @ mkTestCompletionBuf",
$format("dut data is inconsistent with ref data")
);
end
endrule
rule finishTest if (outputCount == fromInteger(caseNum));
$display("Pass all %d tests", caseNum);
$finish;
endrule
endmodule