Skip to content

Repository files navigation

Duck Server

Duck Server is a heterogeneous streaming SoC that offloads heavy compute (scalar CPU, vector GPU/AIPU, and neural NPU workloads) from client devices, delivering results wirelessly to TVs, laptops, and phones.

Network Stream --> SDU --> CPU / GPU / NPU --> Wireless Driver --> Remote Displays

All processing units are implemented in synthesisable SystemVerilog (RV32IM ISA) and verified with cocotb + Icarus Verilog.


Status

Unit Status
RISC-V CPU (RV32IM) ✅ Done — 5-stage pipeline, ALU, register file, L1 cache
Server Dispatch Unit ✅ Done — 1-cycle opcode routing to CPU / GPU / NPU
NPU v2 (16×16 INT8, 0.512 TOPS) ✅ Done — 256 parallel MACs, LOAD_W/LOAD_A/COMPUTE/COMPUTE_ACC, tiled GEMM
GPU / AIPU v1 ✅ Done — 16-lane INT32 vector ALU (ADD/SUB/AND/XOR), see docs/gpu.md
Wireless Peripheral Driver Interface defined — implementation pending

Simulation: tb_server_dispatch_unit TESTS=15 PASS=15 FAIL=0 ✓ · tb_moesi_integration TESTS=3 PASS=1 FAIL=2 (BUG-006 open) — see docs/verification.md


Running Simulations

Requires Docker (pulls riscv_sim image with iverilog 11 + cocotb v2 pre-installed).

# ── Full test suite (default CPU program: cpu_peak_tests.asm) ──────────────
source scripts/run

# ── Run a specific assembly program ────────────────────────────────────────
TEST_TARGET=tb/extended_cpu_test.asm source scripts/run
TEST_TARGET=tb/example_program.asm   source scripts/run

# ── Run a single named test ────────────────────────────────────────────────
COCOTB_TESTCASE=run_npu_gemv          source scripts/run
COCOTB_TESTCASE=run_npu_tiled_gemm    source scripts/run
COCOTB_TESTCASE=run_npu_random_signed source scripts/run
COCOTB_TESTCASE=run_riscv_program     source scripts/run

# ── Run without Docker (if iverilog + cocotb installed locally) ─────────────
make results.xml
make results.xml ASM_TEST=tb/extended_cpu_test.asm

# ── View latest results ─────────────────────────────────────────────────────
cat output.log                        # full log (overwritten on every run)
grep -E "PASS|FAIL|TESTS=" output.log # summary line only

All 9 available tests:

Test name What it exercises
run_npu_gemv Basic 16×16 GEMV — W[r][c]=r+1, A=1
run_npu_identity Identity weight matrix — O should equal A
run_npu_all_ones W=1, A=1 — all lanes output 16
run_npu_random_signed Random signed INT8, Python scoreboard cross-check
run_npu_negative Negative weights — signed arithmetic coverage
run_npu_max_values W=127, A=127 — max INT8, no overflow
run_npu_zero_act A=0 — all outputs must be 0
run_npu_tiled_gemm K=32 tiled GEMM via COMPUTE + COMPUTE_ACC
run_riscv_program RV32IM CPU — MUL chain, 5 register assertions

Repository Layout

rtl/
  system_top.sv            - Top-level wrapper; SRAM, L1 cache, module glue
  server_dispatch_unit.sv  - Opcode router (SDU): CPU / GPU / NPU dispatch
  riscv_core.sv            - RV32IM scalar CPU
  alu.sv                   - Integer ALU
  imm_decode.sv            - Immediate field extractor
  register_file.sv         - 32 x 32-bit register file
  npu.sv                   - 16x16 INT8 parallel MAC array (NPU)
  pe.sv                    - Weight-stationary INT8 MAC processing element

tb/
  tb_server_dispatch_unit.py  - UVM-style cocotb testbench (9 tests: 8 NPU + 1 CPU)
  cpu_peak_tests.asm          - RV32IM peak-performance test program
  extended_cpu_test.asm       - Extended 104-instruction RV32IM test (all instruction groups)
  example_program.asm         - Example CPU program

docs/
  index.md          - Wiki home + full file tree
  architecture.md   - System block diagram, data flow, module map
  cpu.md            - 5-stage pipeline, ALU, forwarding, hazards
  npu.md            - NPU v2: parallel MACs, FSM, tiled GEMM
  sdu.md            - Server Dispatch Unit: routing, backpressure
  system.md         - system_top: SRAM, L1 cache, halt detection
  verification.md   - Testbench, 9 tests, how to run
  reference.md      - Opcode table, encodings, signal glossary
  todo.md           - Roadmap

Makefile            - cocotb simulation build (SIM=icarus)
Dockerfile          - Simulation container
scripts/run         - One-shot test runner

NPU v2 at a Glance

The NPU v2 implements O[16] = W[16×16] × A[16] (INT8 GEMV) and tiled K>16 GEMM using a fully-parallel 256-MAC array dispatched via RISC-V custom-1 opcode 0x6B. All 256 multiplications are combinational — results are registered in a single clock cycle.

Peak throughput: 0.512 TOPS @ 1 GHz

GEMV usage:

  1. 256 × LOAD_W (cmd=000) — fill W[16][16]
  2. 16 × LOAD_A (cmd=001) — fill A[16]
  3. 1 × COMPUTE (cmd=010) — acc = W·A (1 cycle)
  4. Read 16 × INT32 results via result_valid/result_index/result_data

Tiled GEMM (K=32): repeat tiles with COMPUTE_ACC (cmd=011) to accumulate partial sums without losing prior results.

Instruction encoding (bits [9:7] = cmd, [13:10] = row, [17:14] = col, [25:18] = data INT8)

See docs/architecture.md for full instruction encoding and state machine details.


Related Open-Source Chips

Project What we borrowed
Ibex (lowRISC) RV32IM pipeline structure
Rocket Chip (UC Berkeley) SDU/RoCC-style heterogeneous dispatch
Gemmini (UC Berkeley) Weight-stationary systolic array + custom instruction interface
VTA (Apache TVM) LOAD_W / LOAD_A / COMPUTE instruction model
NVDLA (NVIDIA) Full DLA reference for future NPU expansion
CVA6 (OpenHW) Pipeline staging reference

About

Heterogeneous streaming SoC — RV32IM CPU + NPU with MOESI coherency. RTL, testbenches, docs, and automation.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages