mirror of
https://github.com/alex-s168/turbo-blif.git
synced 2025-09-09 17:45:09 +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.
|
||||
|
||||
## Comparison with other parsers
|
||||
| | 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 |
|
||||
@@ -15,7 +16,7 @@ low-memory-usage BLIF (berkeley logic interchange format) parser.
|
||||
| sub-file references | x | x | ? | - | x | - | - | - | - | - |
|
||||
| finite state machines (`.start_kiss`) | x | x | - | - | x | - | - | - | - | - |
|
||||
| clock constraints (mostly for simulation) | soon | x | - | - | - | - | - | - | - | - |
|
||||
| delay constraints | soon | x | - | x | - | - | - | - | - | - |
|
||||
| delay constraints | soon | x | - | ~ | - | - | - | - | - | - |
|
||||
| full BLIF specification [^1] | soon | x | - | - | - | - | - | - | - | - |
|
||||
| extension: "Black- & White-boxes" [^2] | soon | - | - | - | - | - | - | - | - | - |
|
||||
| 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: `.conn` (EBLIF[^3]) | x | - | x | - | - | - | - | - | 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
|
||||
@@ -37,11 +38,13 @@ low-memory-usage BLIF (berkeley logic interchange format) parser.
|
||||
[libblifparse]: https://github.com/verilog-to-routing/libblifparse
|
||||
[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.
|
||||
|
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 meta: ModelMeta,
|
||||
pub commands: Vec<ModelCmd>,
|
||||
pub attr: ModelAttr,
|
||||
}
|
||||
|
||||
impl CommandConsumer for Model {
|
||||
@@ -214,6 +221,10 @@ impl CommandConsumer for Model {
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
fn set_area(&mut self, area: f64) {
|
||||
self.attr.area = Some(area);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -225,12 +236,12 @@ pub enum FullBlifErr<E: std::fmt::Debug> {
|
||||
SearchPathsNotSupported,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Hash)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum BlifEntry {
|
||||
Model(Model),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Hash)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Blif {
|
||||
pub entries: Vec<BlifEntry>,
|
||||
to_search: Vec<String>,
|
||||
@@ -243,6 +254,7 @@ impl ModelConsumer for Blif {
|
||||
Model {
|
||||
meta,
|
||||
commands: vec![],
|
||||
attr: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
16
src/lib.rs
16
src/lib.rs
@@ -106,6 +106,8 @@ pub trait CommandConsumer {
|
||||
|
||||
/// non-standard
|
||||
fn connect(&mut self, from: &str, to: &str);
|
||||
|
||||
fn set_area(&mut self, area: f64);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, PartialOrd)]
|
||||
@@ -844,6 +846,20 @@ fn parse_mod(
|
||||
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: .blackblox
|
||||
_ => 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::*;
|
||||
|
||||
@@ -38,6 +43,7 @@ fn simple_named() {
|
||||
})
|
||||
.into()
|
||||
],
|
||||
attr: Default::default(),
|
||||
})],
|
||||
);
|
||||
}
|
||||
@@ -77,6 +83,7 @@ fn simple_unnamed() {
|
||||
})
|
||||
.into()
|
||||
],
|
||||
attr: Default::default(),
|
||||
})],
|
||||
);
|
||||
}
|
||||
@@ -115,6 +122,7 @@ c
|
||||
})
|
||||
.into()
|
||||
],
|
||||
attr: Default::default(),
|
||||
})],
|
||||
);
|
||||
}
|
||||
@@ -154,6 +162,7 @@ c
|
||||
})
|
||||
.into()
|
||||
],
|
||||
attr: Default::default(),
|
||||
})],
|
||||
);
|
||||
}
|
||||
@@ -224,6 +233,7 @@ fn lut() {
|
||||
})
|
||||
.into()
|
||||
],
|
||||
attr: Default::default(),
|
||||
})],
|
||||
);
|
||||
}
|
||||
@@ -281,7 +291,8 @@ fn submod() {
|
||||
lut: LUT(vec![([Tristate::True].into_iter().collect(), true)])
|
||||
})
|
||||
.into()
|
||||
]
|
||||
],
|
||||
attr: Default::default(),
|
||||
}),
|
||||
BlifEntry::Model(Model {
|
||||
meta: ModelMeta {
|
||||
@@ -303,7 +314,8 @@ fn submod() {
|
||||
)])
|
||||
})
|
||||
.into()
|
||||
]
|
||||
],
|
||||
attr: Default::default(),
|
||||
})
|
||||
]
|
||||
);
|
||||
@@ -507,3 +519,95 @@ fn yosys_attrs() {
|
||||
|
||||
// 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