use patched galette, make comb olmc case work

This commit is contained in:
saji 2024-05-04 17:45:38 -05:00
parent 22f1a2a26b
commit e41aef8440
3 changed files with 85 additions and 53 deletions

11
compiler/Cargo.lock generated
View file

@ -305,11 +305,12 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "galette" name = "galette"
version = "0.3.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/5aji/galette.git#8d8e8247b4820cebd193b707f0f8d45f3d3b58bb"
checksum = "4bacf731bf0e2b11cef74a9454c3e073e737e1423c0b94958da9131dd40a09f5"
dependencies = [ dependencies = [
"anyhow",
"clap 2.34.0", "clap 2.34.0",
"itertools", "itertools",
"test_bin",
"thiserror", "thiserror",
] ]
@ -615,6 +616,12 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "test_bin"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e7a7de15468c6e65dd7db81cf3822c1ec94c71b2a3c1a976ea8e4696c91115c"
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.11.0" version = "0.11.0"

View file

@ -9,7 +9,7 @@ edition = "2021"
anyhow = "1.0.81" anyhow = "1.0.81"
clap = { version = "4.5.4", features = ["derive"] } clap = { version = "4.5.4", features = ["derive"] }
env_logger = "0.11.3" env_logger = "0.11.3"
galette = "0.3.0" galette = { git = "https://github.com/5aji/galette.git" }
log = "0.4.21" log = "0.4.21"
regex = "1.10.4" regex = "1.10.4"
serde = { version = "1.0.197", features = ["derive"] } serde = { version = "1.0.197", features = ["derive"] }

View file

