diff --git a/docs/NOW.md b/docs/NOW.md index c80aedd8f..3d3eb99f9 100644 --- a/docs/NOW.md +++ b/docs/NOW.md @@ -1,3 +1,17 @@ +# NOW -- readiness is READY, for real (2026-08-20) + +Last updated: 2026-08-20 + +## fix(specs): the two unparseable fpga specs used braced TDD blocks (Closes #2251) + +- The first honest master run decomposed into three NAMED causes: apt-mirror + weather on conformance/formal (bounded retries failed fast as designed) and + synth-readiness NOT READY at 94% -- vcd_conformance_compare.t27 and + power_analysis.t27 wrote 64 tests, 7 invariants and 3 benches as braced + blocks; the language's TDD blocks are braceless and indentation-scoped +- Converted mechanically (open/close pairing asserted per family); both parse; + synth-readiness now reports 100%/100% READY FOR SYNTHESIS + # NOW -- the honest red has been repaired for real (2026-08-20) diff --git a/specs/fpga/power_analysis.t27 b/specs/fpga/power_analysis.t27 index 6a03d7fe9..1f94b7391 100644 --- a/specs/fpga/power_analysis.t27 +++ b/specs/fpga/power_analysis.t27 @@ -226,227 +226,188 @@ module PowerAnalysis { // === Tests === - test utilization_creation { + test utilization_creation given u = utilization(1000, 2000, 10, 8) then u.luts == 1000 and u.ffs == 2000 and u.brams == 10 and u.dsps == 8 - } - test utilization_full_creation { + test utilization_full_creation given u = utilization_full(500, 1000, 5, 4, 20, 100) then u.luts == 500 and u.ios == 20 and u.clock_mhz == 100 - } - test zero_utilization_all_zero { + test zero_utilization_all_zero given u = zero_utilization() then u.luts == 0 and u.ffs == 0 and total_resources(u) == 0 - } - test total_resources_sum { + test total_resources_sum given u = utilization(1000, 2000, 10, 8) then total_resources(u) == 3018 - } - test xc7a100t_limits { + test xc7a100t_limits given lim = xc7a100t_limits() then lim.max_luts == 63400 and lim.max_ffs == 126800 and lim.max_brams == 135 and lim.max_dsps == 240 - } - test xc7a35t_limits { + test xc7a35t_limits given lim = xc7a35t_limits() then lim.max_luts == 20800 and lim.name == "xc7a35t" - } - test lut_percent_calc { + test lut_percent_calc given u = utilization(6340, 0, 0, 0) and lim = xc7a100t_limits() then lut_percent(u, lim) == 10 - } - test overall_percent_calc { + test overall_percent_calc given u = utilization(6340, 12680, 13, 24) and lim = xc7a100t_limits() then overall_percent(u, lim) == 10 - } - test percent_zero_limits { + test percent_zero_limits given u = utilization(100, 0, 0, 0) and lim = DeviceLimits{.name = "test", .max_luts = 0, .max_ffs = 0, .max_brams = 0, .max_dsps = 0, .max_ios = 0} then lut_percent(u, lim) == 0 - } - test est_dynamic_power_basic { + test est_dynamic_power_basic given u = utilization(1000, 2000, 10, 8) then est_dynamic_power_mw(u, 12) > 0 - } - test est_static_power_basic { + test est_static_power_basic given u = utilization(1000, 2000, 10, 8) then est_static_power_mw(u) > 50 - } - test est_total_power_gt_dynamic { + test est_total_power_gt_dynamic given u = utilization(1000, 2000, 10, 8) then est_total_power_mw(u, 12) > est_dynamic_power_mw(u, 12) - } - test est_total_power_gt_static { + test est_total_power_gt_static given u = utilization(1000, 2000, 10, 8) then est_total_power_mw(u, 12) > est_static_power_mw(u) - } - test power_budget_creation { + test power_budget_creation given b = power_budget(2000) then b.target_mw == 2000 and b.warning_threshold_pct == 80 and b.critical_threshold_pct == 95 - } - test power_pct_of_budget { + test power_pct_of_budget given b = power_budget(1000) then power_pct_of_budget(800, b) == 80 - } - test is_within_budget_true { + test is_within_budget_true given b = power_budget(2000) then is_within_budget(1500, b) == true - } - test is_within_budget_false { + test is_within_budget_false given b = power_budget(1000) then is_within_budget(1500, b) == false - } - test is_warning_level { + test is_warning_level given b = power_budget(1000) then is_warning(850, b) == true - } - test is_critical_level { + test is_critical_level given b = power_budget(1000) then is_critical(960, b) == true - } - test is_not_warning_below_threshold { + test is_not_warning_below_threshold given b = power_budget(1000) then is_warning(500, b) == false - } - test default_toggle_rate_value { + test default_toggle_rate_value then default_toggle_rate() == 12 - } - test est_toggle_rate_from_activity { + test est_toggle_rate_from_activity then est_toggle_rate_from_activity(50) == 50 - } - test est_toggle_rate_clamped { + test est_toggle_rate_clamped then est_toggle_rate_from_activity(150) == 100 - } - test clock_domain_power_creation { + test clock_domain_power_creation given cdp = clock_domain_power("core", 100, 5000, 10000) then cdp.domain_name == "core" and cdp.clock_mhz == 100 and cdp.power_mw > 0 - } - test total_domain_power_sum { + test total_domain_power_sum given d1 = clock_domain_power("core", 100, 5000, 10000) and d2 = clock_domain_power("io", 50, 1000, 2000) and domains = [d1, d2] then total_domain_power(domains, 2) > 0 - } - test total_domain_power_empty { + test total_domain_power_empty then total_domain_power([], 0) == 0 - } - test validate_utilization_ok { + test validate_utilization_ok given u = utilization(100, 200, 1, 1) then validate_utilization(u) == 0 - } - test validate_utilization_zero_clock { + test validate_utilization_zero_clock given u = Utilization{.luts = 100, .ffs = 200, .brams = 1, .dsps = 1, .ios = 0, .clock_mhz = 0} then validate_utilization(u) > 0 - } - test validate_budget_ok { + test validate_budget_ok given b = power_budget(2000) then validate_budget(b) == 0 - } - test validate_budget_zero_target { + test validate_budget_zero_target given b = PowerBudget{.target_mw = 0, .warning_threshold_pct = 80, .critical_threshold_pct = 95} then validate_budget(b) > 0 - } - test validate_budget_inverted_thresholds { + test validate_budget_inverted_thresholds given b = PowerBudget{.target_mw = 2000, .warning_threshold_pct = 95, .critical_threshold_pct = 80} then validate_budget(b) > 0 - } - test trinity_fpga_top_power_estimate { + test trinity_fpga_top_power_estimate given u = utilization_full(15000, 30000, 30, 50, 48, 50) var total = est_total_power_mw(u, 12); invariant total > 0; - } - test trinity_fpga_top_within_typical_budget { + test trinity_fpga_top_within_typical_budget given u = utilization_full(15000, 30000, 30, 50, 48, 50) and b = power_budget(2000) var total = est_total_power_mw(u, 12); then is_within_budget(total, b) == true - } // === Invariants === - invariant total_resources_non_negative { + invariant total_resources_non_negative given u = utilization(0, 0, 0, 0) assert total_resources(u) >= 0 - } - invariant power_estimates_non_negative { + invariant power_estimates_non_negative given u = utilization(1000, 2000, 10, 8) assert est_total_power_mw(u, 12) >= 0 - } - invariant percent_within_bounds { + invariant percent_within_bounds given u = utilization(6340, 0, 0, 0) and lim = xc7a100t_limits() assert lut_percent(u, lim) <= 100 - } - invariant budget_pct_non_negative { + invariant budget_pct_non_negative given b = power_budget(1000) assert power_pct_of_budget(0, b) >= 0 - } // === Benchmarks === - bench power_analysis_full_latency { + bench power_analysis_full_latency given u = utilization_full(15000, 30000, 30, 50, 48, 50) measure: nanoseconds for est_total_power_mw(u, 12) target: < 200ns - } - bench utilization_percent_calc { + bench utilization_percent_calc given u = utilization_full(6340, 12680, 13, 24, 20, 50) and lim = xc7a100t_limits() measure: nanoseconds for overall_percent(u, lim) target: < 100ns - } } // phi^2 + 1/phi^2 = 3 | TRINITY diff --git a/specs/fpga/vcd_conformance_compare.t27 b/specs/fpga/vcd_conformance_compare.t27 index 010f54435..87b96481e 100644 --- a/specs/fpga/vcd_conformance_compare.t27 +++ b/specs/fpga/vcd_conformance_compare.t27 @@ -215,100 +215,85 @@ module VcdConformanceCompare { // === Tests === - test compare_result_init { + test compare_result_init given r = compare_result() then r.total_checks == 0 and r.passed == 0 and r.failed == 0 and r.errors == 0 - } - test record_pass_increments { + test record_pass_increments var r = compare_result(); record_pass(&r); invariant r.total_checks == 1; invariant r.passed == 1; - } - test record_fail_increments { + test record_fail_increments var r = compare_result(); record_fail(&r); invariant r.total_checks == 1; invariant r.failed == 1; - } - test record_error_increments { + test record_error_increments var r = compare_result(); record_error(&r); invariant r.total_checks == 1; invariant r.errors == 1; - } - test all_passed_true_when_no_failures { + test all_passed_true_when_no_failures var r = compare_result(); record_pass(&r); record_pass(&r); invariant all_passed(r) == true; - } - test all_passed_false_when_failures { + test all_passed_false_when_failures var r = compare_result(); record_pass(&r); record_fail(&r); invariant all_passed(r) == false; - } - test signal_ref_creation { + test signal_ref_creation given s = signal_ref("!", "led_out", 8) then s.vcd_ident == "!" and s.signal_name == "led_out" and s.bit_width == 8 - } - test expected_value_creation { + test expected_value_creation given e = expected_value("led_out", 5, 170) then e.signal_name == "led_out" and e.cycle_offset == 5 and e.expected == 170 and e.mask == 0xFFFFFFFF - } - test expected_value_masked { + test expected_value_masked given e = expected_value_masked("status", 10, 3, 0x0F) then e.mask == 0x0F - } - test compare_value_exact_match { + test compare_value_exact_match given e = expected_value("led", 0, 42) then compare_value(42, e) == true - } - test compare_value_exact_mismatch { + test compare_value_exact_mismatch given e = expected_value("led", 0, 42) then compare_value(43, e) == false - } - test compare_value_masked_match { + test compare_value_masked_match given e = expected_value_masked("status", 0, 3, 0x0F) then compare_value(0x83, e) == true - } - test compare_value_masked_mismatch { + test compare_value_masked_mismatch given e = expected_value_masked("status", 0, 3, 0x0F) then compare_value(0x84, e) == false - } - test extract_value_within_range { + test extract_value_within_range given values = [10, 20, 30] then extract_value(values, 3, 1) == 20 - } - test extract_value_out_of_range { + test extract_value_out_of_range given values = [10, 20] then extract_value(values, 2, 5) == 0 - } - test compare_batch_all_pass { + test compare_batch_all_pass given vcd = [0, 255, 170] and e1 = expected_value("led", 0, 0) and e2 = expected_value("led", 1, 255) @@ -317,9 +302,8 @@ module VcdConformanceCompare { given r = compare_batch(vcd, 3, expected, 3) then r.passed == 3 and r.failed == 0 - } - test compare_batch_mixed { + test compare_batch_mixed given vcd = [0, 255, 100] and e1 = expected_value("led", 0, 0) and e2 = expected_value("led", 1, 254) @@ -328,98 +312,80 @@ module VcdConformanceCompare { given r = compare_batch(vcd, 3, expected, 3) then r.passed == 2 and r.failed == 1 - } - test map_uart_tx_0x55 { + test map_uart_tx_0x55 given bits = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] then map_uart_tx_vector(0x55, bits, 10) > 0 - } - test map_mac_cycle_simple { + test map_mac_cycle_simple given a = [1, 1] and b = [1, 1] then map_mac_cycle_result(a, b, 2, 0) == 2 - } - test map_mac_cycle_with_initial { + test map_mac_cycle_with_initial given a = [1] and b = [1] then map_mac_cycle_result(a, b, 1, 5) == 6 - } - test map_spi_transfer_8bit { + test map_spi_transfer_8bit then map_spi_transfer_bits(0xAA, 8) > 0 - } - test map_led_output_mask { + test map_led_output_mask then map_led_output(255) == 255 - } - test map_led_output_truncate { + test map_led_output_truncate then map_led_output(0x1FF) == 0xFF - } - test parse_timescale_ps_common { + test parse_timescale_ps_common then parse_timescale_ps("1 ps") == 1 and parse_timescale_ps("1 ns") == 1000 and parse_timescale_ps("10 ns") == 10000 - } - test cycle_to_timestamp_ps_basic { + test cycle_to_timestamp_ps_basic then cycle_to_timestamp_ps(5, 20) == 100000 - } - test timestamp_to_cycle_basic { + test timestamp_to_cycle_basic then timestamp_to_cycle(100000, 20) == 5 - } - test validate_signal_ref_ok { + test validate_signal_ref_ok given s = signal_ref("!", "data", 8) then validate_signal_ref(s) == 0 - } - test validate_signal_ref_empty_ident { + test validate_signal_ref_empty_ident given s = signal_ref("", "data", 8) then validate_signal_ref(s) > 0 - } - test validate_signal_ref_zero_width { + test validate_signal_ref_zero_width given s = signal_ref("!", "data", 0) then validate_signal_ref(s) > 0 - } - test validate_expected_ok { + test validate_expected_ok given e = expected_value("sig", 0, 0) then validate_expected(e) == 0 - } - test validate_expected_empty_name { + test validate_expected_empty_name given e = expected_value("", 0, 0) then validate_expected(e) > 0 - } // === Invariants === - invariant result_counts_consistent { + invariant result_counts_consistent var r = compare_result(); record_pass(&r); record_fail(&r); assert r.total_checks == r.passed + r.failed + r.errors - } - invariant extract_value_non_negative { + invariant extract_value_non_negative given values = [10] assert extract_value(values, 1, 0) >= 0 - } - invariant cycle_timestamp_roundtrip { + invariant cycle_timestamp_roundtrip given ts = cycle_to_timestamp_ps(100, 20) assert timestamp_to_cycle(ts, 20) == 100 - } // === Benchmarks === - bench compare_batch_latency { + bench compare_batch_latency given vcd = [0, 255, 170, 42, 99] and e1 = expected_value("led", 0, 0) and e2 = expected_value("led", 1, 255) @@ -429,7 +395,6 @@ module VcdConformanceCompare { and expected = [e1, e2, e3, e4, e5] measure: nanoseconds for compare_batch(vcd, 5, expected, 5) target: < 1000ns - } } // phi^2 + 1/phi^2 = 3 | TRINITY