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 .then_with(|| other.next_val.cmp(&self.next_val))
50 }
51}
52
53pub struct Scheduler<B: SimBackend> {
54 pub time: u64,
55 pub clocks: Vec<Option<ClockDef>>,
56 pub event_queue: BinaryHeap<SimEvent<B>>,
57}
58
59impl<B: SimBackend> Scheduler<B> {
60 pub fn new() -> Self {
61 Self {
62 time: 0,
63 clocks: Vec::new(),
64 event_queue: BinaryHeap::new(),
65 }
66 }
67
68 pub fn next_event_time(&self) -> Option<u64> {
69 self.event_queue.peek().map(|e| e.time)
70 }
71
72 pub fn push(&mut self, event: SimEvent<B>) {
73 self.event_queue.push(event);
74 }
75
76 pub fn pop_all_at_next_time(&mut self) -> Option<(u64, Vec<SimEvent<B>>)> {
77 let next_time = self.next_event_time()?;
78 let mut events = Vec::new();
79 while let Some(ev) = self.event_queue.peek() {
80 if ev.time == next_time {
81 events.push(self.event_queue.pop().unwrap());
82 } else {
83 break;
84 }
85 }
86 Some((next_time, events))
87 }
88}
89
90impl<B: SimBackend> Default for Scheduler<B> {
91 fn default() -> Self {
92 Self::new()
93 }
94}