diff --git a/compiler/src/fitter.rs b/compiler/src/fitter.rs index 9c041b6..8d9c244 100644 --- a/compiler/src/fitter.rs +++ b/compiler/src/fitter.rs @@ -1,5 +1,5 @@ use crate::pcf::PcfFile; -use crate::yosys_parser::{GalOLMC, Graph, NamedPort, Net}; +use crate::yosys_parser::{GalOLMC, GalSop, Graph, NamedPort, Net, Node}; use galette::blueprint::Blueprint; use galette::chips::Chip; use log::info; @@ -16,12 +16,63 @@ pub enum MappingError { #[error("Could not find the SOP input")] MissingSOP, + #[error("Could not find a sop to fit {0}")] + SopTooBig(usize), + #[error("Unknown error")] Unknown, } // attempt to map graph into blueprint +/// Acquire the SOP associated with the OLMC. If it's +fn get_sop_for_olmc(graph: &Graph, olmc_idx: usize) -> Result { + let input = graph.get_node_port_conns(olmc_idx, "A"); + assert_eq!(input.len(), 1, "OLMC input should have one netadjpair"); + let other_node = input[0].get_other(olmc_idx); + let sop = graph + .get_node(other_node.0) + .ok_or(MappingError::MissingSOP)?; + if let Node::Sop(s) = sop { + Ok(s.clone()) + } else { + Err(MappingError::MissingSOP) + } +} + +fn map_remaining_olcm(graph: &Graph, olmc: usize, unused: Vec<(usize, usize)>) -> Result { + // (index, size) + let mut chosen_row: Option<(usize, usize)> = None; + // FIXME: implement. + let sopsize: usize = get_sop_for_olmc(graph, olmc)?.parameters.depth as usize; + + for (olmc_idx, size) in unused { + match chosen_row { + None => { + if size > sopsize { + chosen_row = Some((olmc_idx, size)); + } + } + Some(r) => { + // we do the comparison (size > SOP Size) + if size < r.1 && size > sopsize { + chosen_row = Some((olmc_idx, size)); + } + } + } + } + // at the end, if we have chosen a row, we can swap it in. + match chosen_row { + Some((row, size)) => { + info!("mapping {olmc} size {sopsize} to row {row} with size {size}"); + Ok(row) + }, + None => { + Err(MappingError::SopTooBig(sopsize)) + } + } +} + #[derive(Debug, Clone)] struct GALMapEntry(GalOLMC, usize); // data and the entry in the graph @@ -35,8 +86,10 @@ pub fn graph_convert(graph: &Graph, pcf: PcfFile, chip: Chip) -> anyhow::Result< let mut deferrals: Vec = Vec::new(); + // For all the OLMCs in the graph, we either map it directly since it's constrained to a pin, + // or we defer it to later. for o in graph.get_olmc_idx() { - // find all the nodes named + // find all the let others: Vec = graph .get_node_port_conns(o, "Y") .iter() @@ -56,6 +109,7 @@ pub fn graph_convert(graph: &Graph, pcf: PcfFile, chip: Chip) -> anyhow::Result< let olmc_row = chip .pin_to_olmc(pin.try_into()?) .ok_or(MappingError::Unknown)?; + // TODO: check size of row vs size of SOP info!("Found a real pin to map: Mapping node {o} onto row {olmc_row}"); olmcmap[olmc_row] = Some(o); } @@ -72,37 +126,14 @@ pub fn graph_convert(graph: &Graph, pcf: PcfFile, chip: Chip) -> anyhow::Result< // to map remainders, we need to find the smallest SOP. // // Vec<(olmc_index,size)> - let unused_rows = - olmcmap - .iter() - .enumerate() - .filter_map(|(i, x)| if !x.is_some() { Some(i) } else { None }) - .map(|i| (i, chip.num_rows_for_olmc(i))); + let unused_rows = olmcmap + .iter() + .enumerate() + .filter_map(|(i, x)| if !x.is_some() { Some(i) } else { None }) + .map(|i| (i, chip.num_rows_for_olmc(i))); // find the smallest row that fits. let olmc = deferrals[0]; - let mut chosen_row: Option<(usize, usize)> = None; - // FIXME: implement. - let sopsize = 0; - - for (olmc_idx, size) in unused_rows { - - match chosen_row { - None => { - if size > sopsize { - chosen_row = Some((olmc_idx, size)); - } - }, - Some(r) => { - // we do the comparison (size > SOP Size) - if size < r.1 && size > sopsize { - chosen_row = Some((olmc_idx, size)); - } - } - } - } - - Ok(bp) }