Reorganize source tree: kernel/, v3/, v4/ split and board infrastructure

Source tree reorganization:
- Move StarForth v3 engine to v3/ (src/, include/, Makefile)
- Move kernel to kernel/ (src/, include/, linker/, Makefile)
- Create v4/ skeleton for F18-ISA golden model (DECOMPOSITION.md, JUSTIFICATION.md)
- Move FABRIC-0..4.md to docs/fabric/
- Move ONTOLOGY.md and ROADMAP.md to docs/

Board infrastructure:
- Add boards/ser5/, boards/raspi/, boards/milkv/, boards/zynq7020/
- Each board has board.mk (ISA, CPU flags, boot recipe) and README.md
- Root Makefile becomes thin dispatcher: boot_image, all, clean, docs take TARGET
- make boot_image TARGET=SER5|RASPI|MILKV builds one GPT/MBR image per board
- ZYNQ7020 target exists but stops with clear error (ARMv7 port not built yet)
- scripts/mkdiskimage.sh builds disk images for all boards

Docs pipeline:
- docs/book/ with LaTeX master (main.tex) and Makefile
- pandoc converts Markdown to LaTeX at build time
- Two Lua filters: table-widths.lua (wide tables wrap), code-breaks.lua (inline code breaks)
- make docs builds single PDF (754 pages, 0 missing characters)
- make docs TARGET=<board> adds board appendix
- build/docs/<book|board>/meta.tex stamps git commit into PDF

Bug fixes:
- 42 include paths that only worked by accident now use correct relative paths
- clang-18 hardcode replaced with configurable CC variable (fixed aarch64 build)
- Pi 5: kernel_2712.img linked at 0x80000, .bss zeroed, memory reserved
- Doxyfile, .clang-tidy, README.md, Kconfig paths updated

