mirror of
https://github.com/annoyatron255/yosys4gal.git
synced 2024-12-22 10:42:24 +00:00
use patched galette, make comb olmc case work
This commit is contained in:
parent
22f1a2a26b
commit
e41aef8440
11
compiler/Cargo.lock
generated
11
compiler/Cargo.lock
generated
|
@ -305,11 +305,12 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||
[[package]]
|
||||
name = "galette"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bacf731bf0e2b11cef74a9454c3e073e737e1423c0b94958da9131dd40a09f5"
|
||||
source = "git+https://github.com/5aji/galette.git#8d8e8247b4820cebd193b707f0f8d45f3d3b58bb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 2.34.0",
|
||||
"itertools",
|
||||
"test_bin",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
@ -615,6 +616,12 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test_bin"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e7a7de15468c6e65dd7db81cf3822c1ec94c71b2a3c1a976ea8e4696c91115c"
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
|
|
|
@ -9,7 +9,7 @@ edition = "2021"
|
|||
anyhow = "1.0.81"
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
env_logger = "0.11.3"
|
||||
galette = "0.3.0"
|
||||
galette = { git = "https://github.com/5aji/galette.git" }
|
||||
log = "0.4.21"
|
||||
regex = "1.10.4"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
|
|
|
@ -36,7 +36,6 @@ pub enum MappingError {
|
|||
fn get_sop_for_olmc(
|
||||
graph: &Graph,
|
||||
olmc_idx: &NodeIdx,
|
||||
olmcmap: &Vec<Option<NodeIdx>>,
|
||||
) -> Result<GalSop, MappingError> {
|
||||
let input = graph.get_node_port_conns(olmc_idx, "A");
|
||||
let sops_on_net: Vec<_> = input
|
||||
|
@ -48,28 +47,23 @@ fn get_sop_for_olmc(
|
|||
};
|
||||
let node = graph.get_node(&driver_cell.0)?;
|
||||
match node {
|
||||
Node::Sop(s) => Some(s),
|
||||
// Node::Olmc(o) => {
|
||||
// // find the row that contains this olmc.
|
||||
// // we know this exists because mapping has already finished.
|
||||
// let row = olmcmap.iter().position(|potential_match| {
|
||||
// match potential_match {
|
||||
// Some(row) => row == &driver_cell.0,
|
||||
// None => false,
|
||||
// }
|
||||
// }).unwrap();
|
||||
// let newsop = GalSop {
|
||||
// connections: HashMap::from([
|
||||
// ("A",
|
||||
// ]),
|
||||
// parameters: GalSopParameters {
|
||||
// depth: 1,
|
||||
// width: 1,
|
||||
// table: "10".to_string(),
|
||||
// },
|
||||
// };
|
||||
//
|
||||
// },
|
||||
Node::Sop(s) => Some(s.clone()),
|
||||
Node::Olmc(o) => {
|
||||
// find the row that contains this olmc.
|
||||
// we know this exists because mapping has already finished.
|
||||
let newsop = GalSop {
|
||||
connections: HashMap::from([
|
||||
("A".to_string(), vec![i.net.clone()]),
|
||||
]),
|
||||
parameters: GalSopParameters {
|
||||
depth: 1,
|
||||
width: 1,
|
||||
table: "10".to_string(),
|
||||
},
|
||||
};
|
||||
Some(newsop)
|
||||
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
|
@ -84,12 +78,11 @@ fn map_remaining_olmc(
|
|||
graph: &Graph,
|
||||
olmc: NodeIdx,
|
||||
unused: &Vec<(usize, usize)>,
|
||||
olmcmap: &Vec<Option<NodeIdx>>,
|
||||
) -> Result<(usize, usize), MappingError> {
|
||||
// (index, size)
|
||||
let mut chosen_row: Option<(usize, usize)> = None;
|
||||
// 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;
|
||||
|
||||
for (olmc_idx, size) in unused {
|
||||
|
@ -120,42 +113,74 @@ 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,
|
||||
// then it finds the port on the input of the GAL_INPUT.
|
||||
// find the input on the net.
|
||||
let inputs: Vec<&GalInput> = graph
|
||||
let inputs: Vec<&Node> = graph
|
||||
.find_nodes_on_net(net)
|
||||
.iter()
|
||||
.filter_map(|n| match graph.get_node(n) {
|
||||
Some(Node::Input(i)) => Some(i),
|
||||
_ => None,
|
||||
.filter_map(|n| {
|
||||
let node = graph.get_node(n)?;
|
||||
match node {
|
||||
Node::Input(_) => Some(node),
|
||||
Node::Olmc(_) => Some(node),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.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 {
|
||||
return Err(MappingError::Unknown);
|
||||
}
|
||||
|
||||
let port_nets = inputs[0]
|
||||
.connections
|
||||
.get("A")
|
||||
.ok_or(MappingError::Unknown)?;
|
||||
assert_eq!(port_nets.len(), 1, "should only be one input to GAL_INPUT");
|
||||
let pnet = &port_nets[0];
|
||||
let conns = inputs[0].get_connections();
|
||||
|
||||
if let Some(p) = graph.find_port(pnet) {
|
||||
debug!("Found a port after traversing inputs, {:?}", p);
|
||||
// look up the pin.
|
||||
p.lookup(pcf)
|
||||
.ok_or(MappingError::MissingConstraint(p.clone()))
|
||||
} else {
|
||||
Err(MappingError::Unknown)
|
||||
match inputs[0] {
|
||||
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");
|
||||
let pnet = &port_nets[0];
|
||||
|
||||
if let Some(p) = graph.find_port(pnet) {
|
||||
debug!("Found a port after traversing inputs, {:?}", p);
|
||||
// look up the pin.
|
||||
p.lookup(pcf)
|
||||
.ok_or(MappingError::MissingConstraint(p.clone()))
|
||||
} else {
|
||||
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.
|
||||
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 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();
|
||||
// now use the helper to find the true hardware pin
|
||||
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!
|
||||
match *product {
|
||||
"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.
|
||||
info!("Starting deferred mapping process");
|
||||
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);
|
||||
// insert into the mapping
|
||||
olmcmap[row.0] = Some(olmc);
|
||||
|
@ -322,9 +347,9 @@ pub fn graph_convert(graph: &Graph, pcf: PcfFile, chip: Chip) -> anyhow::Result<
|
|||
match olmc {
|
||||
Some(node) => {
|
||||
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);
|
||||
let term = make_term_from_sop(graph, sop, &pcf);
|
||||
let term = make_term_from_sop(graph, &pcf, &olmcmap, sop);
|
||||
debug!("Got term {:?}", term);
|
||||
let gal_olmc_node = graph.get_node(node).unwrap();
|
||||
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: {:?}",
|
||||
outpin, pinmode
|
||||
);
|
||||
bp.olmcs[idx].set_base(&outpin, term, pinmode)?;
|
||||
bp.olmcs[idx].set_base(&outpin, term, pinmode);
|
||||
} else {
|
||||
panic!("screaming");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue