logicaffeine_compile/codegen_sva/
verified_compiler.rs1use super::fol_to_sva::{synthesize_sva_from_spec, SynthesizedSva};
10use super::sva_model::parse_sva;
11use super::{SvaProperty, SvaAssertionKind, emit_sva_property};
12use std::collections::hash_map::DefaultHasher;
13use std::hash::{Hash, Hasher};
14
15#[derive(Debug, Clone)]
20pub struct CompiledGenerator {
21 cached_body: String,
22 cached_signals: Vec<String>,
23 cached_kind: String,
24 spec_hash: u64,
25}
26
27impl CompiledGenerator {
28 pub fn generate(&self, clock: &str) -> Result<SynthesizedSva, String> {
33 let sva_text = format!(
34 "property p_compiled;\n @(posedge {}) {};\nendproperty\nassert property (p_compiled);",
35 clock, self.cached_body
36 );
37 Ok(SynthesizedSva {
38 sva_text,
39 body: self.cached_body.clone(),
40 signals: self.cached_signals.clone(),
41 kind: self.cached_kind.clone(),
42 })
43 }
44
45 pub fn spec_hash(&self) -> u64 {
47 self.spec_hash
48 }
49
50 pub fn body(&self) -> &str {
52 &self.cached_body
53 }
54
55 pub fn signals(&self) -> &[String] {
57 &self.cached_signals
58 }
59}
60
61pub struct SvaCompiler;
66
67impl SvaCompiler {
68 pub fn compile(&self, spec: &str) -> Result<CompiledGenerator, String> {
72 compile_sva_generator(spec)
73 }
74}
75
76pub fn compile_sva_generator(spec: &str) -> Result<CompiledGenerator, String> {
81 let synthesized = synthesize_sva_from_spec(spec, "clk")?;
83
84 let mut hasher = DefaultHasher::new();
86 spec.hash(&mut hasher);
87 let spec_hash = hasher.finish();
88
89 Ok(CompiledGenerator {
90 cached_body: synthesized.body,
91 cached_signals: synthesized.signals,
92 cached_kind: synthesized.kind,
93 spec_hash,
94 })
95}
96
97pub fn compile_sva_compiler() -> SvaCompiler {
101 SvaCompiler
102}
103
104pub fn verify_compiler_correctness(spec: &str, clock: &str) -> bool {
109 let interpreted = match synthesize_sva_from_spec(spec, clock) {
110 Ok(s) => s,
111 Err(_) => return false,
112 };
113
114 let compiled = match compile_sva_generator(spec) {
115 Ok(gen) => match gen.generate(clock) {
116 Ok(s) => s,
117 Err(_) => return false,
118 },
119 Err(_) => return false,
120 };
121
122 let mut int_signals = interpreted.signals.clone();
124 let mut comp_signals = compiled.signals.clone();
125 int_signals.sort();
126 comp_signals.sort();
127 interpreted.body == compiled.body
128 && int_signals == comp_signals
129 && interpreted.kind == compiled.kind
130}