use super::fol_to_sva::{synthesize_sva_from_spec, SynthesizedSva};
use super::sva_model::parse_sva;
use super::{SvaProperty, SvaAssertionKind, emit_sva_property};
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone)]
pub struct CompiledGenerator {
cached_body: String,
cached_signals: Vec<String>,
cached_kind: String,
spec_hash: u64,
}
impl CompiledGenerator {
pub fn generate(&self, clock: &str) -> Result<SynthesizedSva, String> {
let sva_text = format!(
"property p_compiled;\n @(posedge {}) {};\nendproperty\nassert property (p_compiled);",
clock, self.cached_body
);
Ok(SynthesizedSva {
sva_text,
body: self.cached_body.clone(),
signals: self.cached_signals.clone(),
kind: self.cached_kind.clone(),
})
}
pub fn spec_hash(&self) -> u64 {
self.spec_hash
}
pub fn body(&self) -> &str {
&self.cached_body
}
pub fn signals(&self) -> &[String] {
&self.cached_signals
}
}
pub struct SvaCompiler;
impl SvaCompiler {
pub fn compile(&self, spec: &str) -> Result<CompiledGenerator, String> {
compile_sva_generator(spec)
}
}
pub fn compile_sva_generator(spec: &str) -> Result<CompiledGenerator, String> {
let synthesized = synthesize_sva_from_spec(spec, "clk")?;
let mut hasher = DefaultHasher::new();
spec.hash(&mut hasher);
let spec_hash = hasher.finish();
Ok(CompiledGenerator {
cached_body: synthesized.body,
cached_signals: synthesized.signals,
cached_kind: synthesized.kind,
spec_hash,
})
}
pub fn compile_sva_compiler() -> SvaCompiler {
SvaCompiler
}
pub fn verify_compiler_correctness(spec: &str, clock: &str) -> bool {
let interpreted = match synthesize_sva_from_spec(spec, clock) {
Ok(s) => s,
Err(_) => return false,
};
let compiled = match compile_sva_generator(spec) {
Ok(gen) => match gen.generate(clock) {
Ok(s) => s,
Err(_) => return false,
},
Err(_) => return false,
};
let mut int_signals = interpreted.signals.clone();
let mut comp_signals = compiled.signals.clone();
int_signals.sort();
comp_signals.sort();
interpreted.body == compiled.body
&& int_signals == comp_signals
&& interpreted.kind == compiled.kind
}