pub mod fabric;
pub mod home;
pub mod interconnect;
pub mod protocol;
pub mod stats;
pub use fabric::{CoherenceFabric, FabricLayout};
pub use protocol::{CoherenceProtocol, Mesi};
use crate::config::{
CoherenceConfig, CoherenceProtocolConfig, HomeAgentConfig, InterconnectConfig,
};
use crate::sim::components::ComponentId;
use home::{Broadcast, HomeAgent, SnoopFilter};
use interconnect::{Crossbar, Hypercube, Interconnect, Mesh2D, Ring, RoutedNetwork};
use stats::CoherenceStatPaths;
#[derive(Clone, Copy, Debug)]
pub struct FabricGeometry {
pub line_bytes: usize,
pub private_l2_lines: usize,
}
#[must_use]
pub fn build(
config: &CoherenceConfig,
geometry: FabricGeometry,
llc: ComponentId,
agents: Vec<ComponentId>,
) -> CoherenceFabric {
let cores = agents.len();
let stat_paths = CoherenceStatPaths::new();
let protocol: Box<dyn CoherenceProtocol> = match config.protocol {
CoherenceProtocolConfig::Mesi => Box::new(Mesi),
};
let tracking: Box<dyn HomeAgent> = match config.home_agent {
HomeAgentConfig::Broadcast => Box::new(Broadcast),
HomeAgentConfig::SnoopFilter { capacity_factor, ways } => {
let entries =
(geometry.private_l2_lines as f64 * capacity_factor.max(0.0)).ceil() as usize;
Box::new(SnoopFilter::new(entries.max(ways), ways, geometry.line_bytes as u64))
}
};
let paths = stat_paths.interconnect;
let interconnect: Box<dyn Interconnect> = match config.interconnect {
InterconnectConfig::Crossbar { hop_latency, bytes_per_cycle } => {
Box::new(Crossbar::new(cores, geometry.line_bytes, hop_latency, bytes_per_cycle, paths))
}
InterconnectConfig::Ring { hop_latency, bytes_per_cycle } => Box::new(RoutedNetwork::new(
Ring::new(cores + 1),
cores,
geometry.line_bytes,
hop_latency,
bytes_per_cycle,
paths,
)),
InterconnectConfig::Mesh { hop_latency, bytes_per_cycle } => Box::new(RoutedNetwork::new(
Mesh2D::for_endpoints(cores + 1, false),
cores,
geometry.line_bytes,
hop_latency,
bytes_per_cycle,
paths,
)),
InterconnectConfig::Torus { hop_latency, bytes_per_cycle } => Box::new(RoutedNetwork::new(
Mesh2D::for_endpoints(cores + 1, true),
cores,
geometry.line_bytes,
hop_latency,
bytes_per_cycle,
paths,
)),
InterconnectConfig::Hypercube { hop_latency, bytes_per_cycle } => {
Box::new(RoutedNetwork::new(
Hypercube::for_endpoints(cores + 1),
cores,
geometry.line_bytes,
hop_latency,
bytes_per_cycle,
paths,
))
}
};
let layout = FabricLayout {
llc,
agents,
line_bytes: geometry.line_bytes,
txn_capacity: config.txn_entries,
};
CoherenceFabric::new(protocol, tracking, interconnect, layout, stat_paths)
}