-
Notifications
You must be signed in to change notification settings - Fork 0
/
top_pipelined.bsv
117 lines (99 loc) · 3.48 KB
/
top_pipelined.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
108
109
110
111
112
113
114
115
116
117
// PIPELINED SINGLE CORE PROCESSOR WITH 2 LEVEL CACHE
import RVUtil::*;
import BRAM::*;
import pipelined::*;
import FIFO::*;
import MemTypes::*;
import CacheInterface::*;
// typedef Bit#(32) Word;
module mktop_pipelined(Empty);
// Instantiate the dual ported memory
BRAM_Configure cfg = defaultValue();
cfg.loadFormat = tagged Hex "mem.vmh";
BRAM2PortBE#(Bit#(30), Word, 4) bram <- mkBRAM2ServerBE(cfg);
CacheInterface cache <- mkCacheInterface();
RVIfc rv_core <- mkpipelined;
Reg#(Mem) ireq <- mkRegU;
Reg#(Mem) dreq <- mkRegU;
FIFO#(Mem) mmioreq <- mkFIFO;
let debug = False;
Reg#(Bit#(32)) cycle_count <- mkReg(0);
rule tic;
cycle_count <= cycle_count + 1;
endrule
rule requestI;
let req <- rv_core.getIReq;
if (debug) $display("Get IReq", fshow(req));
ireq <= req;
cache.sendReqInstr(CacheReq{word_byte: req.byte_en, addr: req.addr, data: req.data});
// bram.portB.request.put(BRAMRequestBE{
// writeen: req.byte_en,
// responseOnWrite: True,
// address: truncate(req.addr >> 2),
// datain: req.data});
endrule
rule responseI;
let x <- cache.getRespInstr();
// let x <- bram.portB.response.get();
let req = ireq;
if (debug) $display("Get IResp ", fshow(req), fshow(x));
req.data = x;
rv_core.getIResp(req);
endrule
rule requestD;
let req <- rv_core.getDReq;
dreq <= req;
if (debug) $display("Get DReq", fshow(req));
// $display("DATA ",fshow(CacheReq{word_byte: req.byte_en, addr: req.addr, data: req.data}));
cache.sendReqData(CacheReq{word_byte: req.byte_en, addr: req.addr, data: req.data});
// bram.portA.request.put(BRAMRequestBE{
// writeen: req.byte_en,
// responseOnWrite: True,
// address: truncate(req.addr >> 2),
// datain: req.data});
endrule
rule responseD;
// let x <- bram.portA.response.get();
let x <- cache.getRespData();
let req = dreq;
if (debug) $display("Get IResp ", fshow(req), fshow(x));
req.data = x;
rv_core.getDResp(req);
endrule
rule requestMMIO;
let req <- rv_core.getMMIOReq;
if (debug) $display("Get MMIOReq", fshow(req));
if (req.byte_en == 'hf) begin
if (req.addr == 'hf000_fff4) begin
// Write integer to STDERR
$fwrite(stderr, "%0d", req.data);
$fflush(stderr);
end
end
if (req.addr == 'hf000_fff0) begin
// Writing to STDERR
$fwrite(stderr, "%c", req.data[7:0]);
$fflush(stderr);
end else
if (req.addr == 'hf000_fff8) begin
$display("RAN CYCLES", cycle_count);
// Exiting Simulation
if (req.data == 0) begin
$fdisplay(stderr, " [0;32mPASS[0m");
end
else
begin
$fdisplay(stderr, " [0;31mFAIL[0m (%0d)", req.data);
end
$fflush(stderr);
$finish;
end
mmioreq.enq(req);
endrule
rule responseMMIO;
let req = mmioreq.first();
mmioreq.deq();
if (debug) $display("Put MMIOResp", fshow(req));
rv_core.getMMIOResp(req);
endrule
endmodule