use parking_lot::RwLock;
use std::collections::{HashMap, HashSet};
use std::ops::RangeFrom;
use std::sync::Arc;
use indexmap::IndexMap;
use crate::mod_def::dtypes::{PhysicalPin, VerilogImport};
use crate::mod_def::tracks::{TrackDefinitions, TrackOccupancies};
use crate::connection::PortSliceConnections;
use crate::{IO, Metadata, Usage};
type PhysicalPinMap = IndexMap<String, Vec<Option<PhysicalPin>>>;
type MaxDistanceMap = IndexMap<String, Vec<Option<i64>>>;
pub struct ModDefCore {
pub(crate) name: String,
pub(crate) ports: IndexMap<String, IO>,
pub(crate) interfaces: IndexMap<String, IndexMap<String, (String, usize, usize)>>,
pub(crate) instances: IndexMap<String, Arc<RwLock<ModDefCore>>>,
pub(crate) usage: Usage,
pub(crate) verilog_import: Option<VerilogImport>,
pub(crate) parameters: IndexMap<String, crate::mod_def::ParameterSpec>,
pub(crate) mod_inst_connections:
IndexMap<String, IndexMap<String, Arc<RwLock<PortSliceConnections>>>>,
pub(crate) mod_def_connections: IndexMap<String, Arc<RwLock<PortSliceConnections>>>,
pub(crate) enum_ports: IndexMap<String, String>,
pub(crate) mod_def_metadata: Metadata,
pub(crate) mod_def_port_metadata: HashMap<String, Metadata>,
pub(crate) mod_def_intf_metadata: HashMap<String, Metadata>,
pub(crate) mod_inst_metadata: HashMap<String, Metadata>,
pub(crate) mod_inst_port_metadata: HashMap<String, HashMap<String, Metadata>>,
pub(crate) mod_inst_intf_metadata: HashMap<String, HashMap<String, Metadata>>,
pub(crate) shape: Option<crate::mod_def::dtypes::Polygon>,
pub(crate) layer: Option<String>,
pub(crate) inst_placements: IndexMap<String, crate::mod_def::dtypes::Placement>,
pub(crate) physical_pins: PhysicalPinMap,
pub(crate) port_max_distances: MaxDistanceMap,
pub(crate) track_definitions: Option<TrackDefinitions>,
pub(crate) track_occupancies: Option<TrackOccupancies>,
pub(crate) default_connection_max_distance: Option<i64>,
pub(crate) specified_net_names: HashSet<String>,
pub(crate) pipeline_counter: RangeFrom<usize>,
}
impl ModDefCore {
pub fn get_physical_pin(&self, port_name: &str, bit: usize) -> PhysicalPin {
let pins = self.physical_pins.get(port_name).unwrap_or_else(|| {
panic!(
"Physical pins for port {}.{} not defined",
self.name, port_name
)
});
if bit >= pins.len() {
panic!(
"Bit {} out of range for port {}.{} (width {})",
bit,
self.name,
port_name,
pins.len()
);
}
pins[bit]
.as_ref()
.unwrap_or_else(|| {
panic!(
"Physical pin for {}.{}[{}] is not placed",
self.name, port_name, bit
)
})
.clone()
}
}