cleanup errors, looping feedback in place

This commit is contained in:
saji 2024-05-05 02:26:21 -05:00
parent e5a1f84bf8
commit 22ef300f0a
3 changed files with 53 additions and 32 deletions

View file

@ -1,3 +1,4 @@
use std::error::Error;
use std::str::from_utf8; use std::str::from_utf8;
use crate::pcf::PcfFile; use crate::pcf::PcfFile;
@ -6,6 +7,7 @@ use crate::yosys_parser::{
}; };
use galette::blueprint::{Blueprint, PinMode}; use galette::blueprint::{Blueprint, PinMode};
use galette::chips::Chip; use galette::chips::Chip;
use galette::errors;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
use thiserror::Error; use thiserror::Error;
@ -31,6 +33,9 @@ pub enum MappingError {
#[error("Unknown error")] #[error("Unknown error")]
Unknown, Unknown,
#[error("galette error")]
Galette(#[from] galette::errors::ErrorCode),
} }
// attempt to map graph into blueprint // attempt to map graph into blueprint
@ -248,7 +253,7 @@ fn valid_inputs(chip: Chip) -> Vec<u32> {
} }
} }
pub fn graph_convert(graph: &Graph, pcf: PcfFile, chip: Chip) -> anyhow::Result<Blueprint> { pub fn graph_convert(graph: &Graph, pcf: &PcfFile, chip: Chip) -> Result<Blueprint, MappingError> {
let mut bp = Blueprint::new(chip); let mut bp = Blueprint::new(chip);
let valid_inp = valid_inputs(chip); let valid_inp = valid_inputs(chip);
@ -303,7 +308,7 @@ pub fn graph_convert(graph: &Graph, pcf: PcfFile, chip: Chip) -> anyhow::Result<
.lookup(&pcf) .lookup(&pcf)
.ok_or(MappingError::MissingConstraint(port.clone()))?; .ok_or(MappingError::MissingConstraint(port.clone()))?;
let olmc_row = chip let olmc_row = chip
.pin_to_olmc(pin.try_into()?) .pin_to_olmc(pin as usize)
.ok_or(MappingError::Unknown)?; .ok_or(MappingError::Unknown)?;
// TODO: check size of row vs size of SOP // TODO: check size of row vs size of SOP
// FIXME: -0 to size if registered, if comb, size - 1 // FIXME: -0 to size if registered, if comb, size - 1

View file

@ -1,20 +1,23 @@
mod fitter;
pub mod pcf; pub mod pcf;
pub mod yosys_parser; pub mod yosys_parser;
mod fitter;
use clap::{Parser, Subcommand, ValueEnum, Args}; use crate::fitter::{graph_convert, MappingError};
use crate::pcf::{parse_pcf, PcfFile};
use crate::yosys_parser::{Graph, YosysDoc};
use anyhow::{bail, Result};
use clap::{Args, Parser, Subcommand, ValueEnum};
use env_logger;
use galette::blueprint::Blueprint;
use galette::chips::Chip;
use galette::gal_builder::build; use galette::gal_builder::build;
use galette::writer::{make_jedec, Config}; use galette::writer::{make_jedec, Config};
use crate::pcf::parse_pcf;
use crate::yosys_parser::{YosysDoc, Graph};
use crate::fitter::graph_convert;
use anyhow::{bail, Result};
use serde_json::from_slice; use serde_json::from_slice;
use std::fs::{self, File};
use std::io::Write; use std::io::Write;
use std::path::PathBuf; use std::path::PathBuf;
use galette::chips::Chip; use std::process::Command;
use std::fs::{self, File}; use log::{info, warn};
use env_logger;
#[derive(Parser)] #[derive(Parser)]
struct Cli { struct Cli {
@ -38,7 +41,7 @@ struct ValidateArgs {
#[derive(ValueEnum, Debug, Clone)] #[derive(ValueEnum, Debug, Clone)]
enum ChipType { enum ChipType {
GAL16V8, GAL16V8,
GAL22V10 GAL22V10,
} }
impl ChipType { impl ChipType {
@ -50,7 +53,6 @@ impl ChipType {
} }
} }
#[derive(Args)] #[derive(Args)]
struct SynthArgs { struct SynthArgs {
#[arg(required = true, value_hint = clap::ValueHint::DirPath)] #[arg(required = true, value_hint = clap::ValueHint::DirPath)]
@ -59,10 +61,9 @@ struct SynthArgs {
constraints: PathBuf, constraints: PathBuf,
#[arg(value_enum, long, default_value_t=ChipType::GAL16V8)] #[arg(value_enum, long, default_value_t=ChipType::GAL16V8)]
chip: ChipType chip: ChipType,
} }
fn validate(v: ValidateArgs) -> Result<()> { fn validate(v: ValidateArgs) -> Result<()> {
let f = fs::read(v.file)?; let f = fs::read(v.file)?;
@ -80,30 +81,44 @@ fn validate(v: ValidateArgs) -> Result<()>{
Ok(()) Ok(())
} }
fn load_to_graph(
netlist: &PathBuf,
pcf: &PcfFile,
chip: Chip,
) -> Result<Blueprint, MappingError> {
info!("loading netlist...");
let f = fs::read(netlist).unwrap();
fn synth(s: SynthArgs) -> Result<()> { let data: YosysDoc = from_slice(f.as_slice()).unwrap();
let f = fs::read(s.netlist)?;
let data: YosysDoc = from_slice(f.as_slice())?;
let g = Graph::from(data); let g = Graph::from(data);
let res = g.validate().map_err(|x| x.to_string()); g.validate().map_err(|x| x.to_string()).unwrap();
if let Err(e) = res {
bail!(e);
}
println!("Validation Complete!"); println!("Validation Complete!");
println!("Stats:"); println!("Stats:");
println!("Nodes: {}", g.nodelist.len()); println!("Nodes: {}", g.nodelist.len());
println!("Edges: {}", g.adjlist.len()); println!("Edges: {}", g.adjlist.len());
graph_convert(&g, pcf, chip)
}
fn synth(s: SynthArgs) -> Result<()> {
// load the pcf // load the pcf
let pcf_file = &fs::read(s.constraints)?; let pcf_file = &fs::read(s.constraints)?;
let pcf_string = std::str::from_utf8(pcf_file)?; let pcf_string = std::str::from_utf8(pcf_file)?;
let pcf = parse_pcf(pcf_string); let pcf = parse_pcf(pcf_string);
let res = graph_convert(&g, pcf, s.chip.to_galette())?; let mut res = load_to_graph(&s.netlist, &pcf, s.chip.to_galette());
let mut gal = build(&res)?; while let Err(MappingError::SopTooBig { ref name, sop_size, wanted_size }) = res {
warn!("Sop too large, attempting to split {name}. cur={sop_size} want={wanted_size}");
let yosys = Command::new("yosys").args(["split_sop.tcl"]);
res = load_to_graph(&s.netlist, &pcf, s.chip.to_galette());
}
let bp = res?;
let mut gal = build(&bp)?;
if matches!(s.chip, ChipType::GAL16V8) { if matches!(s.chip, ChipType::GAL16V8) {
gal.set_mode(galette::gal::Mode::Registered); gal.set_mode(galette::gal::Mode::Registered);
@ -113,7 +128,7 @@ fn synth(s: SynthArgs) -> Result<()> {
gen_pin: false, gen_pin: false,
gen_fuse: false, gen_fuse: false,
gen_chip: false, gen_chip: false,
jedec_sec_bit: false jedec_sec_bit: false,
}; };
let mut file = File::create("output.jed")?; let mut file = File::create("output.jed")?;

View file

@ -517,7 +517,8 @@ impl From<YosysDoc> for Graph {
YosysCell::Sop(s) => Node::Sop(s), YosysCell::Sop(s) => Node::Sop(s),
YosysCell::OLMC(n) => Node::Olmc(n), YosysCell::OLMC(n) => Node::Olmc(n),
}; };
newcell.set_name(&cell_name); let fully_qualified_name = format!("{mod_name}/{cell_name}");
newcell.set_name(&fully_qualified_name);
g.nodelist.push(newcell); g.nodelist.push(newcell);
} }
for (port_name, port) in module.ports { for (port_name, port) in module.ports {