MCPcopy Create free account
hub / github.com/LPC4/Full-Stack / tick

Method tick

crates/virtual-machine/src/cpu/pipeline.rs:257–426  ·  view source on GitHub ↗

Advance every pipeline stage by one cycle. Stages execute in reverse order (WB -> MEM -> EX -> ID -> IF) so each stage can pass its results forward within the same cycle.

(&mut self, bus: &mut SystemBus)

Source from the content-addressed store, hash-verified

255 let snap_id_entry: StageEntry = self.if_id.as_ref().map(|r| {
256 let mnem = decode_insn(r.raw).map(|i| i.mnemonic()).unwrap_or("???");
257 (r.pc, mnem)
258 });
259
260 let old_mem_wb = self.mem_wb.take();
261 let old_ex_mem = self.ex_mem.take();
262 let old_id_ex = self.id_ex.take();
263 let old_if_id = self.if_id.take();
264
265 // ---- WB stage -------------------------------------------------------
266 let wb_outcome = self.stage_wb(old_mem_wb.as_ref(), bus)?;
267 match wb_outcome {
268 TickOutcome::Halted(code) => return Ok(TickOutcome::Halted(code)),
269 TickOutcome::EcallSquash => {
270 self.flush_pipeline();
271 return Ok(TickOutcome::Continue);
272 }
273 TickOutcome::Continue => {}
274 }
275
276 if self.memory_wait_cycles > 0 {
277 self.memory_wait_cycles -= 1;
278 self.if_id = old_if_id;
279 self.id_ex = old_id_ex;
280 self.ex_mem = old_ex_mem;
281 if self.memory_wait_cycles == 0 {
282 self.mem_wb = self.pending_mem_wb.take();
283 }
284 self.stats.stall_cycles += 1;
285 self.stats.memory_stall_cycles += 1;
286 self.last_cycle = CpuPipelineFeed {
287 stages: [
288 snap_id_entry,
289 snap_id_entry,
290 snap_ex_entry,
291 snap_mem_entry,
292 snap_wb_entry,
293 ],
294 stalled: true,
295 flushed: false,
296 };
297 return Ok(TickOutcome::Continue);
298 }
299
300 // ---- Interrupt check (precise: after WB retires, before MEM executes) ----
301 // In-flight instructions (old_ex_mem, old_id_ex, old_if_id) are squashed if
302 // an interrupt fires; their pipeline registers are already taken out of self.
303 if let Some((irq_cause, irq_tval, irq_pc)) = self.check_pending_interrupt() {
304 // old_ex_mem / old_id_ex / old_if_id drop here - no memory side-effects yet.
305 self.take_trap(irq_cause, irq_tval, irq_pc);
306 self.last_cycle = CpuPipelineFeed {
307 stages: [
308 None,
309 snap_id_entry,
310 snap_ex_entry,
311 snap_mem_entry,
312 snap_wb_entry,
313 ],
314 stalled: false,

Callers 1

runMethod · 0.45

Calls 15

load_use_hazardFunction · 0.85
increment_cycleMethod · 0.80
clint_mutMethod · 0.80
timer_irq_pendingMethod · 0.80
software_irq_pendingMethod · 0.80
rx_irq_pendingMethod · 0.80
uart_mutMethod · 0.80
set_irqMethod · 0.80
plic_mutMethod · 0.80
next_irqMethod · 0.80
stage_wbMethod · 0.80
flush_pipelineMethod · 0.80

Tested by

no test coverage detected