use crate::Group;
use super::Cell;
#[test]
fn example_pin_opposite() {
let cell = crate::ast::test_parse_fmt::<Cell>(
r#"(test) {
pin_opposite ("Q1 Q2 Q3 ", "QB1 QB2 ") ;
}"#,
r#"
liberty_db::cell::Cell (test) {
| pin_opposite ("Q1 Q2 Q3", "QB1 QB2");
}"#,
);
}
#[test]
fn example23() {
let cell = crate::ast::test_parse_fmt::<Cell>(
r#"(dff4) {
area : 1 ;
pin (CLK) {
direction : input ;
capacitance : 0 ;
min_pulse_width_low : 3 ;
min_pulse_width_high : 3 ;
}
bundle (D) {
members(D1, D2, D3, D4);
nextstate_type : data;
direction : input ;
capacitance : 0 ;
timing() {
related_pin : "CLK" ;
timing_type : setup_rising ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
timing() {
related_pin : "CLK" ;
timing_type : hold_rising ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
}
pin (CLR) {
direction : input ;
capacitance : 0 ;
timing() {
related_pin : "CLK" ;
timing_type : recovery_rising ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
}
pin (PRE) {
direction : input ;
capacitance : 0 ;
timing() {
related_pin : "CLK" ;
timing_type : recovery_rising ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
}
ff_bank (IQ, IQN, 4) {
next_state : "D" ;
clocked_on : "CLK" ;
clear : "CLR’" ;
preset : "PRE’" ;
clear_preset_var1 : L ;
clear_preset_var2 : L ;
}
bundle (Q) {
members(Q1, Q2, Q3, Q4);
direction : output ;
function : "(IQ)" ;
timing() {
related_pin : "CLK" ;
timing_type : rising_edge ;
cell_rise(scalar) {
values (" 2.0 ") ;
}
cell_fall(scalar) {
values (" 2.0 ") ;
}
}
timing() {
related_pin : "PRE" ;
timing_type : preset ;
timing_sense : negative_unate ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
}
timing() {
related_pin : "CLR" ;
timing_type : clear ;
timing_sense : positive_unate ;
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
}
bundle (QN) {
members(Q1N, Q2N, Q3N, Q4N);
direction : output ;
function : "IQN" ;
timing() {
related_pin : "CLK" ;
timing_type : rising_edge ;
cell_rise(scalar) {
values (" 2.0 ") ;
}
cell_fall(scalar) {
values (" 2.0 ") ;
}
}
timing() {
related_pin : "PRE" ;
timing_type : clear ;
timing_sense : positive_unate ;
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
timing() {
related_pin : "CLR" ;
timing_type : preset ;
timing_sense : negative_unate ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
}
}
} /* end of cell dff4 */
"#,
r#"
liberty_db::cell::Cell (dff4) {
| area : 1.0;
| ff_bank (IQ, IQN, 4) {
| | clear : "!CLR";
| | clear_preset_var1 : L;
| | clear_preset_var2 : L;
| | clocked_on : "CLK";
| | next_state : "D";
| | preset : "!PRE";
| }
| pin (CLK) {
| | capacitance : 0.0;
| | direction : input;
| | min_pulse_width_high : 3.0;
| | min_pulse_width_low : 3.0;
| }
| pin (CLR) {
| | capacitance : 0.0;
| | direction : input;
| | timing () {
| | | related_pin : CLK;
| | | timing_type : recovery_rising;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| }
| pin (PRE) {
| | capacitance : 0.0;
| | direction : input;
| | timing () {
| | | related_pin : CLK;
| | | timing_type : recovery_rising;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| }
| bundle (D) {
| | members (D1, D2, D3, D4);
| | direction : input;
| | capacitance : 0.0;
| | nextstate_type : data;
| | timing () {
| | | related_pin : CLK;
| | | timing_type : hold_rising;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| | timing () {
| | | related_pin : CLK;
| | | timing_type : setup_rising;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| }
| bundle (Q) {
| | members (Q1, Q2, Q3, Q4);
| | direction : output;
| | function : "IQ";
| | timing () {
| | | related_pin : CLK;
| | | timing_type : rising_edge;
| | | cell_fall (scalar) {
| | | | values ("2.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("2.0");
| | | }
| | }
| | timing () {
| | | related_pin : CLR;
| | | timing_sense : positive_unate;
| | | timing_type : clear;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | }
| | timing () {
| | | related_pin : PRE;
| | | timing_sense : negative_unate;
| | | timing_type : preset;
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| }
| bundle (QN) {
| | members (Q1N, Q2N, Q3N, Q4N);
| | direction : output;
| | function : "IQN";
| | timing () {
| | | related_pin : CLK;
| | | timing_type : rising_edge;
| | | cell_fall (scalar) {
| | | | values ("2.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("2.0");
| | | }
| | }
| | timing () {
| | | related_pin : CLR;
| | | timing_sense : negative_unate;
| | | timing_type : preset;
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| | timing () {
| | | related_pin : PRE;
| | | timing_sense : positive_unate;
| | | timing_type : clear;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | }
| }
}"#,
);
}
#[test]
fn example27() {
let cell = crate::ast::test_parse_fmt::<Cell>(
r#"(latch4) {
area: 16;
pin (G) { /* gate enable signal, active-high */
direction : input;
}
bundle (D) { /* data input with four member pins */
members(D1, D2, D3, D4);/*must be 1st bundle attribute*/
direction : input;
}
bundle (Q) {
members(Q1, Q2, Q3, Q4);
direction : output;
function : "IQ" ;
}
bundle (QN) {
members (Q1N, Q2N, Q3N, Q4N);
direction : output;
function : "IQN";
}
latch_bank(IQ, IQN, 4) {
enable : "G" ;
data_in : "D" ;
}
}
"#,
r#"
liberty_db::cell::Cell (latch4) {
| area : 16.0;
| latch_bank (IQ, IQN, 4) {
| | enable : "G";
| | data_in : "D";
| }
| pin (G) {
| | direction : input;
| }
| bundle (D) {
| | members (D1, D2, D3, D4);
| | direction : input;
| }
| bundle (Q) {
| | members (Q1, Q2, Q3, Q4);
| | direction : output;
| | function : "IQ";
| }
| bundle (QN) {
| | members (Q1N, Q2N, Q3N, Q4N);
| | direction : output;
| | function : "IQN";
| }
}"#,
);
}
#[test]
fn example_pll() {
let cell = crate::ast::test_parse_fmt::<Cell>(
r#"(my_pll) {
is_pll_cell : true;
pin( REFCLK ) {
direction : input;
is_pll_reference_pin : true;
}
pin( FBKCLK ) {
direction : input;
is_pll_feedback_pin : true;
}
pin (OUTCLK1) {
direction : output;
is_pll_output_pin : true;
timing() { /*Timing Arc*/
related_pin: "REFCLK";
timing_type: combinational_rise;
timing_sense: positive_unate;
cell_rise(scalar) { /*Can be a LUT as well to support NLDM and CCS models*/
values("0.0")
}
}
timing() { /*Timing Arc*/
related_pin: "REFCLK";
timing_type: combinational_fall;
timing_sense: positive_unate;
cell_fall(scalar) {
values("0.0")
}
}
}
pin (OUTCLK2) {
direction : output;
is_pll_output_pin : true;
timing() { /*Timing Arc*/
related_pin: "REFCLK";
timing_type: combinational_rise;
timing_sense: positive_unate;
cell_rise(scalar) { /*Can be a LUT as well to support NLDM and CCS models*/
values("0.0")
}
}
timing() { /*Timing Arc*/
related_pin: "REFCLK";
timing_type: combinational_fall;
timing_sense: positive_unate;
cell_fall(scalar) {
values("0.0")
}
}
}
}"#,
r#"
liberty_db::cell::Cell (my_pll) {
| is_pll_cell : true;
| pin (FBKCLK) {
| | direction : input;
| | is_pll_feedback_pin : true;
| }
| pin (OUTCLK1) {
| | direction : output;
| | is_pll_output_pin : true;
| | timing () {
| | | related_pin : REFCLK;
| | | timing_sense : positive_unate;
| | | timing_type : combinational_fall;
| | | cell_fall (scalar) {
| | | | values ("0.0");
| | | }
| | }
| | timing () {
| | | related_pin : REFCLK;
| | | timing_sense : positive_unate;
| | | timing_type : combinational_rise;
| | | cell_rise (scalar) {
| | | | values ("0.0");
| | | }
| | }
| }
| pin (OUTCLK2) {
| | direction : output;
| | is_pll_output_pin : true;
| | timing () {
| | | related_pin : REFCLK;
| | | timing_sense : positive_unate;
| | | timing_type : combinational_fall;
| | | cell_fall (scalar) {
| | | | values ("0.0");
| | | }
| | }
| | timing () {
| | | related_pin : REFCLK;
| | | timing_sense : positive_unate;
| | | timing_type : combinational_rise;
| | | cell_rise (scalar) {
| | | | values ("0.0");
| | | }
| | }
| }
| pin (REFCLK) {
| | direction : input;
| | is_pll_reference_pin : true;
| }
}"#,
);
}
#[test]
fn example28() {
let cell = crate::ast::test_parse_fmt::<Cell>(
r#"(DLT2) {/* note: 0 hold time */
area : 1 ;
single_bit_degenerate : FDB ;
pin (EN) {
direction : input ;
capacitance : 0 ;
min_pulse_width_low : 3 ;
min_pulse_width_high : 3 ;
}
bundle (D) {
members(DA, DB, DC, DD);
direction : input ;
capacitance : 0 ;
timing() {
related_pin : "EN" ;
timing_type : setup_falling ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
timing() {
related_pin : "EN" ;
timing_type : hold_falling ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
}
bundle (CLR) {
members(CLRA, CLRB, CLRC, CLRD);
direction : input ;
capacitance : 0 ;
timing() {
related_pin : "EN" ;
timing_type : recovery_falling ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
}
bundle (PRE) {
members(PREA, PREB, PREC, PRED);
direction : input ;
capacitance : 0 ;
timing() {
related_pin : "EN" ;
timing_type : recovery_falling ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
}
latch_bank(IQ, IQN, 4) {
data_in : "D" ;
enable : "EN" ;
clear : "CLR’" ;
preset : "PRE’" ;
clear_preset_var1 : H ;
clear_preset_var2 : H ;
}
bundle (Q) {
members(QA, QB, QC, QD);
direction : output ;
function : "IQ" ;
timing() {
related_pin : "D" ;
cell_rise(scalar) {
values (" 2.0 ") ;
}
cell_fall(scalar) {
values (" 2.0 ") ;
}
}
timing() {
related_pin : "EN" ;
timing_type : rising_edge ;
cell_rise(scalar) {
values (" 2.0 ") ;
}
cell_fall(scalar) {
values (" 2.0 ") ;
}
}
timing() {
related_pin : "CLR" ;
timing_type : clear ;
timing_sense : positive_unate ;
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
timing() {
related_pin : "PRE" ;
timing_type : preset ;
timing_sense : negative_unate ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
}
}
bundle (QN) {
members(QNA, QNB, QNC, QND);
direction : output ;
function : "IQN" ;
timing() {
related_pin : "D" ;
cell_rise(scalar) {
values (" 2.0 ") ;
}
cell_fall(scalar) {
values (" 2.0 ") ;
}
}
timing() {
related_pin : "EN" ;
timing_type : rising_edge ;
cell_rise(scalar) {
values (" 2.0 ") ;
}
cell_fall(scalar) {
values (" 2.0 ") ;
}
}
timing() {
related_pin : "CLR" ;
timing_type : preset ;
timing_sense : negative_unate ;
cell_rise(scalar) {
values (" 1.0 ") ;
}
}
timing() {
related_pin : "PRE" ;
timing_type : clear ;
timing_sense : positive_unate ;
cell_fall(scalar) {
values (" 1.0 ") ;
}
}
}
} /* end of cell DLT2
"#,
r#"
liberty_db::cell::Cell (DLT2) {
| area : 1.0;
| single_bit_degenerate : FDB;
| latch_bank (IQ, IQN, 4) {
| | clear : "!CLR";
| | clear_preset_var1 : H;
| | clear_preset_var2 : H;
| | enable : "EN";
| | data_in : "D";
| | preset : "!PRE";
| }
| pin (EN) {
| | capacitance : 0.0;
| | direction : input;
| | min_pulse_width_high : 3.0;
| | min_pulse_width_low : 3.0;
| }
| bundle (CLR) {
| | members (CLRA, CLRB, CLRC, CLRD);
| | direction : input;
| | capacitance : 0.0;
| | timing () {
| | | related_pin : EN;
| | | timing_type : recovery_falling;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| }
| bundle (D) {
| | members (DA, DB, DC, DD);
| | direction : input;
| | capacitance : 0.0;
| | timing () {
| | | related_pin : EN;
| | | timing_type : hold_falling;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| | timing () {
| | | related_pin : EN;
| | | timing_type : setup_falling;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| }
| bundle (PRE) {
| | members (PREA, PREB, PREC, PRED);
| | direction : input;
| | capacitance : 0.0;
| | timing () {
| | | related_pin : EN;
| | | timing_type : recovery_falling;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| }
| bundle (Q) {
| | members (QA, QB, QC, QD);
| | direction : output;
| | function : "IQ";
| | timing () {
| | | related_pin : CLR;
| | | timing_sense : positive_unate;
| | | timing_type : clear;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | }
| | timing () {
| | | related_pin : D;
| | | cell_fall (scalar) {
| | | | values ("2.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("2.0");
| | | }
| | }
| | timing () {
| | | related_pin : EN;
| | | timing_type : rising_edge;
| | | cell_fall (scalar) {
| | | | values ("2.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("2.0");
| | | }
| | }
| | timing () {
| | | related_pin : PRE;
| | | timing_sense : negative_unate;
| | | timing_type : preset;
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| }
| bundle (QN) {
| | members (QNA, QNB, QNC, QND);
| | direction : output;
| | function : "IQN";
| | timing () {
| | | related_pin : CLR;
| | | timing_sense : negative_unate;
| | | timing_type : preset;
| | | cell_rise (scalar) {
| | | | values ("1.0");
| | | }
| | }
| | timing () {
| | | related_pin : D;
| | | cell_fall (scalar) {
| | | | values ("2.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("2.0");
| | | }
| | }
| | timing () {
| | | related_pin : EN;
| | | timing_type : rising_edge;
| | | cell_fall (scalar) {
| | | | values ("2.0");
| | | }
| | | cell_rise (scalar) {
| | | | values ("2.0");
| | | }
| | }
| | timing () {
| | | related_pin : PRE;
| | | timing_sense : positive_unate;
| | | timing_type : clear;
| | | cell_fall (scalar) {
| | | | values ("1.0");
| | | }
| | }
| }
}"#,
);
}