-
Notifications
You must be signed in to change notification settings - Fork 4
/
TestUtils.bsv
107 lines (93 loc) · 3.35 KB
/
TestUtils.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
105
106
107
import FIFOF :: *;
import GetPut :: *;
import Vector :: *;
import ClientServer :: *;
import Randomizable :: *;
import Ports :: *;
import EthUtils :: *;
import SemiFifo :: *;
typedef 32 DELAY_COUNT_WIDTH;
typedef Server#(
dType, dType
) RandomDelay#(type dType, numeric type maxDelay);
module mkRandomDelay(RandomDelay#(dType, maxDelay))
provisos(Bits#(dType, sz));
Bit#(DELAY_COUNT_WIDTH) maxRandDelay = fromInteger(valueOf(maxDelay));
FIFOF#(dType) buffer <- mkFIFOF;
Reg#(Bool) hasInit <- mkReg(False);
Reg#(Bit#(DELAY_COUNT_WIDTH)) delayCounter <- mkReg(0);
Reg#(Bit#(DELAY_COUNT_WIDTH)) randDelayReg <- mkReg(0);
let passData = delayCounter == randDelayReg;
Randomize#(Bit#(DELAY_COUNT_WIDTH)) delayRandomizer <- mkGenericRandomizer;
rule doInit if (!hasInit);
delayRandomizer.cntrl.init;
hasInit <= True;
endrule
rule doCount;
if (delayCounter == randDelayReg) begin
delayCounter <= 0;
let delay <- delayRandomizer.next;
if (valueOf(maxDelay) == 0) begin
randDelayReg <= 0;
end
else begin
randDelayReg <= delay > maxRandDelay ? maxRandDelay : delay;
end
end
else begin
delayCounter <= delayCounter + 1;
end
endrule
interface Put request = toPut(buffer);
interface Get response;
method ActionValue#(dType) get if (passData);
let data = buffer.first;
buffer.deq;
return data;
endmethod
endinterface
endmodule
module mkDataStreamSender#(
String instanceName,
FifoOut#(Bit#(maxRawByteNumWidth)) rawByteNumIn,
FifoOut#(Bit#(maxRawDataWidth)) rawDataIn
)(DataStreamFifoOut)
provisos(
Mul#(maxRawByteNum, BYTE_WIDTH, maxRawDataWidth),
Mul#(DATA_BUS_BYTE_WIDTH, maxFragNum, maxRawByteNum),
NumAlias#(TLog#(TAdd#(maxRawByteNum, 1)), maxRawByteNumWidth),
NumAlias#(TLog#(maxFragNum), maxFragNumWidth)
);
Reg#(Bit#(maxRawByteNumWidth)) rawByteCounter <- mkReg(0);
Reg#(Bit#(maxFragNumWidth)) fragCounter <- mkReg(0);
FIFOF#(DataStream) outputBuf <- mkFIFOF;
rule doFragment;
let rawData = rawDataIn.first;
Vector#(maxFragNum, Data) rawDataVec = unpack(rawData);
let rawByteNum = rawByteNumIn.first;
DataStream dataStream = DataStream {
data: rawDataVec[fragCounter],
byteEn: setAllBits,
isFirst: fragCounter == 0,
isLast: False
};
let nextRawByteCountVal = rawByteCounter + fromInteger(valueOf(DATA_BUS_BYTE_WIDTH));
if (nextRawByteCountVal >= rawByteNum) begin
let extraByteNum = nextRawByteCountVal - rawByteNum;
dataStream.byteEn = dataStream.byteEn >> extraByteNum;
dataStream.data = bitMask(dataStream.data, dataStream.byteEn);
dataStream.isLast = True;
fragCounter <= 0;
rawByteCounter <= 0;
rawDataIn.deq;
rawByteNumIn.deq;
end
else begin
fragCounter <= fragCounter + 1;
rawByteCounter <= nextRawByteCountVal;
end
outputBuf.enq(dataStream);
$display("%s: send %8d fragment ", instanceName, fragCounter, fshow(dataStream));
endrule
return convertFifoToFifoOut(outputBuf);
endmodule