Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proto2lef: convert VLSIR layout proto to LEF description #31

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions layout21converters/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ path = "src/lef2yaml.rs"
test = true
bench = false

# Converts VLSIR layout proto-format files to LEF descriptions using Layout21.
[[bin]]
name = "proto2lef"
path = "src/proto2lef.rs"
test = true
bench = false

[dependencies]
gds21 = {path = "../gds21"}
lef21 = {path = "../lef21"}
Expand Down
104 changes: 104 additions & 0 deletions layout21converters/src/proto2lef.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//! # proto2gds
//!
//! VLSIR protobuf schema (Layout) to LEF converter
//!

use clap::Parser;
use std::error::Error;
//use chrono::NaiveDateTime;
use gds21::GdsLibrary;
use layout21protos::conv as proto_converters;
use layout21protos::tech as protos;
use layout21raw as raw;
use raw::utils::Ptr;

// => The doc-comment on `ProgramOptions` here is displayed by the `clap`-generated help docs =>

/// LEF to Lef21 YAML Schema Converter
#[derive(Parser)]
struct ProgramOptions {
/// VLSIR Layout protobuf (binary) input file
#[clap(short = 'i', long, default_value = "")]
proto: String,
/// LEF output file
#[clap(short = 'o', long, default_value = "")]
lef: String,
/// VLSIR Technology protobuf (binary) input file
#[clap(short = 't', long, default_value = "")]
tech: String,
/// Verbose output mode
#[clap(short, long)]
verbose: bool,
}

/// The main entry point.
/// All logic is offloaded to `_main` for sake of testing.
fn main() -> Result<(), Box<dyn Error>> {
let options = ProgramOptions::parse();
_main(&options)
}

/// All the real logic, with `ProgramOptions` argument for sake of testing
fn _main(options: &ProgramOptions) -> Result<(), Box<dyn Error>> {
let proto_library = match proto_converters::open(&options.proto) {
Err(err) => panic!("Couldn't read layout protobuf: {}", err),
Ok(lib) => lib,
};

if options.verbose {
println!("read: {:?}", &options.proto);
}

let tech_library: protos::Technology = match proto_converters::open(&options.tech) {
Err(err) => panic!("Couldn't read tech protobuf: {}", err),
Ok(lib) => lib,
};

if options.verbose {
println!("read: {:?}", &options.tech);
}

let tech_layers = raw::data::Layers::from_proto(&tech_library)?;

if options.verbose {
println!("assembled technology {:?} layer mapping", tech_library.name);
}

let library = match raw::Library::from_proto(proto_library, Some(Ptr::new(tech_layers))) {
Err(err) => panic!("Couldn't load library from protobuf: {}", err),
Ok(lib) => lib,
};

//// Load LEF from file to a [LefLibrary]
// arya: returns a LayoutResult<lef21::LefLibrary>
let lef_library = layout21raw::lef::LefExporter::export(&library)?;

// arya: in lef21/src/write.rs; this returns LefResult<()>
lef21::save(&lef_library, &options.lef)?;

if options.verbose {
println!("wrote {:?}", &options.lef);
}

Ok(())
}

//#[cfg(test)]
//mod tests {
// use super::*;
//
// #[test]
// fn roundtrip_to_golden_file() -> Result<(), Box<dyn Error>> {
// // The golden file was created by running the program:
// // $ cargo run -- -i resources/macro.lef -o resources/macro.yaml
//
// // TODO(aryap): this
//
// Ok(())
// }
//
// /// Grab the full path of resource-file `fname`
// fn resource(rname: &str) -> String {
// format!("{}/resources/{}", env!("CARGO_MANIFEST_DIR"), rname)
// }
//}
2 changes: 1 addition & 1 deletion layout21raw/src/lef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl<'lib> LefExporter<'lib> {
let layers = self.lib.layers.read()?;
let name = self.unwrap(
layers.get_name(layerkey),
format!("Invalid un-named layer for LEF export"),
format!("Invalid un-named layer for LEF export: {:?}", layerkey),
)?;
Ok(name.to_string())
}
Expand Down
2 changes: 2 additions & 0 deletions layout21raw/src/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,8 @@ impl Layers {
.entry(layer_pb.index)
.or_insert(Layer::from_num(layer_pb.index as i16));

layer.name = Some(layer_pb.name.clone());

let sub_index = layer_pb.sub_index as i16;
let layer_purpose = match &layer_pb.purpose {
Some(purpose) => Layers::proto_to_internal_layer_purpose(sub_index, &purpose.r#type()),
Expand Down
1 change: 1 addition & 0 deletions lef21/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ mod data;
pub use data::*;
mod read;
mod write;
pub use write::save;

// Unit tests
#[cfg(test)]
Expand Down