//! unit tests for libertyparse //! function and FF test use libertyparse::*; use std::sync::Once; static INIT: Once = Once::new(); /// Setup function that is only run once, even if called multiple times. fn setup() { INIT.call_once(|| { clilog::init_stderr_color_debug(); }); } const LIBERTY_FF: &str = include_str!("sky130_dff_simplify.lib"); #[test] fn test_slew_derate_thr() { setup(); let parsed = Liberty::parse_str(LIBERTY_FF).expect("parse error"); let lib = &parsed.libs[0].1; assert_eq!(lib.slew_derate, 0.98); assert_eq!(lib.input_delay_threshold, [0.52, 0.51]); assert_eq!(lib.output_delay_threshold, [0.54, 0.53]); assert_eq!(lib.slew_threshold, [(0.19, 0.78), (0.21, 0.79)]); } #[test] fn test_ff_function() { setup(); let parsed = Liberty::parse_str(LIBERTY_FF).expect("parse error"); // clilog::debug!("Parsed is: {parsed:#?}"); clilog::info!("FF Function unparsed summary:"); parsed.debug_report_unparsed(); assert_eq!(parsed.libs.len(), 1); assert_eq!(parsed.libs[0].0, "sky130_fd_sc_hd__ff_n40C_1v95"); let lib = &parsed.libs[0].1; assert_eq!(lib.cells.len(), 3); assert_eq!(format!("{:?}", lib.cells.iter().map(|(s, _)| s.as_ref()).collect::>()), "[\"sky130_fd_sc_hd__a211oi_1\", \"sky130_fd_sc_hd__dfbbn_1\", \"sky130_fd_sc_hd__sdlclkp_4\"]"); let cell_aoi = &lib.cells[0].1; assert_eq!(cell_aoi.pins.len(), 5); assert_eq!(format!("{:?}", cell_aoi.pins.iter().map(|(s, _)| s.as_ref()).collect::>()), "[\"A1\", \"A2\", \"B1\", \"C1\", \"Y\"]"); assert_eq!(format!("{:?}", cell_aoi.pins[4].1.function), r#"Some(LogicExpr { compiled: [PushVar("A1"), Op(33), PushVar("B1"), Op(33), Op(38), PushVar("C1"), Op(33), Op(38), PushVar("A2"), Op(33), PushVar("B1"), Op(33), Op(38), PushVar("C1"), Op(33), Op(38), Op(124)] })"#); let cell_ff = &lib.cells[1].1; assert_eq!(format!("{:?}", cell_ff.sequential_def), r#"Some(FF(FFDef { pin_v1: "IQ", pin_v2: "IQ_N", clocked_on: LogicExpr { compiled: [PushVar("CLK_N"), Op(33)] }, next_state: LogicExpr { compiled: [PushVar("D")] }, clear: Some(LogicExpr { compiled: [PushVar("RESET_B"), Op(33)] }), preset: Some(LogicExpr { compiled: [PushVar("SET_B"), Op(33)] }), clear_preset_var1: Some(H), clear_preset_var2: Some(L) }))"#); assert_eq!(format!("{:?}", lib.cells[2].1.sequential_def), r#"Some(StateTable(StateTableDef { inputs: ["CLK", "GATE", "SCE"], internals: ["M0"], rows: [[L, L, L, N, L], [L, L, H, N, H], [L, H, L, N, H], [L, H, H, N, H], [H, N, N, N, N]] }))"#); }