Skip to content

Commit 1f6f187

Browse files
Various bug fixes and cleanup (#212)
- DIspatch stall counts were off by one stall condition providing incorrect stall counts - The handshake between the LS and Data was off by one cycle forcing the LS to always see a cache miss even when hit - Some basic cleanup on the code --------- Co-authored-by: Knute Lingaard <klingaard@mips.com>
1 parent 9abf9e6 commit 1f6f187

31 files changed

+3539
-2877
lines changed

arches/big_core.yaml

+18-2
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,34 @@ top.cpu.core0.extension.core_extensions:
4040
# ["0", "3"] means iq0 has exe0, exe1, exe2, and exe3, so it's inclusive
4141
# if you want just one execution unit to issue queue you can do:
4242
# ["0"] which would result in iq0 -> exe0
43-
# *note if you change the number of issue queues,
43+
# *note if you change the number of issue queues,
4444
# you need to add it to latency matrix below
4545

4646
issue_queue_to_pipe_map:
47-
[
47+
[
4848
["0", "1"], # iq0 -> exe0, exe1
4949
["2", "3"], # iq1 -> exe2, exe3
5050
["4", "5"], # iq2 -> exe4, exe5
5151
["6", "7"], # iq3 -> exe6, exe7
5252
["8", "9"], # iq4 -> exe8, exe9
5353
["10"] # iq5 -> exe10
5454
]
55+
56+
exe_pipe_rename:
57+
[
58+
["exe0", "sys_pipe"],
59+
["exe1", "alu1_pipe"],
60+
["exe2", "alu2_pipe"],
61+
["exe3", "alu3_pipe"],
62+
["exe4", "alu4_pipe"],
63+
["exe5", "alu5_pipe"],
64+
["exe6", "fpu0_pipe"],
65+
["exe7", "fpu1_pipe"],
66+
["exe8", "br0_pipe"],
67+
["exe9", "br1_pipe"],
68+
["exe10", "vint_pipe"]
69+
]
70+
5571
top.cpu.core0.rename.scoreboards:
5672
# From
5773
# |

arches/medium_core.yaml

+14-3
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,33 @@ top.cpu.core0.extension.core_extensions:
2929
["br"], # exe5
3030
["vint", "vset", "vdiv", "vmul"] # exe6
3131
]
32-
32+
3333
# this is used to set how many units per queue
3434
# ["0", "3"] means iq0 has exe0, exe1, exe2, and exe3, so it's inclusive
3535
# if you want just one execution unit to issue queue you can do:
3636
# ["0"] which would result in iq0 -> exe0
37-
# *note if you change the number of issue queues,
37+
# *note if you change the number of issue queues,
3838
# you need to add it to latency matrix below
3939
issue_queue_to_pipe_map:
40-
[
40+
[
4141
["0"], # iq0 -> exe0
4242
["1", "2"], # iq1 -> exe1, exe2
4343
["3", "4"], # iq2 -> exe3, exe4
4444
["5"], # iq3 -> exe5
4545
["6"]
4646
]
4747

48+
exe_pipe_rename:
49+
[
50+
["exe0", "alu0_pipe"],
51+
["exe1", "alu1_pipe"],
52+
["exe2", "alu2_pipe"],
53+
["exe3", "fpu0_pipe"],
54+
["exe4", "fpu1_pipe"],
55+
["exe5", "br_pipe"],
56+
["exe6", "vint_pipe"]
57+
]
58+
4859
top.cpu.core0.rename.scoreboards:
4960
# From
5061
# |

arches/small_core.yaml

+11-2
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,25 @@ top.cpu.core0.extension.core_extensions:
2727
# ["0", "3"] means iq0 has exe0, exe1, exe2, and exe3, so it's inclusive
2828
# if you want just one execution unit to issue queue you can do:
2929
# ["0"] which would result in iq0 -> exe0
30-
# *note if you change the number of issue queues,
30+
# *note if you change the number of issue queues,
3131
# you need to add it to latency matrix below
3232
issue_queue_to_pipe_map:
33-
[
33+
[
3434
["0"], # iq0 -> exe0
3535
["1"], # iq1 -> exe1
3636
["2"], # iq2 -> exe2
3737
["3"], # iq3 -> exe3
3838
]
3939

40+
exe_pipe_rename:
41+
[
42+
["exe0", "alu0_pipe"],
43+
["exe1", "fpu0_pipe"],
44+
["exe2", "br_pipe"],
45+
["exe3", "vint_pipe"]
46+
]
47+
48+
4049
top.cpu.core0.rename.scoreboards:
4150
# From
4251
# |

core/DCache.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,6 @@ namespace olympia
272272
void DCache::receiveMemReqFromLSU_(const MemoryAccessInfoPtr & memory_access_info_ptr)
273273
{
274274
ILOG("Received memory access request from LSU " << memory_access_info_ptr);
275-
out_lsu_lookup_ack_.send(memory_access_info_ptr);
276275
in_l2_cache_resp_receive_event_.schedule();
277276
lsu_mem_access_info_ = memory_access_info_ptr;
278277
}

core/DCache.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ namespace olympia
9797
// Input Ports
9898
////////////////////////////////////////////////////////////////////////////////
9999
sparta::DataInPort<MemoryAccessInfoPtr> in_lsu_lookup_req_{&unit_port_set_,
100-
"in_lsu_lookup_req", 1};
100+
"in_lsu_lookup_req", 0};
101101

102102
sparta::DataInPort<uint32_t> in_l2cache_ack_{&unit_port_set_, "in_l2cache_ack", 1};
103103

core/Dispatch.hpp

+77-71
Original file line numberDiff line numberDiff line change
@@ -153,83 +153,89 @@ namespace olympia
153153
// Counters -- this is only supported in C++11 -- uses
154154
// Counter's move semantics
155155
std::array<sparta::CycleCounter, N_STALL_REASONS> stall_counters_{
156-
{sparta::CycleCounter(getStatisticSet(), "stall_cmov_busy", "CMOV busy",
157-
sparta::Counter::COUNT_NORMAL, getClock()),
158-
sparta::CycleCounter(getStatisticSet(), "stall_div_busy", "DIV busy",
159-
sparta::Counter::COUNT_NORMAL, getClock()),
160-
sparta::CycleCounter(getStatisticSet(), "stall_faddsub_busy", "FADDSUB busy",
161-
sparta::Counter::COUNT_NORMAL, getClock()),
162-
sparta::CycleCounter(getStatisticSet(), "stall_float_busy", "FLOAT busy",
163-
sparta::Counter::COUNT_NORMAL, getClock()),
164-
sparta::CycleCounter(getStatisticSet(), "stall_fmac_busy", "FMAC busy",
165-
sparta::Counter::COUNT_NORMAL, getClock()),
166-
sparta::CycleCounter(getStatisticSet(), "stall_i2f_busy", "I2F busy",
167-
sparta::Counter::COUNT_NORMAL, getClock()),
168-
sparta::CycleCounter(getStatisticSet(), "stall_f2i_busy", "F2I busy",
169-
sparta::Counter::COUNT_NORMAL, getClock()),
170-
sparta::CycleCounter(getStatisticSet(), "stall_int_busy", "INT busy",
171-
sparta::Counter::COUNT_NORMAL, getClock()),
172-
sparta::CycleCounter(getStatisticSet(), "stall_lsu_busy", "LSU busy",
173-
sparta::Counter::COUNT_NORMAL, getClock()),
174-
sparta::CycleCounter(getStatisticSet(), "stall_mul_busy", "MUL busy",
175-
sparta::Counter::COUNT_NORMAL, getClock()),
176-
sparta::CycleCounter(getStatisticSet(), "stall_br_busy", "BR busy",
177-
sparta::Counter::COUNT_NORMAL, getClock()),
178-
sparta::CycleCounter(getStatisticSet(), "stall_vint_busy", "VINT busy",
179-
sparta::Counter::COUNT_NORMAL, getClock()),
156+
{
157+
sparta::CycleCounter(getStatisticSet(), "stall_br_busy", "BR busy",
158+
sparta::Counter::COUNT_NORMAL, getClock()),
159+
sparta::CycleCounter(getStatisticSet(), "stall_cmov_busy", "CMOV busy",
160+
sparta::Counter::COUNT_NORMAL, getClock()),
161+
sparta::CycleCounter(getStatisticSet(), "stall_div_busy", "DIV busy",
162+
sparta::Counter::COUNT_NORMAL, getClock()),
163+
sparta::CycleCounter(getStatisticSet(), "stall_faddsub_busy", "FADDSUB busy",
164+
sparta::Counter::COUNT_NORMAL, getClock()),
165+
sparta::CycleCounter(getStatisticSet(), "stall_float_busy", "FLOAT busy",
166+
sparta::Counter::COUNT_NORMAL, getClock()),
167+
sparta::CycleCounter(getStatisticSet(), "stall_fmac_busy", "FMAC busy",
168+
sparta::Counter::COUNT_NORMAL, getClock()),
169+
sparta::CycleCounter(getStatisticSet(), "stall_i2f_busy", "I2F busy",
170+
sparta::Counter::COUNT_NORMAL, getClock()),
171+
sparta::CycleCounter(getStatisticSet(), "stall_f2i_busy", "F2I busy",
172+
sparta::Counter::COUNT_NORMAL, getClock()),
173+
sparta::CycleCounter(getStatisticSet(), "stall_int_busy", "INT busy",
174+
sparta::Counter::COUNT_NORMAL, getClock()),
175+
sparta::CycleCounter(getStatisticSet(), "stall_lsu_busy", "LSU busy",
176+
sparta::Counter::COUNT_NORMAL, getClock()),
177+
sparta::CycleCounter(getStatisticSet(), "stall_mul_busy", "MUL busy",
178+
sparta::Counter::COUNT_NORMAL, getClock()),
179+
sparta::CycleCounter(getStatisticSet(), "stall_vint_busy", "VINT busy",
180+
sparta::Counter::COUNT_NORMAL, getClock()),
180181
sparta::CycleCounter(getStatisticSet(), "stall_vfixed_busy", "VFIXED busy",
181182
sparta::Counter::COUNT_NORMAL, getClock()),
182-
sparta::CycleCounter(getStatisticSet(), "stall_vmask_busy", "VMASK busy",
183-
sparta::Counter::COUNT_NORMAL, getClock()),
184-
sparta::CycleCounter(getStatisticSet(), "stall_vmul_busy", "VMUL busy",
185-
sparta::Counter::COUNT_NORMAL, getClock()),
186-
sparta::CycleCounter(getStatisticSet(), "stall_vdiv_busy", "VDIV busy",
187-
sparta::Counter::COUNT_NORMAL, getClock()),
188-
sparta::CycleCounter(getStatisticSet(), "stall_vset_busy", "VSET busy",
189-
sparta::Counter::COUNT_NORMAL, getClock()),
190-
sparta::CycleCounter(getStatisticSet(), "stall_sys_busy", "No credits from ROB",
191-
sparta::Counter::COUNT_NORMAL, getClock()),
192-
sparta::CycleCounter(getStatisticSet(), "stall_not_stalled",
193-
"Dispatch not stalled, all instructions dispatched",
194-
sparta::Counter::COUNT_NORMAL, getClock())}};
183+
sparta::CycleCounter(getStatisticSet(), "stall_vmask_busy", "VMASK busy",
184+
sparta::Counter::COUNT_NORMAL, getClock()),
185+
sparta::CycleCounter(getStatisticSet(), "stall_vmul_busy", "VMUL busy",
186+
sparta::Counter::COUNT_NORMAL, getClock()),
187+
sparta::CycleCounter(getStatisticSet(), "stall_vdiv_busy", "VDIV busy",
188+
sparta::Counter::COUNT_NORMAL, getClock()),
189+
sparta::CycleCounter(getStatisticSet(), "stall_vset_busy", "VSET busy",
190+
sparta::Counter::COUNT_NORMAL, getClock()),
191+
sparta::CycleCounter(getStatisticSet(), "stall_rob_full", "No credits from ROB",
192+
sparta::Counter::COUNT_NORMAL, getClock()),
193+
sparta::CycleCounter(getStatisticSet(), "stall_not_stalled",
194+
"Dispatch not stalled, all instructions dispatched",
195+
sparta::Counter::COUNT_NORMAL, getClock())
196+
}
197+
};
195198

196199
std::array<sparta::Counter, InstArchInfo::N_TARGET_PIPES> unit_distribution_{
197-
{sparta::Counter(getStatisticSet(), "count_cmov_insts", "Total CMOV insts",
198-
sparta::Counter::COUNT_NORMAL),
199-
sparta::Counter(getStatisticSet(), "count_div_insts", "Total DIV insts",
200-
sparta::Counter::COUNT_NORMAL),
201-
sparta::Counter(getStatisticSet(), "count_faddsub_insts", "Total FADDSUB insts",
202-
sparta::Counter::COUNT_NORMAL),
203-
sparta::Counter(getStatisticSet(), "count_float_insts", "Total FLOAT insts",
204-
sparta::Counter::COUNT_NORMAL),
205-
sparta::Counter(getStatisticSet(), "count_fmac_insts", "Total FMAC insts",
206-
sparta::Counter::COUNT_NORMAL),
207-
sparta::Counter(getStatisticSet(), "count_i2f_insts", "Total I2F insts",
208-
sparta::Counter::COUNT_NORMAL),
209-
sparta::Counter(getStatisticSet(), "count_f2i_insts", "Total F2I insts",
210-
sparta::Counter::COUNT_NORMAL),
211-
sparta::Counter(getStatisticSet(), "count_int_insts", "Total INT insts",
212-
sparta::Counter::COUNT_NORMAL),
213-
sparta::Counter(getStatisticSet(), "count_lsu_insts", "Total LSU insts",
214-
sparta::Counter::COUNT_NORMAL),
215-
sparta::Counter(getStatisticSet(), "count_mul_insts", "Total MUL insts",
216-
sparta::Counter::COUNT_NORMAL),
217-
sparta::Counter(getStatisticSet(), "count_br_insts", "Total BR insts",
218-
sparta::Counter::COUNT_NORMAL),
219-
sparta::Counter(getStatisticSet(), "count_vint_insts", "Total VINT insts",
200+
{
201+
sparta::Counter(getStatisticSet(), "count_br_insts", "Total BR insts",
202+
sparta::Counter::COUNT_NORMAL),
203+
sparta::Counter(getStatisticSet(), "count_cmov_insts", "Total CMOV insts",
204+
sparta::Counter::COUNT_NORMAL),
205+
sparta::Counter(getStatisticSet(), "count_div_insts", "Total DIV insts",
206+
sparta::Counter::COUNT_NORMAL),
207+
sparta::Counter(getStatisticSet(), "count_faddsub_insts", "Total FADDSUB insts",
208+
sparta::Counter::COUNT_NORMAL),
209+
sparta::Counter(getStatisticSet(), "count_float_insts", "Total FLOAT insts",
210+
sparta::Counter::COUNT_NORMAL),
211+
sparta::Counter(getStatisticSet(), "count_fmac_insts", "Total FMAC insts",
212+
sparta::Counter::COUNT_NORMAL),
213+
sparta::Counter(getStatisticSet(), "count_i2f_insts", "Total I2F insts",
214+
sparta::Counter::COUNT_NORMAL),
215+
sparta::Counter(getStatisticSet(), "count_f2i_insts", "Total F2I insts",
216+
sparta::Counter::COUNT_NORMAL),
217+
sparta::Counter(getStatisticSet(), "count_int_insts", "Total INT insts",
218+
sparta::Counter::COUNT_NORMAL),
219+
sparta::Counter(getStatisticSet(), "count_lsu_insts", "Total LSU insts",
220+
sparta::Counter::COUNT_NORMAL),
221+
sparta::Counter(getStatisticSet(), "count_mul_insts", "Total MUL insts",
222+
sparta::Counter::COUNT_NORMAL),
223+
sparta::Counter(getStatisticSet(), "count_vint_insts", "Total VINT insts",
220224
sparta::Counter::COUNT_NORMAL),
221225
sparta::Counter(getStatisticSet(), "count_vfixed_insts", "Total VFIXED insts",
222-
sparta::Counter::COUNT_NORMAL),
223-
sparta::Counter(getStatisticSet(), "count_vmask_insts", "Total VMASK insts",
224-
sparta::Counter::COUNT_NORMAL),
225-
sparta::Counter(getStatisticSet(), "count_vmul_insts", "Total VMUL insts",
226-
sparta::Counter::COUNT_NORMAL),
227-
sparta::Counter(getStatisticSet(), "count_vdiv_insts", "Total VDIV insts",
228-
sparta::Counter::COUNT_NORMAL),
229-
sparta::Counter(getStatisticSet(), "count_vset_insts", "Total VSET insts",
230-
sparta::Counter::COUNT_NORMAL),
231-
sparta::Counter(getStatisticSet(), "count_sys_insts", "Total SYS insts",
232-
sparta::Counter::COUNT_NORMAL)}};
226+
sparta::Counter::COUNT_NORMAL),
227+
sparta::Counter(getStatisticSet(), "count_vmask_insts", "Total VMASK insts",
228+
sparta::Counter::COUNT_NORMAL),
229+
sparta::Counter(getStatisticSet(), "count_vmul_insts", "Total VMUL insts",
230+
sparta::Counter::COUNT_NORMAL),
231+
sparta::Counter(getStatisticSet(), "count_vdiv_insts", "Total VDIV insts",
232+
sparta::Counter::COUNT_NORMAL),
233+
sparta::Counter(getStatisticSet(), "count_vset_insts", "Total VSET insts",
234+
sparta::Counter::COUNT_NORMAL),
235+
sparta::Counter(getStatisticSet(), "count_sys_insts", "Total SYS insts",
236+
sparta::Counter::COUNT_NORMAL)
237+
}
238+
};
233239

