Duck Server — Wiki
Duck Server is a heterogeneous streaming SoC that offloads heavy compute from client devices. Instructions arrive from a network stream, are classified and routed by the NoC router, dispatched to the CPU or NPU, and results are transmitted to remote displays. A MOESI coherency controller mediates shared memory access between the CPU and NPU DMA.
Pages
| Page | What it covers |
|---|---|
| status.md | Live status — latest test results, recent commits, next scheduled runs |
| next_run.md | Next-run queue — check/uncheck what the automation does next |
| automation.md | Schedule, cron setup, and rules for the autonomous dev cycles |
| progression.md | How the project evolved v1→v4, version history, bug history |
| architecture.md | System block diagram, data flow, module map, comparison with related work |
| chiplets.md | v5 — chiplet disaggregation + UCIe: base die / CPU chiplet / NPU chiplet, link training, flit channels |
| cpu.md | 5-stage RV32IM pipeline — stages, ALU, MUL/DIV stalls, forwarding, hazards |
| npu.md | NPU v3 — INT8/INT16 mixed-precision, ping-pong weight banks, COMPUTE_ACC |
| system.md | system_top v4 (historical) — instruction SRAM, MOESI coherency ctrl, halt detection. See chiplets.md for the current v5 package split |
| verification.md | 14-test suite, MOESI integration testbench, how to run, adding new tests |
| toolchain.md | Assembler — write real RV32IM assembly (labels, pseudo-ops, NPU/GPU mnemonics), assemble with scripts/riscv_asm.py, run it, see the output |
| reference.md | Opcode table, NPU encoding, ALU control codes, key constants |
| rtl/index.md | RTL Source Reference — one page per rtl/*.sv file: ports, functionality, worked examples |
| tb/index.md | Testbench Reference — one page per tb/*.py file: what it drives, test list, how to run |
| todo.md | Roadmap — completed, near-term, medium-term, long-term |
| issues/README.md | Issue log — bugs found during simulation/verification/review |
| unsolved/README.md | Unsolved log — roadblocks the automation couldn't close out alone; parked here for a human to fix on a branch and merge on approval |
Repository File Tree
duck_server/
│
├── rtl/ ← Synthesisable SystemVerilog
│ ├── system_top.sv ← Top-level chip wrapper (v5 — package assembly)
│ ├── base_die_top.sv ← Base/I-O die: NoC router + MOESI L2 + ext I/O
│ ├── cpu_chiplet_top.sv ← CPU chiplet: riscv_core + imem + halt detect
│ ├── npu_chiplet_top.sv ← NPU chiplet: npu + result buffering
│ ├── ucie_chan.sv ← Generic UCIe mainband channel (credit + latency)
│ ├── ucie_link_ctrl.sv ← UCIe link training FSM (functional stub)
│ ├── duck_ucie_pkg.sv ← Flit field / opcode reference (docs only)
│ ├── duck_coherency_ctrl.sv ← MOESI coherency controller + L2 cache
│ ├── noc_router.sv ← NoC instruction router (replaces SDU)
│ ├── riscv_core.sv ← RV32IM 5-stage pipeline CPU
│ ├── alu.sv ← Integer ALU: ADD/SUB/logic/shifts/MUL/DIV
│ ├── imm_decode.sv ← Immediate extractor (I/S/B/U/J types)
│ ├── register_file.sv ← 32×32-bit regfile
│ ├── npu.sv ← NPU v3: INT8/INT16, ping-pong, COMPUTE_ACC
│ └── pe.sv ← Weight-stationary INT8 MAC cell
│
├── tb/ ← Verification
│ ├── tb_server_dispatch_unit.py ← Regression testbench (15 tests)
│ ├── tb_moesi_integration.py ← MOESI coherency testbench (3 tests)
│ ├── tb_video_stream_workload.py ← 256 kbps CPU+NPU workload testbench (2 tests)
│ ├── cpu_peak_tests.asm ← Default RV32IM CPU test program
│ ├── moesi_weight_test.asm ← MOESI coherency test program
│ ├── extended_cpu_test.asm ← 104-instruction full ISA coverage
│ ├── branch_regression.s ← Assembler source: all 4 branch families
│ └── test_rv32m_control_flow_regression.s ← Assembler source: JAL/BNE/MUL
│
├── docs/ ← This wiki
│ ├── index.md ← You are here
│ ├── progression.md ← Version history v1→v4
│ ├── architecture.md
│ ├── chiplets.md ← v5 — chiplet disaggregation + UCIe
│ ├── cpu.md
│ ├── npu.md
│ ├── system.md
│ ├── verification.md
│ ├── toolchain.md ← Assembler: syntax, pseudo-ops, NPU/GPU mnemonics
│ ├── reference.md
│ ├── todo.md
│ ├── rtl/ ← RTL Source Reference — one page per rtl/*.sv file
│ ├── tb/ ← Testbench Reference — one page per tb/*.py file
│ ├── issues/ ← Bug log
│ │ ├── README.md
│ │ ├── TEMPLATE.md
│ │ ├── BUG-001.md through BUG-007.md
│ └── unsolved/ ← Unsolved log — roadblocks for a human to fix on a branch
│ ├── README.md
│ ├── TEMPLATE.md
│ └── UNSOLVED-001.md
│
├── scripts/
│ ├── run ← Docker simulation runner
│ ├── riscv_asm.py ← RV32IM assembler (labels, pseudo-ops, NPU/GPU mnemonics)
│ └── commit_all.sh ← Grouped git commit helper
│
├── run_sims.command ← Run MOESI + regression in one shot
├── Makefile ← cocotb build (SIM=icarus)
├── Dockerfile ← iverilog + cocotb simulation container
└── README.md ← Project overview + quick start
System at a Glance
Logical dataflow — unchanged since v4. As of v5 the router/CPU/NPU/MOESI blocks below are split across three dies connected by UCIe links; see chiplets.md for the physical package view.
Network Stream (32-bit words)
│
▼
NoC Router ← classify by opcode[6:0], cpu_accept single-pulse write
│ │
▼ ▼
RV32IM NPU v3 ← INT8/INT16, ping-pong weight banks
CPU Core (16×16 MACs)
│ │
▼ │ npu_dma_* (coherent read)
MOESI L2 ◄─────────┘
Controller
│
▼
External DRAM
Quick Simulation Status
Regression: TESTS=11 PASS=11 FAIL=0
MOESI: TESTS=3 PASS=1 FAIL=2 — BUG-006 open
Total: TESTS=14 PASS=12 FAIL=2
Verified against v5 (chiplet disaggregation + UCIe — see chiplets.md); regression and MOESI results are both unchanged from the pre-split v4 baseline.
Run: ./run_sims.command
See: verification.md for full breakdown.