Verified:
- Hosted v3 build passes 1012 tests, 0 failures
- SER5 image boots in QEMU (OVMF), POST passes, K exact (65536 = Q48_ONE)
- Milk-V image boots in QEMU (OpenSBI + U-Boot + bootefi), POST passes
- make clean TARGET=<board> removes only that board and its ISA objects
- make all builds all boards, hosted v3, and docs in one run

Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
rajames
2026-10-01 15:40:09 -04:00
co-authored by Junie
parent 3c709c115b
commit a8b70e88d3
630 changed files with 2646 additions and 2036 deletions
+314
View File
@@ -0,0 +1,314 @@
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 2023–2025 Robert A. James
All rights reserved.
This file is part of the StarForth project.
Licensed under the StarForth License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
express or implied, including but not limited to the warranties of
merchantability, fitness for a particular purpose, and noninfringement.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* physics_hotwords_cache.h
*
* Hot-words cache optimization: frequency-driven dictionary acceleration
*
* Compile-time switch to enable/disable the hot-words cache variant.
* Allows measuring impact before/after on different build profiles.
*
* Usage:
* make clean && make ENABLE_HOTWORDS_CACHE=1 # With cache
* make clean && make ENABLE_HOTWORDS_CACHE=0 # Without cache
*
* Measure performance:
* BENCH-DICT-LOOKUP (show baseline + stats)
* PHYSICS-SHOW-CACHE-STATS (show hit rate, evictions, etc)
*/
#ifndef PHYSICS_HOTWORDS_CACHE_H
#define PHYSICS_HOTWORDS_CACHE_H
#include <stdint.h>
#include "vm.h"
/* ============================================================================
* Feature Switch
* ============================================================================
*
* Set via -DENABLE_HOTWORDS_CACHE=1 during compilation
* Default: enabled (can be disabled for baseline comparison)
*/
#ifndef ENABLE_HOTWORDS_CACHE
#define ENABLE_HOTWORDS_CACHE 1
#endif
/* ============================================================================
* Hot Words Cache Configuration
* ============================================================================
*/
/** Maximum number of hot words to cache (typically 16-32) */
#define HOTWORDS_CACHE_SIZE 32
/** Execution heat threshold to consider a word "hot" (execution count) */
#define HOTWORDS_EXECUTION_HEAT_THRESHOLD 50
/** Reorder bucket when execution heat delta exceeds this (avoid thrashing) */
#define HOTWORDS_EXECUTION_HEAT_DELTA_THRESHOLD 100
/* ============================================================================
* Statistics Structure
* ============================================================================
*
* Tracks cache performance for measurement and diagnostics
*/
typedef struct {
/** Total lookups performed */
uint64_t total_lookups;
/** Lookups that hit the hot-words cache */
uint64_t cache_hits;
/** Lookups that missed cache but found in bucket */
uint64_t bucket_hits;
/** Lookups that failed (word not found) */
uint64_t misses;
/** Words evicted from cache (LRU) */
uint64_t evictions;
/** Times a word was promoted to hot-words */
uint64_t promotions;
/** Times bucket was reordered */
uint64_t bucket_reorders;
/** === 64-bit Fixed-Point Statistics (Q48.16 format) ===
* Q48.16 = 48-bit integer + 16-bit fractional part
* Precision: 2^-16 ns ≈ 0.0000153 ns
* Range: ±140 trillion ns (≈ 4.4 years)
* Allows: Bayesian inference, precise averaging, statistical computation
*/
/** Sum of cache hit latencies (64-bit fixed-point, Q48.16) */
int64_t cache_hit_total_ns_q48;
/** Sum of bucket search latencies (64-bit fixed-point, Q48.16) */
int64_t bucket_search_total_ns_q48;
/** Number of cache hit samples (for averaging) */
uint64_t cache_hit_samples;
/** Number of bucket search samples (for averaging) */
uint64_t bucket_search_samples;
/** Minimum cache hit latency (nanoseconds) */
int64_t min_cache_hit_ns;
/** Maximum cache hit latency (nanoseconds) */
int64_t max_cache_hit_ns;
/** Minimum bucket search latency (nanoseconds) */
int64_t min_bucket_search_ns;
/** Maximum bucket search latency (nanoseconds) */
int64_t max_bucket_search_ns;
/** Sum of squared cache hit latencies (for variance/stddev) */
int64_t cache_hit_variance_sum_q48;
/** Sum of squared bucket search latencies (for variance/stddev) */
int64_t bucket_search_variance_sum_q48;
} HotwordsStats;
/* ============================================================================
* Hot Words Cache State
* ============================================================================
*
* Embedded in VM for global state
*/
typedef struct HotwordsCache_s {
/** Cache entries (pointers to DictEntry) */
DictEntry *cache[HOTWORDS_CACHE_SIZE];
/** Number of valid entries in cache */
uint32_t cache_count;
/** LRU: last-used index for eviction */
uint32_t lru_index;
/** Performance statistics */
HotwordsStats stats;
/** Enabled/disabled flag (runtime toggle) */
int enabled;
} HotwordsCache;
/* ============================================================================
* Public API
* ============================================================================
*/
/**
* Initialize hot-words cache
* Should be called during VM initialization
*/
void hotwords_cache_init(HotwordsCache *cache);
/**
* Cleanup hot-words cache
*/
void hotwords_cache_cleanup(HotwordsCache *cache);
/**
* Lookup word in cache first, then fall back to bucket search
* Returns the found word, or NULL if not found
*
* This is the main function that replaces vm_find_word() logic.
* Takes the VM so the bucket fallback can resolve same-named entries by
* definition age (vm_dict_resolve_in_bucket) — bucket order alone is not
* authoritative once dict_reorganize_buckets_by_heat() has run.
*/
DictEntry *hotwords_cache_lookup(VM *vm,
HotwordsCache *cache,
DictEntry **bucket,
size_t bucket_count,
const char *name,
size_t len);
/**
* Promote a word to the hot-words cache
* Called when a word's execution heat exceeds threshold
*/
void hotwords_cache_promote(HotwordsCache *cache, DictEntry *word);
/**
* Evict every cache slot holding this exact entry.
* Must be called before an entry is freed (FORGET) — a stale pointer in the
* ring is a use-after-free.
*/
void hotwords_cache_evict_entry(HotwordsCache *cache, const DictEntry *word);
/**
* Evict every cache slot whose entry matches this name.
* Called whenever name resolution may change: word creation (shadowing),
* smudge/unsmudge, hide. The next lookup re-resolves through the bucket.
*/
void hotwords_cache_evict_name(HotwordsCache *cache, const char *name, size_t len);
/**
* Reorder a bucket by execution heat (move hot words forward)
* Called when execution heat delta exceeds threshold
*/
void hotwords_bucket_reorder(DictEntry **bucket, size_t count);
/**
* Reset statistics (for before/after comparison)
*/
void hotwords_stats_reset(HotwordsStats *stats);
/**
* Print statistics to stdout
*/
void hotwords_stats_print(const HotwordsStats *stats);
/**
* Enable/disable cache at runtime (for A/B testing)
*/
void hotwords_cache_set_enabled(HotwordsCache *cache, int enabled);
/* ============================================================================
* Bayesian Inference Statistics
* ============================================================================
*/
/**
* Bayesian statistics structure for inference and credible intervals
* All values stored in Q48.16 fixed-point (64-bit signed integer)
* representing nanoseconds with 2^-16 ≈ 0.0000153 ns precision
*/
typedef struct {
int64_t mean_ns_q48; /* Mean latency (Q48.16) */
int64_t stddev_ns_q48; /* Standard deviation (Q48.16) */
int64_t median_ns_q48; /* Median (p50) (Q48.16) */
int64_t credible_lower_95; /* Lower bound of 95% credible interval (Q48.16) */
int64_t credible_upper_95; /* Upper bound of 95% credible interval (Q48.16) */
int64_t credible_lower_99; /* Lower bound of 99% credible interval (Q48.16) */
int64_t credible_upper_99; /* Upper bound of 99% credible interval (Q48.16) */
uint64_t sample_count; /* Number of samples in posterior */
} BayesianLatencyPosterior;
/**
* Calculate posterior distribution for cache hits
* Uses accumulated samples to compute credible intervals
*/
BayesianLatencyPosterior hotwords_posterior_cache_hits(const HotwordsStats *stats);
/**
* Calculate posterior distribution for bucket searches
* Uses accumulated samples to compute credible intervals
*/
BayesianLatencyPosterior hotwords_posterior_bucket_searches(const HotwordsStats *stats);
/**
* Calculate speedup estimate with credible interval
* All values in Q48.16 fixed-point format (64-bit signed integer)
* Probabilities are in range [0, Q48_SCALE] representing [0%, 100%]
*/
struct SpeedupEstimate {
int64_t speedup_factor_q48; /* Bucket latency / Cache latency (Q48.16) */
int64_t credible_lower_95_q48; /* Lower bound (95% credible) (Q48.16) */
int64_t credible_upper_95_q48; /* Upper bound (95% credible) (Q48.16) */
int64_t probability_gt_10pct_q48; /* P(speedup > 1.1) in Q48.16, [0, 65536] = [0%, 100%] */
int64_t probability_gt_double_q48;/* P(speedup > 2.0) in Q48.16, [0, 65536] = [0%, 100%] */
};
/**
* Calculate speedup estimate with uncertainty
*/
struct SpeedupEstimate hotwords_speedup_estimate(const HotwordsStats *stats);
/**
* Generate detailed Bayesian inference report
* Compares cache vs bucket performance with confidence measures
*/
void hotwords_bayesian_report(const HotwordsStats *stats_with_cache,
const HotwordsStats *stats_without_cache);
#endif /* PHYSICS_HOTWORDS_CACHE_H */