mirror of
https://github.com/alex-s168/turbo-blif.git
synced 2025-09-10 01:55:08 +02:00
c
This commit is contained in:
19
README.md
19
README.md
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
low-memory-usage BLIF (berkeley logic interchange format) parser.
|
low-memory-usage BLIF (berkeley logic interchange format) parser.
|
||||||
|
|
||||||
|
## Comparison with other parsers
|
||||||
| | this | SIS | yosys | abc | [pip blifparser] | [lorina] | [crates.io blif-parser] | [quaigh] | [libblifparse] | [spydrnet] |
|
| | this | SIS | yosys | abc | [pip blifparser] | [lorina] | [crates.io blif-parser] | [quaigh] | [libblifparse] | [spydrnet] |
|
||||||
| ------------------------------------------- | ---- | --- | ----- | --- | ---------------- | -------- | ----------------------- | -------- | -------------- | ---------- |
|
| ------------------------------------------- | ---- | --- | ----- | --- | ---------------- | -------- | ----------------------- | -------- | -------------- | ---------- |
|
||||||
| top module, latches, LUTs | x | x | x | x | x | x | x | x | x | x |
|
| top module, latches, LUTs | x | x | x | x | x | x | x | x | x | x |
|
||||||
@@ -15,7 +16,7 @@ low-memory-usage BLIF (berkeley logic interchange format) parser.
|
|||||||
| sub-file references | x | x | ? | - | x | - | - | - | - | - |
|
| sub-file references | x | x | ? | - | x | - | - | - | - | - |
|
||||||
| finite state machines (`.start_kiss`) | x | x | - | - | x | - | - | - | - | - |
|
| finite state machines (`.start_kiss`) | x | x | - | - | x | - | - | - | - | - |
|
||||||
| clock constraints (mostly for simulation) | soon | x | - | - | - | - | - | - | - | - |
|
| clock constraints (mostly for simulation) | soon | x | - | - | - | - | - | - | - | - |
|
||||||
| delay constraints | soon | x | - | x | - | - | - | - | - | - |
|
| delay constraints | soon | x | - | ~ | - | - | - | - | - | - |
|
||||||
| full BLIF specification [^1] | soon | x | - | - | - | - | - | - | - | - |
|
| full BLIF specification [^1] | soon | x | - | - | - | - | - | - | - | - |
|
||||||
| extension: "Black- & White-boxes" [^2] | soon | - | - | - | - | - | - | - | - | - |
|
| extension: "Black- & White-boxes" [^2] | soon | - | - | - | - | - | - | - | - | - |
|
||||||
| extension: `.blackbox` | soon | - | x | x | - | - | - | - | x | x |
|
| extension: `.blackbox` | soon | - | x | x | - | - | - | - | x | x |
|
||||||
@@ -23,7 +24,7 @@ low-memory-usage BLIF (berkeley logic interchange format) parser.
|
|||||||
| extension: `.attr` and `.param` (EBLIF[^3]) | x | - | x | - | - | - | - | - | x | x |
|
| extension: `.attr` and `.param` (EBLIF[^3]) | x | - | x | - | - | - | - | - | x | x |
|
||||||
| extension: `.conn` (EBLIF[^3]) | x | - | x | - | - | - | - | - | x | x |
|
| extension: `.conn` (EBLIF[^3]) | x | - | x | - | - | - | - | - | x | x |
|
||||||
| extension: `.barbuff` (identical: `.conn`) | x | - | x | - | - | - | - | - | - | - |
|
| extension: `.barbuff` (identical: `.conn`) | x | - | x | - | - | - | - | - | - | - |
|
||||||
|
| extension: `.and_gate_delay` | soon | - | - | x | - | - | - | - | - | - |
|
||||||
|
|
||||||
|
|
||||||
[^1]: https://people.eecs.berkeley.edu/~alanmi/publications/other/blif.pdf
|
[^1]: https://people.eecs.berkeley.edu/~alanmi/publications/other/blif.pdf
|
||||||
@@ -37,11 +38,13 @@ low-memory-usage BLIF (berkeley logic interchange format) parser.
|
|||||||
[libblifparse]: https://github.com/verilog-to-routing/libblifparse
|
[libblifparse]: https://github.com/verilog-to-routing/libblifparse
|
||||||
[spydrnet]: https://github.com/byuccl/spydrnet
|
[spydrnet]: https://github.com/byuccl/spydrnet
|
||||||
|
|
||||||
- the latest BLIF specification (dated July 28, 1992)
|
|
||||||
- all yosys BLIF extensions
|
|
||||||
(supports reading of BLIF files generated with `write_blif -iname -iattr -param -cname -blackbox -attr -conn`)
|
|
||||||
- KISS state machines (which yosys doesn't even support)
|
|
||||||
- clock and delay constraints (yosys just ignores those)
|
|
||||||
|
|
||||||
If you found a program that generates non-standard BLIF attributes or keywords, please open a GitHub issue.
|
## Tested with BLIF generators
|
||||||
|
- yosys `write_blif`, including all supported extensions: `write_blif -iname -iattr -param -cname -blackbox -attr -conn`
|
||||||
|
- abc write blif
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
- parse every BLIF file in existence
|
||||||
|
|
||||||
|
If you found a program that generates or consists of non-standard BLIF attributes or keywords, please open a GitHub issue.
|
||||||
We want to support all non-standard extensions.
|
We want to support all non-standard extensions.
|
||||||
|
18
src/ast.rs
18
src/ast.rs
@@ -127,10 +127,17 @@ impl From<ModelCmdKind> for ModelCmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, PartialEq, PartialOrd)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Default)]
|
||||||
|
pub struct ModelAttr {
|
||||||
|
/// from blif `.area` attribute
|
||||||
|
pub area: Option<f64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
pub meta: ModelMeta,
|
pub meta: ModelMeta,
|
||||||
pub commands: Vec<ModelCmd>,
|
pub commands: Vec<ModelCmd>,
|
||||||
|
pub attr: ModelAttr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandConsumer for Model {
|
impl CommandConsumer for Model {
|
||||||
@@ -214,6 +221,10 @@ impl CommandConsumer for Model {
|
|||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_area(&mut self, area: f64) {
|
||||||
|
self.attr.area = Some(area);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -225,12 +236,12 @@ pub enum FullBlifErr<E: std::fmt::Debug> {
|
|||||||
SearchPathsNotSupported,
|
SearchPathsNotSupported,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Hash)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum BlifEntry {
|
pub enum BlifEntry {
|
||||||
Model(Model),
|
Model(Model),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Hash)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Blif {
|
pub struct Blif {
|
||||||
pub entries: Vec<BlifEntry>,
|
pub entries: Vec<BlifEntry>,
|
||||||
to_search: Vec<String>,
|
to_search: Vec<String>,
|
||||||
@@ -243,6 +254,7 @@ impl ModelConsumer for Blif {
|
|||||||
Model {
|
Model {
|
||||||
meta,
|
meta,
|
||||||
commands: vec![],
|
commands: vec![],
|
||||||
|
attr: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
src/lib.rs
16
src/lib.rs
@@ -106,6 +106,8 @@ pub trait CommandConsumer {
|
|||||||
|
|
||||||
/// non-standard
|
/// non-standard
|
||||||
fn connect(&mut self, from: &str, to: &str);
|
fn connect(&mut self, from: &str, to: &str);
|
||||||
|
|
||||||
|
fn set_area(&mut self, area: f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, PartialEq, PartialOrd)]
|
#[derive(Debug, Clone, Hash, PartialEq, PartialOrd)]
|
||||||
@@ -844,6 +846,20 @@ fn parse_mod(
|
|||||||
consumer.connect(from, to);
|
consumer.connect(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
".area" => {
|
||||||
|
let val = args
|
||||||
|
.next()
|
||||||
|
.ok_or(BlifParserError::MissingArgs)?
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| BlifParserError::Invalid)?;
|
||||||
|
|
||||||
|
if args.next().is_some() {
|
||||||
|
Err(BlifParserError::TooManyArgs)?
|
||||||
|
}
|
||||||
|
|
||||||
|
consumer.set_area(val);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: clock & delay cst
|
// TODO: clock & delay cst
|
||||||
// TODO: .blackblox
|
// TODO: .blackblox
|
||||||
_ => Err(BlifParserError::UnknownKw(cmd.to_string()))?,
|
_ => Err(BlifParserError::UnknownKw(cmd.to_string()))?,
|
||||||
|
108
src/tests.rs
108
src/tests.rs
@@ -1,3 +1,8 @@
|
|||||||
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
use std::default;
|
||||||
|
|
||||||
use super::ast::*;
|
use super::ast::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@@ -38,6 +43,7 @@ fn simple_named() {
|
|||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
],
|
],
|
||||||
|
attr: Default::default(),
|
||||||
})],
|
})],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -77,6 +83,7 @@ fn simple_unnamed() {
|
|||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
],
|
],
|
||||||
|
attr: Default::default(),
|
||||||
})],
|
})],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -115,6 +122,7 @@ c
|
|||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
],
|
],
|
||||||
|
attr: Default::default(),
|
||||||
})],
|
})],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -154,6 +162,7 @@ c
|
|||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
],
|
],
|
||||||
|
attr: Default::default(),
|
||||||
})],
|
})],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -224,6 +233,7 @@ fn lut() {
|
|||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
],
|
],
|
||||||
|
attr: Default::default(),
|
||||||
})],
|
})],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -281,7 +291,8 @@ fn submod() {
|
|||||||
lut: LUT(vec![([Tristate::True].into_iter().collect(), true)])
|
lut: LUT(vec![([Tristate::True].into_iter().collect(), true)])
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
]
|
],
|
||||||
|
attr: Default::default(),
|
||||||
}),
|
}),
|
||||||
BlifEntry::Model(Model {
|
BlifEntry::Model(Model {
|
||||||
meta: ModelMeta {
|
meta: ModelMeta {
|
||||||
@@ -303,7 +314,8 @@ fn submod() {
|
|||||||
)])
|
)])
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
]
|
],
|
||||||
|
attr: Default::default(),
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
@@ -507,3 +519,95 @@ fn yosys_attrs() {
|
|||||||
|
|
||||||
// TODO: assert_eq
|
// TODO: assert_eq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn delay_cst__area() {
|
||||||
|
let ast = parse_str_blif_to_ast(
|
||||||
|
"top.blif",
|
||||||
|
r#"
|
||||||
|
.model top
|
||||||
|
.names $true
|
||||||
|
1
|
||||||
|
# .area is not a model attribute, but a command
|
||||||
|
.area 100.31
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
ast.entries,
|
||||||
|
vec![BlifEntry::Model(Model {
|
||||||
|
meta: ModelMeta {
|
||||||
|
name: "top".into(),
|
||||||
|
inputs: None,
|
||||||
|
outputs: None,
|
||||||
|
clocks: vec![],
|
||||||
|
},
|
||||||
|
commands: vec![ModelCmd {
|
||||||
|
kind: ModelCmdKind::Gate(Gate {
|
||||||
|
meta: GateMeta {
|
||||||
|
inputs: vec![],
|
||||||
|
output: "$true".into(),
|
||||||
|
external_dc: false,
|
||||||
|
},
|
||||||
|
lut: LUT(vec![([].into_iter().collect(), true)])
|
||||||
|
}),
|
||||||
|
attrs: vec![],
|
||||||
|
}],
|
||||||
|
attr: ModelAttr {
|
||||||
|
area: Some(100.31),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
})]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// generated by abc: https://github.com/berkeley-abc/abc/blob/master/src/base/io/ioWriteBlif.c
|
||||||
|
#[test]
|
||||||
|
fn abc__and_gate_delay() {
|
||||||
|
let ast = parse_str_blif_to_ast(
|
||||||
|
"top.blif",
|
||||||
|
r#"
|
||||||
|
.model top
|
||||||
|
.names $true
|
||||||
|
1
|
||||||
|
# not a model attribute, but a command
|
||||||
|
.and_gate_delay 12.31
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// TODO: assert
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn delay_cst__default_spec() {
|
||||||
|
let ast = parse_str_blif_to_ast(
|
||||||
|
"top.blif",
|
||||||
|
r#"
|
||||||
|
.model top
|
||||||
|
.names $true
|
||||||
|
1
|
||||||
|
# not a model attribute, but a command
|
||||||
|
|
||||||
|
.default_input_arrival 3.0 3.2
|
||||||
|
.default_output_required 2.1 2.5
|
||||||
|
|
||||||
|
.default_max_input_load 200
|
||||||
|
.default_output_load 300
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// TODO: assert
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
//.delay <in-name> <phase> <load> <max-load> <brise> <drise> <bfall> <dfall>
|
||||||
|
//.wire_load_slope <load>
|
||||||
|
//.wire <wire-load-list>
|
||||||
|
//.input_arrival <in-name> <rise> <fall> [<before-after> <event>]
|
||||||
|
//.output_required <out-name> <rise> <fall> [<before-after> <event>]
|
||||||
|
//.max_input_load <load>
|
||||||
|
//.input_drive <in-name> <rise> <fall>
|
||||||
|
//.output_load <out-name> <load>
|
||||||
|
Reference in New Issue
Block a user