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§
- LEFDesign
Rule Adapter - Provides standardized read access to the design-rules defined in a LEF structure.
Enums§
- LefDef
Parse Error - Error while parsing LEF or DEF. TODO: Separate lexer errors from LEF/DEF specific errors.