mirror of
				https://github.com/YosysHQ/sby.git
				synced 2025-11-04 06:39:11 +00:00 
			
		
		
		
	Add aigcxemin and cexenum.py tools
This commit is contained in:
		
							parent
							
								
									9e35ec9948
								
							
						
					
					
						commit
						040b8deef2
					
				
					 11 changed files with 2223 additions and 0 deletions
				
			
		
							
								
								
									
										145
									
								
								tools/aigcexmin/src/main.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								tools/aigcexmin/src/main.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,145 @@
 | 
			
		|||
#![allow(clippy::needless_range_loop)]
 | 
			
		||||
 | 
			
		||||
use std::{fs, mem::replace, path::PathBuf};
 | 
			
		||||
 | 
			
		||||
use clap::{Parser, ValueEnum};
 | 
			
		||||
use color_eyre::eyre::bail;
 | 
			
		||||
 | 
			
		||||
use flussab_aiger::binary;
 | 
			
		||||
 | 
			
		||||
pub mod aig_eval;
 | 
			
		||||
pub mod care_graph;
 | 
			
		||||
pub mod util;
 | 
			
		||||
 | 
			
		||||
/// AIG counter example minimization
 | 
			
		||||
#[derive(clap::Parser)]
 | 
			
		||||
#[command(author, version, about, long_about = None, help_template="\
 | 
			
		||||
{before-help}{name} {version}
 | 
			
		||||
{author-with-newline}{about-with-newline}
 | 
			
		||||
{usage-heading} {usage}
 | 
			
		||||
 | 
			
		||||
{all-args}{after-help}
 | 
			
		||||
")]
 | 
			
		||||
pub struct Options {
 | 
			
		||||
    /// Input AIGER file
 | 
			
		||||
    aig: PathBuf,
 | 
			
		||||
    /// Input AIGER witness file
 | 
			
		||||
    witness: PathBuf,
 | 
			
		||||
    /// Output AIGER witness file
 | 
			
		||||
    output: PathBuf,
 | 
			
		||||
 | 
			
		||||
    /// Verify the minimized counter example
 | 
			
		||||
    #[clap(long, default_value = "cex")]
 | 
			
		||||
    verify: VerificationOption,
 | 
			
		||||
 | 
			
		||||
    /// Minimize latch initialization values
 | 
			
		||||
    ///
 | 
			
		||||
    /// Without this option the latch initialization values of the witness file are assumed to be
 | 
			
		||||
    /// fixed and will remain as-is in the minimized witness file.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Note that some tools (including the current Yosys/SBY flow) do not use AIGER native latch
 | 
			
		||||
    /// initialization but instead perform initialization using inputs in the first frame.
 | 
			
		||||
    #[clap(long)]
 | 
			
		||||
    latches: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Copy, Clone, ValueEnum)]
 | 
			
		||||
enum VerificationOption {
 | 
			
		||||
    /// Skip verification
 | 
			
		||||
    Off,
 | 
			
		||||
    /// Verify the counter example
 | 
			
		||||
    Cex,
 | 
			
		||||
    /// Verify the counter example and that it is minimal (expensive)
 | 
			
		||||
    Full,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() -> color_eyre::Result<()> {
 | 
			
		||||
    let options = Options::parse();
 | 
			
		||||
 | 
			
		||||
    color_eyre::install()?;
 | 
			
		||||
 | 
			
		||||
    let file_input = fs::File::open(options.aig)?;
 | 
			
		||||
    let file_witness = fs::File::open(options.witness)?;
 | 
			
		||||
    let file_output = fs::File::create(options.output)?;
 | 
			
		||||
 | 
			
		||||
    let mut writer_output = flussab::DeferredWriter::from_write(file_output);
 | 
			
		||||
 | 
			
		||||
    let mut read_witness_owned = flussab::DeferredReader::from_read(file_witness);
 | 
			
		||||
    let read_witness = &mut read_witness_owned;
 | 
			
		||||
 | 
			
		||||
    let aig_reader = binary::Parser::<u32>::from_read(file_input, binary::Config::default())?;
 | 
			
		||||
 | 
			
		||||
    let aig = aig_reader.parse()?;
 | 
			
		||||
 | 
			
		||||
    let mut offset = 0;
 | 
			
		||||
    offset = flussab::text::next_newline(read_witness, offset);
 | 
			
		||||
 | 
			
		||||
    if offset == 2 {
 | 
			
		||||
        read_witness.advance(replace(&mut offset, 0));
 | 
			
		||||
        offset = flussab::text::next_newline(read_witness, offset);
 | 
			
		||||
        read_witness.advance(replace(&mut offset, 0));
 | 
			
		||||
 | 
			
		||||
        offset = flussab::text::next_newline(read_witness, offset);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if offset != aig.latches.len() + 1 {
 | 
			
		||||
        bail!(
 | 
			
		||||
            "unexpected number of initial latch states, found {} expected {}",
 | 
			
		||||
            offset.saturating_sub(1),
 | 
			
		||||
            aig.latches.len()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let latch_init = read_witness.buf()[..aig.latches.len()]
 | 
			
		||||
        .iter()
 | 
			
		||||
        .copied()
 | 
			
		||||
        .map(util::parse_input_bit)
 | 
			
		||||
        .collect::<Result<Vec<_>, _>>()?;
 | 
			
		||||
 | 
			
		||||
    read_witness.advance(replace(&mut offset, 0));
 | 
			
		||||
 | 
			
		||||
    let mut frame_inputs = vec![];
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
        offset = flussab::text::next_newline(read_witness, offset);
 | 
			
		||||
 | 
			
		||||
        if matches!(read_witness.buf().first(), None | Some(b'.') | Some(b'#')) {
 | 
			
		||||
            read_witness.check_io_error()?;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if offset != aig.input_count + 1 {
 | 
			
		||||
            bail!(
 | 
			
		||||
                "unexpected number of input bits, found {} expected {}",
 | 
			
		||||
                offset.saturating_sub(1),
 | 
			
		||||
                aig.input_count
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        frame_inputs.push(
 | 
			
		||||
            read_witness.buf()[..aig.input_count]
 | 
			
		||||
                .iter()
 | 
			
		||||
                .copied()
 | 
			
		||||
                .map(util::parse_input_bit)
 | 
			
		||||
                .collect::<Result<Vec<_>, _>>()?,
 | 
			
		||||
        );
 | 
			
		||||
        read_witness.advance(replace(&mut offset, 0));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    care_graph::minimize(
 | 
			
		||||
        &aig,
 | 
			
		||||
        &latch_init,
 | 
			
		||||
        &frame_inputs,
 | 
			
		||||
        &mut writer_output,
 | 
			
		||||
        &care_graph::MinimizationOptions {
 | 
			
		||||
            fixed_init: !options.latches,
 | 
			
		||||
            verify: match options.verify {
 | 
			
		||||
                VerificationOption::Off => None,
 | 
			
		||||
                VerificationOption::Cex => Some(care_graph::Verification::Cex),
 | 
			
		||||
                VerificationOption::Full => Some(care_graph::Verification::Full),
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    )?;
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue