mirror of
https://github.com/annoyatron255/yosys4gal.git
synced 2024-12-22 18:52:23 +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]]
|
[[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"
|
||||||
|
|
|
@ -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"] }
|
||||||
|
|
|
@ -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,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,
|
// 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)?;
|
||||||
_ => None,
|
match node {
|
||||||
|
Node::Input(_) => Some(node),
|
||||||
|
Node::Olmc(_) => Some(node),
|
||||||
|
_ => 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")
|
|
||||||
.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) {
|
match inputs[0] {
|
||||||
debug!("Found a port after traversing inputs, {:?}", p);
|
Node::Input(_) => {
|
||||||
// look up the pin.
|
let port_nets = conns.get("A").ok_or(MappingError::Unknown)?;
|
||||||
p.lookup(pcf)
|
assert_eq!(port_nets.len(), 1, "should only be one input to GAL_INPUT");
|
||||||
.ok_or(MappingError::MissingConstraint(p.clone()))
|
let pnet = &port_nets[0];
|
||||||
} else {
|
|
||||||
Err(MappingError::Unknown)
|
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.
|
/// 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");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue