Crate libreda_lefdef

Source
Expand description

LEF and DEF input/output for the LibrEDA framework.

LEF and DEF have their own data structures which are kept very close to the both file formats. The import module provides functions to convert LEF and DEF structures into a type which supports the L2NEdit trait. Similar the export module helps converting L2NBase types into DEF structures.

§Current limitations

Currently there’s no writer implemented for LEF because normally place and route tools will not modify the LEF file. There was just no need yet.

Data import from LEF and DEF is quite minimal yet. From DEF there is no routing information being imported. Currently, design import from DEF is only useful as input for placment and routing but not for post-routing stages.

§Examples

§Read and import a LEF File

use std::fs::File;
use std::io::BufReader;
use libreda_lefdef::lef_parser;

// Open a LEF file.
let f = File::open("./tests/data/lef_examples/freepdk45/gscl45nm.lef").unwrap();
// Create a buffered reader for faster reading.
let mut buf = BufReader::new(f);

// Read the LEF data.
let result = lef_parser::read_lef_bytes(&mut buf);

if result.is_err() {
    // Handle IO errors and parsing errors.
    println!("Failed to parse LEF: {:?}", result);
}

// Access the LEF structure.
let lef = result.expect("Failed to parse LEF.");

// Import a LEF library into the DB format.
use libreda_lefdef::import;
use libreda_lefdef::libreda_db::prelude::*;
let mut chip = Chip::new();
let import_options = import::LEFImportOptions::default();
import::import_lef_into_db(&import_options, &lef, &mut chip)
  .expect("Failed to import LEF.");

§Read and import a DEF File

use std::fs::File;
use std::io::BufReader;
use libreda_lefdef::def_parser;

// Open a DEF file.
let f = File::open("./tests/data/def_examples/dummy.def").unwrap();
// Create a buffered reader for faster reading.
let mut buf = BufReader::new(f);

// Read the LEF data.
let result = def_parser::read_def_bytes(&mut buf);

if result.is_err() {
    // Handle IO errors and parsing errors.
    println!("Failed to parse DEF: {:?}", result);
}

// Access the DEF structure.
let def = result.expect("Failed to parse DEF.");

// Import a DEF design into the DB format.
// Note that in this example the DEF file does not contain any components (cell instances)
// because otherwise this example would require to also import a (LEF) library first.
use libreda_lefdef::import;
use libreda_lefdef::libreda_db::prelude::*;
// Create an empty layout.
let mut chip = Chip::new();

let mut import_options = import::DEFImportOptions::default();
// Disable import of wiring for the sake of simplicity.
// This way, a LEF structure is not necessary during the DEF import.
import_options.import_wiring = false;

// Start the import.
import::import_def_into_db(&import_options, None, &def, &mut chip)
  .expect("Failed to import DEF.");

§Export to DEF

Designs can be exported to DEF. However, DEF has a flat hierarchy and supports only a top-level design with child instances, called ‘components’. A design must eventually be flattened before exported to DEF.

The export to DEF first creates a DEF data-structure which can then be serialized.

use libreda_lefdef::libreda_db::prelude::*;
use libreda_lefdef::DEF;
use libreda_lefdef::export::{export_db_to_def, DEFExportOptions};

// Create a design to be exported.
let mut chip = Chip::new();
let outline_layer = chip.create_layer(1, 0); // Outline layer is necessary for exporting to DEF.

// The design must contain at least one cell, which will be the top-level.
let top = chip.create_cell("TOP".into());
// Create cell outline.
chip.insert_shape(&top, &outline_layer, Rect::new((0, 0), (10, 10)).into());

// Populate a DEF structure with the data from the `chip`.
let mut def = DEF::default();
let mut options = DEFExportOptions::default();
options.outline_layer = Some(outline_layer);
// Do the conversion.
let result = export_db_to_def(&options, &chip, &top, &mut def);
assert!(result.is_ok()); // Handle errors.

§Write DEF

A DEF structure can be serialized into the DEF format.

use libreda_lefdef::DEF;
use libreda_lefdef::def_writer::*;

// Create a new empty DEF.
let mut def = DEF::default();
// Fill it with data. Consider using the export functions for this.
def.design_name = Some("MyDesign".to_string());

// Serialize to a 'writer'. This can be any type implementing the `Write` trait.
let mut buffer: Vec<u8> = Vec::new();
let result = write_def(&mut buffer, &def);
assert!(result.is_ok()); // Handle errors.

Re-exports§

pub use def_ast::DEF;
pub use lef_ast::LEF;
pub use crate::def_parser::DEFReaderConfig;
pub use crate::def_writer::DEFWriterError;
pub use libreda_db;

Modules§

common
Data types and parser functions used for both LEF and DEF.
def_ast
Data types specific to DEF.
def_parser
Parser for DEF (Design Exchange Format).
def_writer
Write DEF data structure into DEF file format.
export
Export libreda-db structures to LEF and DEF.
import
Import LEF and DEF structures by populating data base structures.
lef_ast
Data types that are used to populate the LEF data structure.
lef_parser
Parser for LEF data streams.

Structs§

LEFDesignRuleAdapter
Provides standardized read access to the design-rules defined in a LEF structure.

Enums§

LefDefParseError
Error while parsing LEF or DEF. TODO: Separate lexer errors from LEF/DEF specific errors.