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;