234240
// As an example, this is a context counter that does the same
235241
// thing as the unit_distribution counter, albeit a little

core/Inst.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -517,9 +517,9 @@ namespace olympia
517517
// - any changes here will break EXPECT
518518
inline std::ostream & operator<<(std::ostream & os, const Inst & inst)
519519
{
520-
os << "uid: " << inst.getUniqueID() << " " << std::setw(10) << inst.getStatus() << " "
521-
<< std::hex << inst.getPC() << std::dec << " pid: " << inst.getProgramID()
522-
<< " uopid: " << inst.getUOpID() << " '" << inst.getDisasm() << "' ";
520+
os << "uid:" << inst.getUniqueID() << std::setw(10) << inst.getStatus() << " "
521+
<< std::hex << inst.getPC() << std::dec << " pid:" << inst.getProgramID()
522+
<< " uopid:" << inst.getUOpID() << " '" << inst.getDisasm() << "' ";
523523
return os;
524524
}
525525

core/IssueQueue.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ namespace olympia
188188
ready_queue_.erase(delete_iter);
189189
popIssueQueue_(inst);
190190
++total_insts_issued_;
191+
issue_event_.collect(*inst);
191192
break;
192193
}
193194
}

core/IssueQueue.hpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "sparta/simulation/ResourceFactory.hpp"
1515
#include "sparta/simulation/TreeNode.hpp"
1616
#include "sparta/simulation/Unit.hpp"
17+
#include "sparta/pevents/PeventCollector.hpp"
1718