@ -36,7 +36,6 @@ pub enum MappingError {
fn get_sop_for_olmc( fn get_sop_for_olmc(
graph: &Graph, graph: &Graph,
olmc_idx: &NodeIdx, olmc_idx: &NodeIdx,
olmcmap: &Vec<Option<NodeIdx>>,
) -> Result<GalSop, MappingError> { ) -> Result<GalSop, MappingError> {
let input = graph.get_node_port_conns(olmc_idx, "A"); let input = graph.get_node_port_conns(olmc_idx, "A");
let sops_on_net: Vec<_> = input let sops_on_net: Vec<_> = input
@ -48,28 +47,23 @@ fn get_sop_for_olmc(
}; };
let node = graph.get_node(&driver_cell.0)?; let node = graph.get_node(&driver_cell.0)?;
match node { match node {
Node::Sop(s) => Some(s), Node::Sop(s) => Some(s.clone()),
// Node::Olmc(o) => { Node::Olmc(o) => {
// // find the row that contains this olmc. // find the row that contains this olmc.
// // we know this exists because mapping has already finished. // we know this exists because mapping has already finished.
// let row = olmcmap.iter().position(|potential_match| { let newsop = GalSop {
// match potential_match { connections: HashMap::from([
// Some(row) => row == &driver_cell.0, ("A".to_string(), vec![i.net.clone()]),
// None => false, ]),
// } parameters: GalSopParameters {
// }).unwrap(); depth: 1,
// let newsop = GalSop { width: 1,
// connections: HashMap::from([ table: "10".to_string(),
// ("A", },
// ]), };
// parameters: GalSopParameters { Some(newsop)
// depth: 1,
// width: 1, },
// table: "10".to_string(),
// },
// };
//
// },
_ => None, _ => None,
} }
}) })
@ -84,12 +78,11 @@ fn map_remaining_olmc(
graph: &Graph, graph: &Graph,
olmc: NodeIdx, olmc: NodeIdx,
unused: &Vec<(usize, usize)>, unused: &Vec<(usize, usize)>,
olmcmap: &Vec<Option<NodeIdx>>,
) -> Result<(usize, usize), MappingError> { ) -> Result<(usize, usize), MappingError> {
// (index, size) // (index, size)
let mut chosen_row: Option<(usize, usize)> = None; let mut chosen_row: Option<(usize, usize)> = None;
// FIXME: implement. // FIXME: implement.
let sop = get_sop_for_olmc(graph, &olmc, olmcmap)?; let sop = get_sop_for_olmc(graph, &olmc)?;
let sopsize: usize = sop.parameters.depth as usize; let sopsize: usize = sop.parameters.depth as usize;
for (olmc_idx, size) in unused { for (olmc_idx, size) in unused {
@ -120,28 +113,38 @@ fn map_remaining_olmc(
} }
} }
fn find_hwpin_for_net(graph: &Graph, pcf: &PcfFile, net: &Net) -> Result<u32, MappingError> { fn find_hwpin_for_net(
graph: &Graph,
pcf: &PcfFile,
olmcmap: &Vec<Option<NodeIdx>>,
net: &Net,
) -> Result<u32, MappingError> {
// this does a double lookup. first it finds the Input on the net, // this does a double lookup. first it finds the Input on the net,
// then it finds the port on the input of the GAL_INPUT. // then it finds the port on the input of the GAL_INPUT.
// find the input on the net. // find the input on the net.
let inputs: Vec<&GalInput> = graph let inputs: Vec<&Node> = graph
.find_nodes_on_net(net) .find_nodes_on_net(net)
.iter() .iter()
.filter_map(|n| match graph.get_node(n) { .filter_map(|n| {
Some(Node::Input(i)) => Some(i), let node = graph.get_node(n)?;
match node {
Node::Input(_) => Some(node),
Node::Olmc(_) => Some(node),
_ => None, _ => None,
}
}) })
.collect(); .collect();
// now we have an array of inputs, this should be one elemnt. // now we have an array of inputs, this should be one driver element.
if inputs.len() != 1 { if inputs.len() != 1 {
return Err(MappingError::Unknown); return Err(MappingError::Unknown);
} }
let port_nets = inputs[0] let conns = inputs[0].get_connections();
.connections
.get("A") match inputs[0] {
.ok_or(MappingError::Unknown)?; Node::Input(_) => {
let port_nets = conns.get("A").ok_or(MappingError::Unknown)?;
assert_eq!(port_nets.len(), 1, "should only be one input to GAL_INPUT"); assert_eq!(port_nets.len(), 1, "should only be one input to GAL_INPUT");
let pnet = &port_nets[0]; let pnet = &port_nets[0];
@ -153,9 +156,31 @@ fn find_hwpin_for_net(graph: &Graph, pcf: &PcfFile, net: &Net) -> Result<u32, Ma
} else { } else {
Err(MappingError::Unknown) Err(MappingError::Unknown)
} }
}
Node::Olmc(_) => {
// find the row that this olmc is in.
debug!("an olmc is driving this net, looking up what row it is");
let olmc_idx = graph
.nodelist
.iter()
.position(|node| node == inputs[0])
.unwrap();
let olmc_row = olmcmap.iter().position(|r| r == &Some(NodeIdx(olmc_idx))).unwrap();
// we have the row.
let pin = olmc_row + 12; // TODO: fix!
debug!("OLMC discovered on {pin}");
Ok(pin as u32)
}
_ => Err(MappingError::Unknown),
}
} }
/// Takes a gal sop, and turns it into a vec of mapped pins. /// Takes a gal sop, and turns it into a vec of mapped pins.
fn make_term_from_sop(graph: &Graph, sop: GalSop, pcf: &PcfFile) -> Term { fn make_term_from_sop(
graph: &Graph,
pcf: &PcfFile,
olmcmap: &Vec<Option<NodeIdx>>,
sop: GalSop,
) -> Term {
let table = sop.parameters.table.as_bytes(); let table = sop.parameters.table.as_bytes();
let n_products = sop.parameters.depth; let n_products = sop.parameters.depth;
@ -178,7 +203,7 @@ fn make_term_from_sop(graph: &Graph, sop: GalSop, pcf: &PcfFile) -> Term {
let net_for_pin = input_nets.get(idx).unwrap(); let net_for_pin = input_nets.get(idx).unwrap();
// now use the helper to find the true hardware pin // now use the helper to find the true hardware pin
let hwpin: usize = let hwpin: usize =
find_hwpin_for_net(graph, pcf, net_for_pin).unwrap() as usize; find_hwpin_for_net(graph, pcf, olmcmap, net_for_pin).unwrap() as usize;
// we now have our hardware pin number! // we now have our hardware pin number!
match *product { match *product {
"01" => Some(Pin { "01" => Some(Pin {
@ -306,7 +331,7 @@ pub fn graph_convert(graph: &Graph, pcf: PcfFile, chip: Chip) -> anyhow::Result<
// find the smallest row that fits. // find the smallest row that fits.
info!("Starting deferred mapping process"); info!("Starting deferred mapping process");
for olmc in deferrals { for olmc in deferrals {
let row = map_remaining_olmc(graph, olmc, &unused_rows, &olmcmap)?; let row = map_remaining_olmc(graph, olmc, &unused_rows)?;
debug!("Found a mapping for {olmc} in row {} size {}", row.0, row.1); debug!("Found a mapping for {olmc} in row {} size {}", row.0, row.1);
// insert into the mapping // insert into the mapping
olmcmap[row.0] = Some(olmc); olmcmap[row.0] = Some(olmc);
@ -322,9 +347,9 @@ pub fn graph_convert(graph: &Graph, pcf: PcfFile, chip: Chip) -> anyhow::Result<
match olmc { match olmc {
Some(node) => { Some(node) => {
debug!("Mapping node {node} at row {idx}"); debug!("Mapping node {node} at row {idx}");
let sop = get_sop_for_olmc(graph, node, &olmcmap)?; let sop = get_sop_for_olmc(graph, node)?;
debug!("Got SOP {:?} attached to node", sop); debug!("Got SOP {:?} attached to node", sop);
let term = make_term_from_sop(graph, sop, &pcf); let term = make_term_from_sop(graph, &pcf, &olmcmap, sop);
debug!("Got term {:?}", term); debug!("Got term {:?}", term);
let gal_olmc_node = graph.get_node(node).unwrap(); let gal_olmc_node = graph.get_node(node).unwrap();
if let Node::Olmc(o) = gal_olmc_node { if let Node::Olmc(o) = gal_olmc_node {
@ -343,7 +368,7 @@ pub fn graph_convert(graph: &Graph, pcf: PcfFile, chip: Chip) -> anyhow::Result<
"Setting base for olmc outpin: {:?}, pinmode: {:?}", "Setting base for olmc outpin: {:?}, pinmode: {:?}",
outpin, pinmode outpin, pinmode
); );
bp.olmcs[idx].set_base(&outpin, term, pinmode)?; bp.olmcs[idx].set_base(&outpin, term, pinmode);
} else { } else {
panic!("screaming"); panic!("screaming");
} }