reda-lib 0.4.0

Liberty file library
Documentation
use reda_lib_macro::model;
use crate::{lib_enum, model::LibPin};

use super::{LibExpr, LibPinDirection};

#[model]
#[derive(Debug, Clone, Default)]
pub struct LibCell {
    pub name: String,

    pub area: Option<f64>,
    pub drive_strength: Option<usize>,
    pub cell_leakage_power: Option<f64>,

    pub leakage_powers: Vec<LibLeakagePower>,
    pub pins: Vec<LibPin>,
    pub pg_pins: Vec<LibPgPin>,
}

#[model]
#[derive(Debug, Clone, Default)]
pub struct LibPgPin {
    pub name: String,
    pub voltage_name: String,
    pub pg_type: LibPgType,  
    pub user_pg_type: Option<String>,
    pub physical_connection: Option<LibPhysicalConnection>,
}

#[model]
#[derive(Debug, Clone)]
pub struct LibFF {
    pub names: Vec<String>,
    pub clear: LibExpr,
    pub clear_preset_var1: LibClearPresetVar,
    pub clear_preset_var2: LibClearPresetVar,
    pub clocked_on: LibExpr,
    pub clocked_on_also: LibExpr,
    pub next_state: LibExpr,
    pub preset: LibExpr,
}

lib_enum!(LibDontFault, 
    Sa0,
    Sa1,
    Sa01,
);

lib_enum!(LibFpgaCellType, 
    Sa0,
    Sa1,
    Sa01,
);

lib_enum!(LibClearPresetVar,
    rising_edge_clock_cell, falling_edge_clock_cell
);

lib_enum!(LibPgType, 
    primary_power, 
    primary_ground, 
    backup_power, 
    backup_ground, 
    internal_power, 
    internal_ground, 
    pwell, 
    nwell, 
    deepnwell, 
    deeppwell
);

lib_enum!(LibPhysicalConnection,
    device_layer,
    routing_pin,
);

#[model]
#[derive(Debug, Clone)]
pub struct LibLeakagePower {
    pub when: LibExpr,
    pub value: f64,
}

impl LibCell {
    pub fn new<S: Into<String>>(name: S) -> Self {
        Self { 
            name: name.into(),
            ..Default::default()
        }
    }

    pub fn pin(&self, name: &str) -> Option<&LibPin> {
        self.pins.iter().find(|p| p.name == name)
    }

    pub fn input_pins(&self) -> impl Iterator<Item = &LibPin> {
        self.pins.iter()
            .filter(|pin| {
                pin.direction == LibPinDirection::Input
            })
    } 

    pub fn output_pins(&self) -> impl Iterator<Item = &LibPin> {
        self.pins.iter()
            .filter(|pin| {
                pin.direction == LibPinDirection::Output
            })
    }

    pub fn get_pin(&self, name: &str) -> Option<&LibPin> {
        self.pins.iter()
            .find(|pin| pin.name == name)
    }

    pub fn get_pg_pin(&self, name: &str) -> Option<&LibPgPin> {
        self.pg_pins.iter()
            .find(|pin| pin.name == name)
    }
}