celox_runtime/
scheduler.rs1use crate::{
2 SignalRef,
3 backend::{EventHandle, SimBackend},
4};
5use std::collections::BinaryHeap;
6
7#[derive(Debug, Clone)]
8pub struct ClockDef {
9 pub period: u64,
10}
11
12#[derive(Debug, Clone)]
13pub struct SimEvent<B: SimBackend> {
14 pub time: u64,
15 pub event_ref: B::Event,
16 pub signal: SignalRef,
17 pub next_val: u8,
18}
19
20impl<B: SimBackend> PartialEq for SimEvent<B> {
21 fn eq(&self, other: &Self) -> bool {
22 self.time == other.time
23 && self.event_ref.addr() == other.event_ref.addr()
24 && self.signal == other.signal
25 && self.next_val == other.next_val
26 }
27}
28
29impl<B: SimBackend> Eq for SimEvent<B> {}
30
31impl<B: SimBackend> PartialOrd for SimEvent<B> {
32 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
33 Some(self.cmp(other))
34 }
35}
36
37impl<B: SimBackend> Ord for SimEvent<B> {
38 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
39 other
41 .time
42 .cmp(&self.time)
43 .then_with(|| {
44 let id1 = self.event_ref.id();
45 let id2 = other.event_ref.id();
46 id2.cmp(&id1)
47 })
48 .then_with(|| other.signal.cmp(&self.signal))
49 }
50}
51
52pub struct Scheduler<B: SimBackend> {
53 pub time: u64,
54 pub clocks: Vec<Option<ClockDef>>,
55 pub event_queue: BinaryHeap<SimEvent<B>>,
56}
57
58impl<B: SimBackend> Scheduler<B> {
59 pub fn new() -> Self {
60 Self {
61 time: 0,
62 clocks: Vec::new(),
63 event_queue: BinaryHeap::new(),
64 }
65 }
66
67 pub fn next_event_time(&self) -> Option<u64> {
68 self.event_queue.peek().map(|e| e.time)
69 }
70
71 pub fn push(&mut self, event: SimEvent<B>) {
72 self.event_queue.push(event);
73 }
74
75 pub fn pop_all_at_next_time(&mut self) -> Option<(u64, Vec<SimEvent<B>>)> {
76 let next_time = self.next_event_time()?;
77 let mut events = Vec::new();
78 while let Some(ev) = self.event_queue.peek() {
79 if ev.time == next_time {
80 events.push(self.event_queue.pop().unwrap());
81 } else {
82 break;
83 }
84 }
85 Some((next_time, events))
86 }
87}
88
89impl<B: SimBackend> Default for Scheduler<B> {
90 fn default() -> Self {
91 Self::new()
92 }
93}