1819
#include "sparta/resources/PriorityQueue.hpp"
1920

@@ -137,9 +138,13 @@ namespace olympia
137138
sparta::Counter::COUNT_NORMAL};
138139
bool rob_stopped_simulation_ = false;
139140
friend class IssueQueueTester;
141+
142+
// For correlation activities
143+
sparta::pevents::PeventCollector<InstPEventPairs> issue_event_{"ISSUE", getContainer(), getClock()};
144+
140145
};
141146

142147
using IssueQueueFactory =
143148
sparta::ResourceFactory<olympia::IssueQueue, olympia::IssueQueue::IssueQueueParameterSet>;
144149
class IssueQueueTester;
145-
} // namespace olympia
150+
} // namespace olympia

core/LSU.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ namespace olympia
104104
node->getParent()->registerForNotification<bool, LSU, &LSU::onROBTerminate_>(
105105
this, "rob_stopped_notif_channel", false /* ROB maybe not be constructed yet */);
106106

107+
108+
auto & events = ldst_pipeline_.getEventsAtStage(cache_read_stage_);
109+
for (auto & event : events) {
110+
in_cache_lookup_ack_.registerConsumerEvent(event->getScheduleable());
111+
}
112+
107113
uev_append_ready_ >> uev_issue_inst_;
108114
// NOTE:
109115
// To resolve the race condition when:
@@ -244,7 +250,7 @@ namespace olympia
244250
// either a new issue event, or a re-issue event
245251
// however, we can ONLY update instruction status as SCHEDULED for a new issue event
246252

