use crate::common::{Orient, PinDirection, PropertyType, PropertyValue};
use crate::stream_parser::LefDefParseError;
use libreda_db::prelude as db;
use std::collections::BTreeMap;
use std::fmt;
use std::str::FromStr;
pub type MaskNum = u8;
pub type Coord = db::Coord;
#[derive(Clone, Debug)]
pub struct DEF {
pub version: Option<String>,
pub busbitchars: (char, char),
pub dividerchar: char,
pub design_name: Option<String>,
pub technology: Option<String>,
pub units: u32,
pub history: Vec<String>,
pub property_definitions: BTreeMap<String, DEFPropertyDefinition>,
pub die_area: Option<db::SimpleRPolygon<Coord>>,
pub rows: BTreeMap<String, Row>,
pub tracks: Vec<Tracks>,
pub gcell_grid: Vec<()>,
pub vias: BTreeMap<String, ViaDefinition>,
pub styles: Vec<()>,
pub nondefault_rules: (),
pub regions: BTreeMap<String, Region>,
pub components: Vec<Component>,
pub pins: Vec<Pin>,
pub pin_properties: (),
pub blockages: Vec<Blockage>,
pub slots: (),
pub fills: (),
pub special_nets: BTreeMap<String, ()>,
pub nets: Vec<Net>,
pub scan_chains: (),
pub groups: BTreeMap<String, Vec<Group>>,
pub extensions: (),
}
impl Default for DEF {
fn default() -> Self {
DEF {
version: Some("5.8".into()),
busbitchars: ('[', ']'),
dividerchar: '/',
design_name: None,
technology: None,
units: 0,
history: Default::default(),
property_definitions: Default::default(),
die_area: Default::default(),
rows: Default::default(),
tracks: Default::default(),
gcell_grid: Default::default(),
vias: Default::default(),
styles: Default::default(),
nondefault_rules: Default::default(),
regions: Default::default(),
components: Default::default(),
pins: Default::default(),
pin_properties: Default::default(),
blockages: Default::default(),
slots: Default::default(),
fills: Default::default(),
special_nets: Default::default(),
nets: Default::default(),
scan_chains: Default::default(),
groups: Default::default(),
extensions: Default::default(),
}
}
}
#[derive(Clone, Debug)]
pub enum SpacingOrDesignRuleWidth {
MinSpacing(Coord),
DesignRuleWidth(Coord),
}
#[derive(Clone, Debug)]
pub enum Blockage {
PlacementBlockage(PlacementBlockage),
LayerBlockage(LayerBlockage),
}
#[derive(Clone, Debug)]
pub enum RectOrPolygon {
Rect(db::Rect<Coord>),
Polygon(db::SimplePolygon<Coord>),
}
#[derive(Clone, Debug, Default)]
pub struct LayerBlockage {
pub layer: String,
pub slots: bool,
pub fills: bool,
pub pushdown: bool,
pub except_pg_net: bool,
pub component: Option<String>,
pub spacing: Option<Coord>,
pub spacing_or_designrule_width: Option<SpacingOrDesignRuleWidth>,
pub mask_num: Option<MaskNum>,
pub blockage_shapes: Vec<RectOrPolygon>,
}
#[derive(Clone, Debug)]
pub enum PlacementBlockageType {
Soft,
Partial(f64),
}
#[derive(Clone, Debug, Default)]
pub struct PlacementBlockage {
pub blockage_type: Option<PlacementBlockageType>,
pub pushdown: bool,
pub component: Option<String>,
pub rects: Vec<db::Rect<Coord>>,
}
#[derive(Clone, Debug)]
pub struct DEFPropertyDefinition {
pub object_type: DEFPropertyObjectType,
pub property_type: PropertyType,
pub range: Option<(PropertyValue, PropertyValue)>,
pub default_value: Option<PropertyValue>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DEFPropertyObjectType {
Component,
ComponentPin,
Design,
Group,
Net,
NonDefaultRule,
Region,
Row,
SpecialNet,
}
impl FromStr for DEFPropertyObjectType {
type Err = ();
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"COMPONENT" => Ok(Self::Component),
"COMPONENTPIN" => Ok(Self::ComponentPin),
"DESIGN" => Ok(Self::Design),
"GROUP" => Ok(Self::Group),
"NET" => Ok(Self::Net),
"NONDEFAULTRULE" => Ok(Self::NonDefaultRule),
"REGION" => Ok(Self::Region),
"ROW" => Ok(Self::Row),
"SPECIALNET" => Ok(Self::SpecialNet),
_ => Err(()),
}
}
}
impl fmt::Display for DEFPropertyObjectType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Component => f.write_str("COMPONENT"),
Self::ComponentPin => f.write_str("COMPONENTPIN"),
Self::Design => f.write_str("DESIGN"),
Self::Group => f.write_str("GROUP"),
Self::Net => f.write_str("NET"),
Self::NonDefaultRule => f.write_str("NONDEFAULTRULE"),
Self::Region => f.write_str("REGION"),
Self::Row => f.write_str("ROW"),
Self::SpecialNet => f.write_str("SPECIALNET"),
}
}
}
#[derive(Clone, Debug, Default)]
pub struct Component {
pub name: String,
pub model_name: String,
pub eeq_master: Option<String>,
pub source: ComponentSource,
pub position: Option<(db::Point<i32>, Orient, bool)>,
pub halo: Option<(bool, i32, i32, i32, i32)>,
pub route_halo: Option<(i32, String, String)>,
pub weight: u32,
pub region: Option<String>,
pub properties: BTreeMap<String, PropertyValue>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ComponentSource {
Netlist,
Dist,
User,
Timing,
}
impl Default for ComponentSource {
fn default() -> Self {
Self::Netlist
}
}
impl FromStr for ComponentSource {
type Err = ();
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"NETLIST" => Ok(Self::Netlist),
"DIST" => Ok(Self::Dist),
"USER" => Ok(Self::User),
"TIMING" => Ok(Self::Timing),
_ => Err(()),
}
}
}
impl fmt::Display for ComponentSource {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Netlist => f.write_str("NETLIST"),
Self::Dist => f.write_str("DIST"),
Self::User => f.write_str("USER"),
Self::Timing => f.write_str("TIMING"),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum NetSource {
Dist,
Netlist,
Test,
Timing,
User,
}
impl Default for NetSource {
fn default() -> Self {
Self::Netlist
}
}
impl FromStr for NetSource {
type Err = ();
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"DIST" => Ok(Self::Dist),
"NETLIST" => Ok(Self::Netlist),
"TEST" => Ok(Self::Test),
"TIMING" => Ok(Self::Timing),
"USER" => Ok(Self::User),
_ => Err(()),
}
}
}
impl fmt::Display for NetSource {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Dist => f.write_str("DIST"),
Self::Netlist => f.write_str("NETLIST"),
Self::Test => f.write_str("TEST"),
Self::Timing => f.write_str("TIMING"),
Self::User => f.write_str("USER"),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum NetPattern {
Balanced,
Steiner,
Trunk,
WiredLogic,
}
impl Default for NetPattern {
fn default() -> Self {
Self::Steiner
}
}
impl FromStr for NetPattern {
type Err = ();
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"BALANCED" => Ok(Self::Balanced),
"STEINER" => Ok(Self::Steiner),
"TRUNK" => Ok(Self::Trunk),
"WIREDLOGIC" => Ok(Self::WiredLogic),
_ => Err(()),
}
}
}
impl fmt::Display for NetPattern {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Balanced => f.write_str("BALANCED"),
Self::Steiner => f.write_str("STEINER"),
Self::Trunk => f.write_str("TRUNK"),
Self::WiredLogic => f.write_str("WIREDLOGIC"),
}
}
}
#[derive(Clone, Debug)]
pub enum NetTerminal {
ComponentPin {
component_name: String,
pin_name: String,
},
IoPin(String),
}
#[derive(Clone, Debug)]
pub struct Mustjoin {
pub component_name: String,
pub pin_name: String,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum WiringClass {
COVER,
FIXED,
ROUTED,
NOSHIELD,
}
impl FromStr for WiringClass {
type Err = ();
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"COVER" => Ok(Self::COVER),
"FIXED" => Ok(Self::FIXED),
"ROUTED" => Ok(Self::ROUTED),
"NOSHIELD" => Ok(Self::NOSHIELD),
_ => Err(()),
}
}
}
impl fmt::Display for WiringClass {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::COVER => f.write_str("COVER"),
Self::FIXED => f.write_str("FIXED"),
Self::ROUTED => f.write_str("ROUTED"),
Self::NOSHIELD => f.write_str("NOSHIELD"),
}
}
}
#[derive(Clone, Debug)]
pub enum RegularWiringElement {
Point {
x: Coord,
y: Coord,
ext_value: Option<Coord>,
},
Via {
via_name: String,
},
MaskNum(u32),
ViaMaskNum(ViaMaskNum),
Virtual {
x: Coord,
y: Coord,
},
Rect(),
}
#[derive(Clone, Debug)]
pub enum RoutingPoint {
Point {
point: db::Point<Coord>,
ext_value: Option<Coord>,
mask_num: Option<MaskNum>,
},
Via {
via_name: String,
orient: Option<Orient>,
via_mask_num: Option<ViaMaskNum>,
},
Rect {
rect: db::Rect<Coord>,
mask_num: Option<MaskNum>,
},
Virtual(db::Point<Coord>),
}
#[derive(Clone, Debug)]
pub struct RegularWiringStatement {
pub start_layer_name: String,
pub taper_rule: Option<String>,
pub style_num: u32,
pub routing_points: Vec<RoutingPoint>,
}
#[derive(Clone, Debug)]
pub struct RegularWiring {
pub class: WiringClass,
pub wiring: Vec<RegularWiringStatement>,
}
#[derive(Clone, Debug)]
pub struct Net {
pub name: Option<String>,
pub mustjoin: Option<Mustjoin>,
pub terminals: Vec<NetTerminal>,
pub shield_nets: Vec<String>,
vpin: BTreeMap<String, ()>,
subnets: BTreeMap<String, ()>,
pub xtalk_class: u16,
pub non_default_rule: Option<String>,
pub regular_wiring: Vec<RegularWiring>,
pub source: NetSource,
pub fixed_bump: bool,
pub frequency: Option<f64>,
pub original: Option<String>,
pub net_use: DEFSignalUse,
pub pattern: NetPattern,
pub est_cap: Option<f64>,
pub weight: u32,
pub properties: BTreeMap<String, PropertyValue>,
}
impl Default for Net {
fn default() -> Self {
Net {
name: Default::default(),
mustjoin: Default::default(),
terminals: Default::default(),
shield_nets: Default::default(),
vpin: Default::default(),
subnets: Default::default(),
xtalk_class: Default::default(),
non_default_rule: Default::default(),
regular_wiring: Default::default(),
source: Default::default(),
fixed_bump: Default::default(),
frequency: Default::default(),
original: Default::default(),
net_use: Default::default(),
pattern: Default::default(),
est_cap: Default::default(),
weight: 1,
properties: Default::default(),
}
}
}
#[derive(Clone, Debug, Default)]
pub struct SpecialNet {}
#[derive(Clone, Debug, Default)]
pub struct Pin {
pub pin_name: String,
pub net_name: String,
pub special: bool,
pub direction: Option<PinDirection>,
pub net_expr: Option<String>,
pub supply_sensitivity: Option<String>,
pub ground_sensitivity: Option<String>,
pub signal_use: DEFSignalUse,
pub antenna_rules: (),
pub ports: Vec<PinPort>,
}
#[derive(Clone, Debug, Default)]
pub struct PinPort {
pub port_statements: Vec<PinPortStatement>,
}
#[derive(Clone, Debug)]
pub enum PinPortStatement {
Layer {
layer_name: String,
mask_num: Option<MaskNum>,
spacing_or_width: Option<SpacingOrDesignRuleWidth>,
rect: db::Rect<Coord>,
},
Polygon {
layer_name: String,
mask_num: Option<MaskNum>,
spacing_or_width: Option<SpacingOrDesignRuleWidth>,
polygon: db::SimplePolygon<Coord>,
},
Via {
via_name: String,
mask_num: Option<ViaMaskNum>,
location: db::Point<Coord>,
},
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DEFSignalUse {
SIGNAL,
POWER,
GROUND,
CLOCK,
TIEOFF,
ANALOG,
SCAN,
RESET,
}
impl Default for DEFSignalUse {
fn default() -> Self {
Self::SIGNAL
}
}
impl FromStr for DEFSignalUse {
type Err = ();
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"SIGNAL" => Ok(Self::SIGNAL),
"POWER" => Ok(Self::POWER),
"GROUND" => Ok(Self::GROUND),
"CLOCK" => Ok(Self::CLOCK),
"TIEOFF" => Ok(Self::TIEOFF),
"ANALOG" => Ok(Self::ANALOG),
"SCAN" => Ok(Self::SCAN),
"RESET" => Ok(Self::RESET),
_ => Err(()),
}
}
}
impl fmt::Display for DEFSignalUse {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::SIGNAL => f.write_str("SIGNAL"),
Self::POWER => f.write_str("POWER"),
Self::GROUND => f.write_str("GROUND"),
Self::CLOCK => f.write_str("CLOCK"),
Self::TIEOFF => f.write_str("TIEOFF"),
Self::ANALOG => f.write_str("ANALOG"),
Self::SCAN => f.write_str("SCAN"),
Self::RESET => f.write_str("RESET"),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct ViaMaskNum {
pub top_mask_num: MaskNum,
pub cut_mask_num: MaskNum,
pub bottom_mask_num: MaskNum,
}
impl FromStr for ViaMaskNum {
type Err = LefDefParseError;
fn from_str(input: &str) -> Result<Self, Self::Err> {
if input.len() != 3 {
Err(LefDefParseError::InvalidLiteral(input.to_string()))
} else {
Ok(Self {
top_mask_num: MaskNum::from_str_radix(&input[0..1], 16)?,
cut_mask_num: MaskNum::from_str_radix(&input[1..2], 16)?,
bottom_mask_num: MaskNum::from_str_radix(&input[2..3], 16)?,
})
}
}
}
impl fmt::Display for ViaMaskNum {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{:#0x}{:#0x}{:#0x}",
self.top_mask_num, self.cut_mask_num, self.bottom_mask_num
)
}
}
#[derive(Clone, Debug, Default)]
pub struct Region {
pub regions: Vec<db::Rect<Coord>>,
pub region_type: Option<RegionType>,
pub properties: (),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum RegionType {
Fence,
Guide,
}
impl FromStr for RegionType {
type Err = ();
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"FENCE" => Ok(Self::Fence),
"GUIDE" => Ok(Self::Guide),
_ => Err(()),
}
}
}
impl fmt::Display for RegionType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Fence => f.write_str("FENCE"),
Self::Guide => f.write_str("GUIDE"),
}
}
}
#[derive(Clone, Debug, Default)]
pub struct Group {
pub component_names: Vec<String>,
pub region_name: Option<String>,
pub properties: BTreeMap<String, PropertyValue>,
}
#[derive(Clone, Debug, Default)]
pub struct Row {
pub site_name: String,
pub orig: (Coord, Coord),
pub site_orient: Orient,
pub step_pattern: RowStepPattern,
pub properties: BTreeMap<String, PropertyValue>,
}
#[derive(Clone, Debug)]
pub struct RowStepPattern {
pub num_x: u32,
pub num_y: u32,
pub step: Option<(Coord, Coord)>,
}
impl Default for RowStepPattern {
fn default() -> Self {
Self {
num_x: 1,
num_y: 1,
step: None,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct Tracks {
pub is_horizontal: bool,
pub start: Coord,
pub num_tracks: u32,
pub step: Coord,
pub mask: Option<(MaskNum, bool)>,
pub layers: Vec<String>,
}
#[derive(Clone, Debug)]
pub enum ViaDefinition {
ViaGeometry(Vec<ViaGeometry>),
ViaRule,
}
#[derive(Clone, Debug)]
pub struct ViaGeometry {
pub layer: String,
pub mask_num: Option<MaskNum>,
pub shape: RectOrPolygon,
}
#[derive(Clone, Debug)]
pub struct ViaRule {
pub cut_size: (Coord, Coord),
pub bot_metal_layer: String,
pub cut_layer: String,
pub top_metal_layer: String,
pub cut_spacing: (Coord, Coord),
pub enclosure: (Coord, Coord, Coord, Coord),
num_cut_rows: u32,
num_cut_cols: u32,
origin: db::Point<Coord>,
offset: (),
cut_pattern: (),
}