mirror of
https://github.com/annoyatron255/yosys4gal.git
synced 2024-12-22 18:52:23 +00:00
cleanup errors, looping feedback in place
This commit is contained in:
parent
e5a1f84bf8
commit
22ef300f0a
|
@ -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
|
||||||
|
|
|
@ -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,11 +61,10 @@ 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)?;
|
||||||
|
|
||||||
let data: YosysDoc = from_slice(f.as_slice())?;
|
let data: YosysDoc = from_slice(f.as_slice())?;
|
||||||
|
@ -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")?;
|
||||||
|
@ -124,7 +139,7 @@ fn synth(s: SynthArgs) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()>{
|
fn main() -> Result<()> {
|
||||||
let args = Cli::parse();
|
let args = Cli::parse();
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
match args.command {
|
match args.command {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue