mod crossbar;
mod routed;
mod topology;
pub use crossbar::Crossbar;
pub use routed::RoutedNetwork;
pub use topology::{Hypercube, Mesh2D, NetworkTopology, Ring};
use crate::common::CoreId;
use crate::sim::packet::coherence::{CoherenceMsg, Node};
use crate::sim::stats::Stats;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TopologyInfo {
pub kind: &'static str,
pub endpoints: usize,
pub nodes: usize,
pub diameter: usize,
}
pub trait Interconnect: Send + Sync + std::fmt::Debug {
fn send(&mut self, now: u64, from: Node, msg: CoherenceMsg);
fn tick(&mut self, now: u64, stats: &mut Stats, deliver: &mut dyn FnMut(Node, CoherenceMsg));
fn is_idle(&self) -> bool;
fn is_quiet(&self, _now: u64) -> bool {
self.is_idle()
}
fn topology(&self) -> TopologyInfo;
}
#[must_use]
pub const fn port_of(node: Node, cores: usize) -> usize {
match node {
Node::Core(core) => core.as_index(),
Node::Home => cores,
}
}
#[must_use]
pub fn node_of(port: usize, cores: usize) -> Node {
if port == cores {
Node::Home
} else {
Node::Core(CoreId::new(u32::try_from(port).unwrap_or(u32::MAX)))
}
}
#[derive(Clone, Copy, Debug)]
struct Queued {
msg: CoherenceMsg,
arrived: u64,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct InFlight {
deliver_at: u64,
seq: u64,
to: Node,
msg: CoherenceMsg,
}
impl PartialOrd for InFlight {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for InFlight {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
(self.deliver_at, self.seq).cmp(&(other.deliver_at, other.seq))
}
}