logicaffeine_compile/codegen_sva/
signoff_blocks.rs1use super::flow_config::SynthStrategy;
10
11#[derive(Debug, Clone, Copy)]
13pub struct SignoffBlock {
14 pub name: &'static str,
15 pub period_ns: f64,
16 pub synth_strategy: Option<SynthStrategy>,
20 pub basis: &'static str,
22}
23
24pub const SLOW_CORNER_MARGIN: f64 = 1.05;
28
29pub fn honest_period_ns(period_ns: f64, slowest_setup_slack_ns: f64) -> f64 {
36 if !slowest_setup_slack_ns.is_sign_negative() {
37 return period_ns;
38 }
39 let required = (period_ns - slowest_setup_slack_ns) * SLOW_CORNER_MARGIN;
40 (required * 2.0 - 1e-9).ceil() / 2.0
41}
42
43macro_rules! block {
44 ($name:literal, $was:literal, $slack:literal, $run:literal) => {
45 block!($name, $was, $slack, $run, None)
46 };
47 ($name:literal, $was:literal, $slack:literal, $run:literal, $strategy:expr) => {
48 SignoffBlock {
49 name: $name,
50 period_ns: honest_period_ns($was, $slack),
51 synth_strategy: $strategy,
52 basis: concat!(
53 "worst setup across every corner ",
54 stringify!($slack),
55 " ns at ",
56 stringify!($was),
57 " ns, ",
58 $run
59 ),
60 }
61 };
62}
63
64#[allow(unused_macros)]
68macro_rules! seeded {
69 ($name:literal from $sibling:literal, $was:literal, $slack:literal, $run:literal) => {
70 SignoffBlock {
71 name: $name,
72 period_ns: honest_period_ns($was, $slack),
73 synth_strategy: None,
74 basis: concat!(
75 "seeded from ",
76 $sibling,
77 ": worst setup across every corner ",
78 stringify!($slack),
79 " ns at ",
80 stringify!($was),
81 " ns, ",
82 $run
83 ),
84 }
85 };
86}
87
88pub static SIGNOFF_BLOCKS: std::sync::LazyLock<Vec<SignoffBlock>> =
92 std::sync::LazyLock::new(|| {
93 vec![
94 block!(
95 "rev_alu_core",
96 7.7,
97 0.14,
98 "RUN_2026.10.17_18.20.14",
99 Some(SynthStrategy::Delay(0))
100 ),
101 block!("soft_core_scalar", 15.0, 0.41, "RUN_2026.10.15_17.14.37"),
102 block!(
103 "cgra_sumto",
104 6.4,
105 0.11,
106 "RUN_2026.10.17_17.32.11",
107 Some(SynthStrategy::Delay(0))
108 ),
109 block!("nested_tri", 16.5, 0.07, "RUN_2026.10.15_08.18.56"),
110 block!(
111 "dram_executor",
112 5.0,
113 0.03,
114 "RUN_2026.10.17_16.50.21",
115 Some(SynthStrategy::Delay(0))
116 ),
117 block!(
118 "infinichip",
119 8.1,
120 0.01,
121 "RUN_2026.10.18_18.34.30",
122 Some(SynthStrategy::Delay(0))
123 ),
124 block!(
125 "dram_executor_wb",
126 4.8,
127 0.12,
128 "RUN_2026.10.17_17.19.18",
129 Some(SynthStrategy::Delay(0))
130 ),
131 block!("dpu_ingest", 14.5, 1.66, "RUN_2026.10.15_16.56.32"),
132 block!("coproc_core", 67.0, 0.31, "RUN_2026.10.15_18.29.32"),
133 block!("gpu_simt", 19.5, 0.28, "RUN_2026.10.15_16.58.45"),
134 block!(
135 "decision_hft_bist",
136 4.4,
137 0.06,
138 "RUN_2026.10.17_17.04.21",
139 Some(SynthStrategy::Delay(0))
140 ),
141 block!(
142 "decision_hft_realbist",
143 10.8,
144 0.02,
145 "RUN_2026.10.18_16.36.28",
146 Some(SynthStrategy::Delay(0))
147 ),
148 block!("fabric_horner_seq", 41.0, 0.98, "RUN_2026.10.20_17.57.25"),
149 block!("fabric_soc", 468.0, 6.89, "RUN_2026.10.15_17.51.57"),
150 block!(
151 "gemm_mac_realbist",
152 9.4,
153 0.06,
154 "RUN_2026.10.18_19.21.23",
155 Some(SynthStrategy::Delay(0))
156 ),
157 block!(
158 "systolic_tile_realbist",
159 21.0,
160 2.62,
161 "RUN_2026.10.15_17.21.09"
162 ),
163 block!(
164 "systolic_pipe8_realbist",
165 15.0,
166 0.34,
167 "RUN_2026.10.15_17.27.18"
168 ),
169 block!(
170 "systolic_os_pipe8_realbist",
171 20.5,
172 1.86,
173 "RUN_2026.10.20_18.30.02"
174 ),
175 block!("dram_user_project", 20.0, 7.15, "RUN_2026.10.16_07.41.44"),
176 block!(
177 "systolic_pipe16_realbist",
178 19.5,
179 0.47,
180 "RUN_2026.10.17_05.49.26"
181 ),
182 block!("soft_core_realbist", 24.5, 0.4, "RUN_2026.10.15_17.39.59"),
183 block!(
184 "psram_edge",
185 5.8,
186 0.05,
187 "RUN_2026.10.17_18.00.41",
188 Some(SynthStrategy::Delay(0))
189 ),
190 ]
191 });
192
193pub fn registered_period_ns(name: &str) -> Option<f64> {
195 SIGNOFF_BLOCKS
196 .iter()
197 .find(|b| b.name == name)
198 .map(|b| b.period_ns)
199}
200
201pub fn registered_synth_strategy(name: &str) -> Option<Option<SynthStrategy>> {
204 SIGNOFF_BLOCKS
205 .iter()
206 .find(|b| b.name == name)
207 .map(|b| b.synth_strategy)
208}
209
210pub fn resolve_synth_strategy(
214 name: &str,
215 asked: Option<Option<SynthStrategy>>,
216) -> Result<Option<SynthStrategy>, String> {
217 let spell = |s: Option<SynthStrategy>| s.map_or_else(|| "default".to_string(), |s| s.flag());
218 match (registered_synth_strategy(name), asked) {
219 (Some(reg), Some(a)) if a != reg => Err(format!(
220 "{} is not the registered synthesis strategy for {name}: it is {}, the strategy its signoff period was \
221 measured under (codegen_sva::signoff_blocks)",
222 spell(a),
223 spell(reg)
224 )),
225 (Some(reg), _) => Ok(reg),
226 (None, a) => Ok(a.flatten()),
227 }
228}