247-
ILOG("Another issue event scheduled " << inst_ptr);
253+
ILOG("Inst fully readdy: " << inst_ptr);
248254

249255
if (isReadyToIssueInsts_())
250256
{
@@ -529,6 +535,7 @@ namespace olympia
529535
// Is its a cache miss we dont need to rechedule the instruction
530536
if (!mem_access_info_ptr->isCacheHit())
531537
{
538+
ILOG("ma cache miss: " << mem_access_info_ptr);
532539
return;
533540
}
534541

core/LoadStoreInstInfo.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ namespace olympia
195195
inline std::ostream & operator<<(std::ostream & os, const olympia::LoadStoreInstInfo & ls_info)
196196
{
197197
os << "lsinfo: "
198-
<< "uid: " << ls_info.getInstUniqueID() << " pri:" << ls_info.getPriority()
199-
<< " state: " << ls_info.getState();
198+
<< "uid:" << ls_info.getInstUniqueID() << " pri:" << ls_info.getPriority()
199+
<< " state:" << ls_info.getState();
200200
return os;
201201
}
202202

layouts/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
all: small_core.alf medium_core.alf big_core.alf
33

4-
%_core.alf: ./gen_alf.py
4+
%_core.alf: ./gen_alf.py ../fastdebug/olympia
55
@echo "Generating pipeout for $@"
6-
@(cd ../release; ./olympia -z ../layouts/pipeout -i1 traces/dhry_riscv.zstf > /dev/null)
6+
@(cd ../fastdebug; ./olympia -z ../layouts/pipeout -i1 traces/dhry_riscv.zstf > /dev/null)
77
@./gen_alf.py -d pipeoutlocation.dat -a $*_core.alf
88
@rm pipeout*
99

0 commit comments

Comments
 (0)