diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ac044fe..d889c6c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,6 +3,7 @@ name: deploy on: push: branches: [main] + pull_request: workflow_dispatch: # Allow the gym repo to trigger a rebuild when its API changes: # gh api repos/ManhattanReasoning/manhattanreasoning-docs/dispatches \ diff --git a/docs/examples/ffn-accel.md b/docs/examples/ffn-accel.md index 482f45f..2a74898 100644 --- a/docs/examples/ffn-accel.md +++ b/docs/examples/ffn-accel.md @@ -41,9 +41,11 @@ The whole dual-engine slave at `tile=4`: | FFNSlave | 3,437 | 840 | 40 | 6 | 1,505 | | **Budget (LFE5UM5G-85F)** | 84k | – | **156** | 208 | – | -Fits with huge headroom next to the VexRiscv+LiteEth SoC. The parallel MAC -grid scales as `tile²` DSPs, 12×12 (144 MACs) is the max all-DSP fit; 16×16 -(256 MACs) needs on-fabric multipliers. +Fits with huge headroom next to the VexRiscv+LiteEth SoC (see +[Hardware & SoC architecture](../reference/hardware.md) for what that SoC +alone costs and how much of the chip is left over before this design is even +added). The parallel MAC grid scales as `tile²` DSPs, 12×12 (144 MACs) is the +max all-DSP fit; 16×16 (256 MACs) needs on-fabric multipliers. ## Run it diff --git a/docs/javascripts/mermaid-init.js b/docs/javascripts/mermaid-init.js new file mode 100644 index 0000000..d708e02 --- /dev/null +++ b/docs/javascripts/mermaid-init.js @@ -0,0 +1,44 @@ +// Mermaid rendering for diagram code fences (see mkdocs.yml's superfences +// "mermaid" custom fence). The custom theme has no light/dark toggle (fixed +// dark, data-md-color-scheme="slate" in main.html), so themeVariables below +// are a one-shot match to theme/css/docs.css's palette rather than a +// light/dark pair. +import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs"; + +mermaid.initialize({ + startOnLoad: false, + theme: "base", + fontFamily: '"Helvetica Neue", Helvetica, Arial, sans-serif', + themeVariables: { + background: "#0e1218", + primaryColor: "#10151d", + primaryTextColor: "#d7dee9", + primaryBorderColor: "#1c2330", + secondaryColor: "#0e1218", + secondaryBorderColor: "#1c2330", + tertiaryColor: "#0e1218", + tertiaryBorderColor: "#1c2330", + lineColor: "#5fb0ff", + textColor: "#d7dee9", + mainBkg: "#10151d", + nodeTextColor: "#d7dee9", + clusterBkg: "#05070d", + clusterBorder: "#1c2330", + titleColor: "#f2f5fa", + edgeLabelBackground: "#0e1218", + fontSize: "14px", + }, + flowchart: { curve: "basis", htmlLabels: true, padding: 14 }, + securityLevel: "loose", +}); + +// pymdownx.superfences emits
...;
+// mermaid's run() reads the element's raw innerHTML and chokes on that
+// nested tag ("No diagram type detected... text: ...").
+// Flatten each block to a plain text node (still the exact decoded diagram
+// source) before handing it to mermaid.
+for (const el of document.querySelectorAll("pre.mermaid")) {
+ el.textContent = el.textContent;
+}
+
+mermaid.run({ querySelector: "pre.mermaid" });
diff --git a/docs/reference/hardware.md b/docs/reference/hardware.md
new file mode 100644
index 0000000..4c388e5
--- /dev/null
+++ b/docs/reference/hardware.md
@@ -0,0 +1,112 @@
+# Hardware & SoC architecture
+
+What's on the other end of `mrg run`: the board, the fixed LiteX SoC every
+node boots, and the FPGA resources left over for your design.
+
+## The board
+
+Every node is a Lattice ECP5 FPGA, device `LFE5UM5G-85F-8BG381`. A cluster of
+these boards is the pool `mrg run` schedules onto. See the
+[CLI guide](../guides/cli.md) for `status` and `reset`.
+
+## System architecture
+
+Every board boots the same LiteX SoC: a VexRiscv CPU, a LiteEth network
+stack, and a Wishbone bus, with one pluggable slot for your design.
+
+```mermaid
+flowchart LR
+ PLL(["On-chip PLL"]) --> SYS["cd_sys
50 MHz, fixed"]
+ PLL --> USR["cd_user
tunable"]
+
+ subgraph SOC["Fixed LiteX SoC"]
+ SYS --> CPU["VexRiscv CPU"]
+ CPU --> BUS(("Wishbone bus"))
+ BUS --> ROM["Firmware ROM"]
+ BUS --> SRAM["SRAM"]
+ BUS --> MAC["Ethernet MAC"]
+ BUS --> BRIDGE["Clock domain bridge"]
+ end
+
+ MAC --> PHY["Ethernet PHY"]
+ BRIDGE --> USR
+ USR --> YOURS["Your design
2 KB Wishbone window"]
+
+ classDef focus fill:#0072ff1f,stroke:#0072ff,color:#f2f5fa,stroke-width:2px;
+ class YOURS focus;
+```
+
+The control plane (`cd_sys`: CPU, bus, bridge firmware, MAC) always runs at a
+fixed 50 MHz, identical on every build. Only `cd_user`, the domain your
+design is instantiated in, is tunable. A clock sweep only changes your
+design's clock, never the known-good infrastructure around it.
+
+Your side of the contract is a plain Wishbone B4 peripheral, top module
+`user_design`:
+
+```text
+input clk, rst
+input wb_cyc, wb_stb, wb_we
+input [8:0] wb_adr (32-bit word address, 512 words)
+input [31:0] wb_dat_w
+input [3:0] wb_sel
+output [31:0] wb_dat_r
+output wb_ack (registered, 1 cycle after cyc & stb)
+```
+
+That's the only interface between your logic and the rest of the SoC: one
+2 KB MMIO window, nothing else. Everything outside that window (firmware,
+CPU memory, networking) is off limits and not reachable from `user_design`.
+
+## Address space
+
+| Region | Address | Size | Access |
+| --- | --- | --- | --- |
+| **Your design** | `0x90000000` | 2 KB (512 x 32-bit words) | Read and write, this is yours |
+| Everything else | n/a | n/a | Off limits, reserved for the SoC |
+
+## FPGA resources
+
+Numbers below are from a real build: the LiteX SoC synthesized and placed
+with a no-op placeholder in the user slot, so this is what the CPU, bus, and
+networking cost before your design adds a single gate.
+
+**Total available on the chip:**
+
+```text
+LUT 83,640
+FF 83,640
+BRAM 208
+DSP 156
+PLL 4
+IO 365
+```
+
+**Used by the SoC (CPU, bus, networking), before your design:**
+
+```text
+LUT [█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒] 6% 5,348
+FF [█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒] 3% 2,718
+BRAM [██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒] 12% 25
+DSP [▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒] 2% 4
+PLL [█████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒] 25% 1
+IO [█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒] 4% 15
+```
+
+**Left over for your design:**
+
+```text
+LUT [███████████████████▒] 94% 78,292
+FF [███████████████████▒] 97% 80,922
+BRAM [██████████████████▒▒] 88% 183
+DSP [████████████████████] 98% 152
+PLL [███████████████▒▒▒▒▒] 75% 3
+IO [███████████████████▒] 96% 350
+```
+
+The [FFN accelerator example](../examples/ffn-accel.md) is a real design
+sized against this same budget (3,437 LUT, 1,505 FF, 40 DSP, 6 BRAM), well
+inside what's left over.
+
+One PLL is already spent generating `cd_sys` and `cd_user`. A design that
+needs its own independent clock domain has 3 PLLs left, not 4.
diff --git a/docs/reference/index.md b/docs/reference/index.md
index 9bddb9d..f0675f6 100644
--- a/docs/reference/index.md
+++ b/docs/reference/index.md
@@ -1,7 +1,10 @@
# API Reference
Generated from `manhattan-reasoning-gym`'s public docstrings. For a narrative
-walkthrough of these same surfaces, see the [SDK guide](../guides/sdk.md).
+walkthrough of these same surfaces, see the [SDK guide](../guides/sdk.md). For
+what's physically on the other end of these calls, the board, the SoC, and
+the FPGA resource budget your design gets, see
+[Hardware & SoC architecture](hardware.md).
The SDK is organized by role into four namespaces:
diff --git a/mkdocs.yml b/mkdocs.yml
index 7730a3e..264ed17 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -21,6 +21,11 @@ extra_javascript:
# reads as a dark-mode version of the main site. Harmless on pages with no
# such canvas.
- javascripts/routing-viz.js
+ # Renders ```mermaid fences (see the superfences custom_fences entry below)
+ # with themeVariables matched to docs.css's palette. Harmless on pages with
+ # no .mermaid blocks.
+ - path: javascripts/mermaid-init.js
+ type: module
markdown_extensions:
- admonition
@@ -79,6 +84,7 @@ nav:
- FFN accelerator: examples/ffn-accel.md
- Reference:
- Overview: reference/index.md
+ - Hardware & SoC: reference/hardware.md
- mrg.cloud: reference/cloud.md
- mrg.build: reference/build.md
- mrg.sandbox: reference/sandbox.md
diff --git a/theme/css/docs.css b/theme/css/docs.css
index cc10204..3718bd1 100644
--- a/theme/css/docs.css
+++ b/theme/css/docs.css
@@ -346,6 +346,17 @@ a:hover { text-decoration: underline; }
/* line-number gutter (anchor_linenums) */
.highlight .linenos { color: var(--dim); user-select: none; }
+/* Mermaid diagrams (see docs/javascripts/mermaid-init.js for the matching
+ themeVariables). Framed like a code block so it reads as part of the same
+ content system, not a foreign embed. */
+.md-content pre.mermaid {
+ display: flex; justify-content: center;
+ background: var(--surface); border: 1px solid var(--line);
+ border-radius: 10px; padding: 1.4rem; margin: 0 0 1.3rem;
+ overflow-x: auto;
+}
+.md-content pre.mermaid svg { max-width: 100%; }
+
/* Tables */
.md-content table {
width: 100%; border-collapse: collapse; margin: 0 0 1.4rem;