#![cfg(test)]
use itertools::Itertools;
use libreda_db::chip::Chip;
use libreda_db::prelude::*;
#[test]
fn test_create_circuit() {
let mut chip = Chip::new();
assert_eq!(chip.num_cells(), 0);
let a = chip.create_cell("A".to_string());
assert_eq!(chip.num_cells(), 1);
let b = chip.create_cell("B".to_string());
assert_eq!(chip.num_cells(), 2);
assert_eq!(chip.cell_name(&a), "A");
assert_eq!(chip.cell_name(&b), "B");
chip.remove_cell(&a);
assert_eq!(chip.num_cells(), 1);
}
#[test]
fn test_get_cell_by_name() {
let mut chip = Chip::new();
let a = chip.create_cell("A".to_string());
let b = chip.create_cell("B".to_string());
assert_eq!(chip.cell_by_name("A"), Some(a));
assert_eq!(chip.cell_by_name("B"), Some(b));
assert_eq!(chip.cell_by_name("C"), None);
}
#[test]
fn test_create_sub_circuit() {
let mut chip = Chip::new();
let a = chip.create_cell("A".into());
let b = chip.create_cell("B".into());
let inst_a = chip.create_cell_instance(&b, &a, Some("inst_a".into()));
assert_eq!(chip.num_child_instances(&b), 1);
assert_eq!(chip.num_cell_references(&a), 1);
assert_eq!(chip.num_cell_references(&b), 0);
assert_eq!(chip.template_cell(&inst_a), a);
assert_eq!(chip.parent_cell(&inst_a), b);
assert_eq!(chip.each_cell_instance(&b).collect_vec(), vec![inst_a]);
assert_eq!(chip.each_cell_instance(&a).count(), 0);
assert_eq!(chip.each_cell_reference(&a).collect_vec(), vec![inst_a]);
assert_eq!(chip.each_cell_reference(&b).count(), 0);
assert_eq!(chip.num_dependent_cells(&a), 1);
assert_eq!(chip.num_dependent_cells(&b), 0);
assert_eq!(chip.num_cell_dependencies(&a), 0);
assert_eq!(chip.num_cell_dependencies(&b), 1);
assert_eq!(chip.each_dependent_cell(&a).collect_vec(), vec![b]);
assert_eq!(chip.each_dependent_cell(&b).collect_vec(), vec![]);
assert_eq!(chip.each_cell_dependency(&a).collect_vec(), vec![]);
assert_eq!(chip.each_cell_dependency(&b).collect_vec(), vec![a]);
}
#[test]
fn test_get_sub_circuit_by_name() {
let mut chip = Chip::new();
let a = chip.create_cell("A".into());
let b = chip.create_cell("B".into());
let inst1 = chip.create_cell_instance(&b, &a, Some("a1".into()));
let inst2 = chip.create_cell_instance(&b, &a, Some("a2".into()));
assert_eq!(chip.cell_instance_by_name(&b, "a1"), Some(inst1));
assert_eq!(chip.cell_instance_by_name(&b, "a2"), Some(inst2));
assert_eq!(chip.cell_instance_by_name(&b, "a3"), None);
}
#[test]
fn test_create_pins() {
let mut chip = Chip::new();
let a = chip.create_cell("A".into());
let b = chip.create_cell("B".into());
let inst1 = chip.create_cell_instance(&b, &a, Some("a1".into()));
let pin1 = chip.create_pin(&a, "pin1".into(), Direction::Input);
assert_eq!(chip.num_pins(&a), 1);
assert_eq!(chip.each_pin_instance(&inst1).count(), 1);
for pin_inst in chip.each_pin_instance(&inst1) {
assert_eq!(&chip.template_pin(&pin_inst), &pin1);
}
assert_eq!(chip.pin_by_name(&a, "pin1").as_ref(), Some(&pin1));
}
#[test]
fn test_create_nets() {
let mut chip = Chip::new();
let a = chip.create_cell("A".into());
let b = chip.create_cell("B".into());
let a_net1 = chip.create_net(&a, Some("net1".into()));
assert_eq!(chip.num_internal_nets(&a), 1 + 2); let a_net2 = chip.create_net(&a, Some("net2".into()));
let b_net2 = chip.create_net(&b, Some("net2".into()));
assert_eq!(chip.num_internal_nets(&a), 2 + 2);
assert_eq!(chip.net_by_name(&a, "net1").as_ref(), Some(&a_net1));
assert_eq!(chip.net_by_name(&a, "net2").as_ref(), Some(&a_net2));
assert_eq!(chip.net_by_name(&b, "net1").as_ref(), None);
assert_eq!(chip.net_by_name(&b, "net2").as_ref(), Some(&b_net2));
}
#[test]
fn test_connect_nets() {
#![allow(unused_variables)]
let mut chip = Chip::new();
let a = chip.create_cell("A".into());
let top = chip.create_cell("TOP".into());
let a_pin1 = chip.create_pin(&a, "pin1".into(), Direction::Input);
let a_pin2 = chip.create_pin(&a, "pin2".into(), Direction::Output);
let a_clk = chip.create_pin(&a, "clk".into(), Direction::Clock);
let top_pin_clk = chip.create_pin(&top, "clk".into(), Direction::Clock);
let inst1 = chip.create_cell_instance(&top, &a, Some("a1".into()));
let inst2 = chip.create_cell_instance(&top, &a, Some("a2".into()));
let top_net1 = chip.create_net(&top, Some("net1".into()));
let top_net2 = chip.create_net(&top, Some("net2".into()));
let top_clk = chip.create_net(&top, Some("clk".into()));
assert_eq!(chip.connect_pin(&top_pin_clk, Some(top_clk)), None);
assert_eq!(chip.num_net_terminals(&top_clk), 1);
let inst1_clk_pin = chip.pin_instance(&inst1, &a_clk);
let inst2_clk_pin = chip.pin_instance(&inst2, &a_clk);
assert_eq!(
chip.connect_pin_instance(&inst1_clk_pin, Some(top_clk)),
None
);
assert_eq!(
chip.connect_pin_instance(&inst2_clk_pin, Some(top_clk)),
None
);
assert_eq!(chip.num_net_terminals(&top_clk), 3);
let top_clk_terminals = chip.each_terminal_of_net(&top_clk).collect_vec();
assert!(top_clk_terminals.contains(&TerminalId::PinId(top_pin_clk)));
assert!(top_clk_terminals.contains(&TerminalId::PinInstId(inst1_clk_pin)));
assert!(top_clk_terminals.contains(&TerminalId::PinInstId(inst2_clk_pin)));
}
#[test]
#[should_panic(expected = "Cannot create recursive instances.")]
fn test_circuit_no_recursion_1() {
let mut chip = Chip::new();
let top = chip.create_cell("top".into());
let _top_inst = chip.create_cell_instance(&top, &top, Some("top_inst".into()));
}
#[test]
#[should_panic(expected = "Cannot create recursive instances.")]
fn test_circuit_no_recursion_2() {
let mut chip = Chip::new();
let top = chip.create_cell("top".into());
let sub = chip.create_cell("sub".into());
let _sub_inst = chip.create_cell_instance(&top, &sub, Some("sub_inst".into()));
let _top_inst = chip.create_cell_instance(&sub, &top, Some("recursive_inst".into()));
}
#[test]
fn test_rename_net() {
let mut chip = Chip::new();
let top = chip.create_cell("top".into());
let net1 = chip.create_net(&top, Some("Net1".into()));
assert_eq!(Some(&net1), chip.net_by_name(&top, "Net1").as_ref());
chip.rename_net(&net1, Some("NewName".into()));
assert_eq!(Some(&net1), chip.net_by_name(&top, "NewName").as_ref());
chip.rename_net(&net1, Some("Net1".into()));
assert_eq!(Some(&net1), chip.net_by_name(&top, "Net1").as_ref());
chip.rename_net(&net1, None);
assert_eq!(None, chip.net_by_name(&top, "Net1"));
}
#[test]
fn test_flatten_circuit_instance() {
let mut chip = Chip::new();
let top = chip.create_cell("top".into());
let top_pin_a = chip.create_pin(&top, "A".into(), Direction::InOut);
let a = chip.create_cell("a".into());
let a_pin_a = chip.create_pin(&a, "A".into(), Direction::InOut);
let b = chip.create_cell("b".into());
let _b_pin_a = chip.create_pin(&b, "A".into(), Direction::InOut);
let a_inst = chip.create_cell_instance(&top, &a, Some("a_inst".into()));
let b_inst = chip.create_cell_instance(&a, &b, Some("b_inst".into()));
let net1 = chip.create_net(&top, Some("Net1".into()));
chip.connect_pin(&top_pin_a, Some(net1));
let a_pin_inst_a = chip.each_pin_instance_vec(&a_inst);
chip.connect_pin_instance(&a_pin_inst_a[0], Some(net1));
assert_eq!(chip.num_net_terminals(&net1), 2);
let net2 = chip.create_net(&a, Some("Net2".into()));
let b_pin_inst_a = chip.each_pin_instance_vec(&b_inst);
chip.connect_pin_instance(&b_pin_inst_a[0], Some(net2));
chip.connect_pin(&a_pin_a, Some(net2));
assert_eq!(chip.num_net_terminals(&net2), 2);
chip.flatten_circuit_instance(&a_inst);
assert_eq!(chip.num_child_instances(&top), 1);
assert_eq!(chip.cell_instance_by_name(&top, "a_inst"), None);
assert!(chip.cell_instance_by_name(&top, "a_inst:b_inst").is_some());
assert_eq!(chip.num_net_terminals(&net1), 2);
}