|
6 | 6 |
|
7 | 7 | #include "sparta/utils/LogUtils.hpp" |
8 | 8 | #include "sparta/events/StartupEvent.hpp" |
| 9 | +#include "CoreUtils.hpp" |
9 | 10 |
|
10 | 11 | namespace olympia |
11 | 12 | { |
@@ -72,6 +73,7 @@ namespace olympia |
72 | 73 |
|
73 | 74 | void ROB::sendInitialCredits_() |
74 | 75 | { |
| 76 | + setupScoreboardView_() ; |
75 | 77 | out_reorder_buffer_credits_.send(reorder_buffer_.capacity()); |
76 | 78 | ev_ensure_forward_progress_.schedule(retire_timeout_interval_); |
77 | 79 | } |
@@ -188,13 +190,7 @@ namespace olympia |
188 | 190 | // This is rare for the example |
189 | 191 | if(SPARTA_EXPECT_FALSE(ex_inst.getPipe() == InstArchInfo::TargetPipe::SYS)) |
190 | 192 | { |
191 | | - ILOG("Instigating flush... " << ex_inst); |
192 | | - |
193 | | - FlushManager::FlushingCriteria criteria(FlushManager::FlushCause::POST_SYNC, ex_inst_ptr); |
194 | | - out_retire_flush_.send(criteria); |
195 | | - |
196 | | - ++num_flushes_; |
197 | | - break; |
| 193 | + retireSysInst_(ex_inst_ptr); |
198 | 194 | } |
199 | 195 | } |
200 | 196 | else { |
@@ -248,4 +244,54 @@ namespace olympia |
248 | 244 | } |
249 | 245 | } |
250 | 246 |
|
| 247 | + // sys instr doesn't have a pipe so we handle special stuff here |
| 248 | + void ROB::retireSysInst_(InstPtr &ex_inst) |
| 249 | + { |
| 250 | + auto reg_file = ex_inst->getRenameData().getDestination().rf; |
| 251 | + if (reg_file == core_types::RegFile::RF_INVALID) |
| 252 | + { // this is the case if dst = x0 |
| 253 | + DLOG("retiring SYS instr "); |
| 254 | + } else // this is needed or else destination register is |
| 255 | + { // forever reserved and not ready |
| 256 | + const auto & dest_bits = ex_inst->getDestRegisterBitMask(reg_file); |
| 257 | + scoreboard_views_[reg_file]->setReady(dest_bits); |
| 258 | + DLOG("retiring SYS inst dest reg bits: " << sparta::printBitSet(dest_bits)); |
| 259 | + } |
| 260 | + |
| 261 | + FlushManager::FlushingCriteria criteria(FlushManager::FlushCause::POST_SYNC, ex_inst); |
| 262 | + out_retire_flush_.send(criteria); |
| 263 | + expect_flush_ = true; |
| 264 | + ++num_flushes_; |
| 265 | + ILOG("Instigating flush due to SYS instruction... " << *ex_inst); |
| 266 | + |
| 267 | + |
| 268 | + } |
| 269 | + |
| 270 | + // for SYS instr which doesn't have an exe pipe |
| 271 | + void ROB::setupScoreboardView_() |
| 272 | + { |
| 273 | + std::string iq_name = "iq0"; // default name |
| 274 | + |
| 275 | + if (getContainer() != nullptr) |
| 276 | + { |
| 277 | + const auto exe_pipe_rename = |
| 278 | + olympia::coreutils::getPipeTopology(getContainer()->getParent(), "exe_pipe_rename"); |
| 279 | + if (exe_pipe_rename.size() > 0) |
| 280 | + iq_name = exe_pipe_rename[0][1]; // just grab the first issue queue |
| 281 | + } |
| 282 | + |
| 283 | + auto cpu_node = getContainer()->findAncestorByName("core.*"); |
| 284 | + if (cpu_node == nullptr) |
| 285 | + { |
| 286 | + cpu_node = getContainer()->getRoot(); |
| 287 | + } |
| 288 | + const auto& rf = core_types::RF_INTEGER; |
| 289 | + |
| 290 | + // alu0, alu1 name is based on exe names, point to issue_queue name instead |
| 291 | + DLOG("setup sb view: " << iq_name ); |
| 292 | + scoreboard_views_[rf].reset( |
| 293 | + new sparta::ScoreboardView(iq_name, core_types::regfile_names[rf], |
| 294 | + cpu_node)); // name needs to come from issue_queue |
| 295 | + } |
251 | 296 | } |
| 297 | + |
0 commit comments