A full rebuild of the 1988 Norsk Data ND-120 CPU card (the 3202D board) from the original design documents - first drawn in Logisim-Evolution, now in Verilog - that runs the original operating system, SINTRAN III, on FPGA boards you can buy today.
Note: read more about this CPU and the rest of the ND range in NDWiki, and on the official Norsk Data site.
| π³ Module hierarchy | What sits inside what - the whole machine as a tree you can fold open, for the simulation and for every FPGA board, made from a real yosys elaboration |
| π§© All modules | Every one of the ~400 modules, grouped by area. Each page has the module's symbol, a schematic drawn from the Verilog (every sub-module box links to its page), the ports, and the Verilog source |
| π Boards | The FPGA boards - Tang Nano 20K, Nexys 4 DDR, MiSTer, MEGA65 and more - with a quick start for each |
| π Design notes | How the machine works and why it is built the way it is |
A good first page: the CPU gate array, then follow the boxes in its schematic down to the ALU.
The machine boots SINTRAN III from a Winchester disc image on an SD card, and you can log in and run programs.
π₯ Releases page - ready-built bitstreams, no FPGA tools needed
- β Tang Nano 20K - boots SINTRAN, 20.25 MHz, timing-clean - quickstart
- β Nexys 4 DDR - boots SINTRAN, 33.333 MHz with the cache on - quickstart
- β MiSTer / DE10-Nano - boots SINTRAN, 20 MHz - quickstart
- π§ MEGA65 - builds for both board revisions, timing-clean, not yet run on a real MEGA65 - quickstart
- Explore the Design
- Overview
- Quick Start
- FPGA Boards
- Simulation
- Original Diagnostics
- What the Cache Is Worth
- Inside the Machine
- About the ND-120
- Documentation
- Status
- License
This repository holds:
- the original Norsk Data ND-120 design documents from 1988, scanned in 2023;
- Logisim-Evolution schematics of every part of the board;
- the Verilog version of the whole card, which runs in Verilator and on FPGAs.
| Component | Schematic | HDL | Status |
|---|---|---|---|
| DELILAH CPU Gate Array (CGA) | β Complete | Verilog (first made from Logisim, now kept by hand) | β Boots SINTRAN III |
| NEC Decoder Gate Array (DGA) | β Complete | Verilog (first made from Logisim, now kept by hand) | β Boots SINTRAN III |
| ND 3202 CPU Board revision D | β Complete | Verilog (first made from Logisim, now kept by hand) | β Boots SINTRAN III |
| PAL chips | β PALASM checked | Verilog with test benches | β Boots SINTRAN III |
The CPU board carries the DELILAH CPU, the decoder, all PAL chips and the support chips (74-series logic, RAM and the UART).
nd-120/
βββ DesignDocuments/ # Original 1988 design documents (scanned)
βββ NorskData-Doc/ # Functional description, instruction set, microprogramming guide
βββ Logisim/ # Logisim-Evolution schematics
βββ Code/
β βββ Microcode/ # Microcode PROM images, sources (.uc) and listings (version L)
β βββ 68705/ # Panel controller ROM dumps and analysis
β βββ RTC/ # Real-time clock notes
βββ Verilog/
βββ DELILAH-CPU/ # CPU gate array (ALU, microcode control, MMU access, interrupts)
βββ DECODE-GateArray/# Instruction decoder gate array
βββ CPU-BOARD-3202/ # The full 3202D board
βββ PAL/ # PAL chips, converted from PALASM
βββ Shared/ # TTL chips, memories, support logic
βββ ND-BUS-DEVICES/ # Floppy, Winchester, tape and other bus devices
βββ SD-FAT/ # SD card and FAT file system for the disc images
βββ Terminals/ # TDV2200 terminal (screen + keyboard)
βββ sim/ runSim/ # Verilator harnesses
βββ tests/ # Test registry and instruction checks
βββ docs/ # Design notes and analyses
βββ fpga/ # One folder per FPGA board
- Download the bitstream for your board from the Releases page.
- Follow the quickstart for your board: Tang Nano 20K Β· Nexys 4 DDR (incl. the SD-card-only path) Β· MiSTer Β· MEGA65 Β· QMTECH XC7A35T
# 1. Clone the repository
git clone https://github.com/RetroCoreLabs/nd-120.git
cd nd-120
# 2. Configure it: finds the tools, asks for what it cannot find (the build
# folder, where the other ND repositories are), fetches the submodules,
# makes the microcode preload images, and remembers the answers in
# local.mk (machine-local, never committed). From a Windows shell: py configure.py
python3 configure.py
python3 configure.py --check # later: what is set, what is missingEvery setting, what reads it and which targets need it: CONTRIBUTING.md - Local settings.
# Waveform simulation: compiles, runs, and opens GTKWave
cd Verilog/sim
make clean
make all
# Full CPU: microcode load + self-test + OPCOM console
cd ../runSim
make clean
make compile
make run
# All self-checking test benches (fail-fast)
cd ..
make testPrerequisites: Verilator, Icarus Verilog, GTKWave (optional). Development is done on Linux / WSL2 with bash.
Want the details? See BUILDING.md for build, test and troubleshooting steps.
Each board has its own folder of build scripts, pin files and notes under Verilog/fpga/ - that page holds the full per-board status and priority order.
| Board | Status | CPU clock | Main memory | Console | Disc images | Tools | Docs |
|---|---|---|---|---|---|---|---|
| Tang Nano 20K | β Boots SINTRAN III - primary target | 20.25 MHz (fast20), timing-clean |
4 MB SDRAM | Serial, 115200 | SD card | OSS CAD Suite + Gowin EDA | README Β· quickstart |
| Nexys 4 DDR | β Boots SINTRAN III | 33.333 MHz, cache on (7.52 MIPS) | DDR2 behind a BRAM cache | TDV2200 on VGA + USB keyboard, and serial | microSD - boots with no PC | Vivado | README Β· quickstart Β· timing |
| MiSTer (DE10-Nano) | β Boots SINTRAN III | 20 MHz | 4 MB SDRAM module | TDV2200 on the MiSTer screen and keyboard | Picked in the OSD | Quartus | README Β· quickstart |
| MEGA65 | π§ Built and timing-clean, not yet run on a MEGA65 | 13.33 MHz (R3) / 20 MHz (R4-R6) | 4 MB in HyperRAM (R3) / SDRAM (R4-R6) | TDV2200 on the MEGA65 keyboard and screen | SD card | Vivado | README Β· quickstart |
| QMTECH XC7A35T | π§ Built, timing met, not yet run | 20 MHz | 4 MB SDRAM | Serial | SD card (Pmod) | Vivado | README Β· quickstart |
| Basys3 | - | 24K words BRAM | Serial | - | Vivado | README | |
| Cmod A7-35T | - | BRAM | - | - | Vivado | README |
Verilator is the signal-level reference: waveforms, unit test benches, and the latch-versus-flip-flop comparison that proves a change altered nothing.
- β
Microcode loads, Master Clear runs, and the CPU self-test passes clean:
0 execution-phase STERR visits (the
ND120_COUNT_STERRprobe inVerilog/runSim/Run120.cpp). An older "7 of 14 subtests" figure is retracted (RETRACTED.md). - β The self-test does not touch memory parity, which is why the FPGA builds compute parity on read instead of storing it (nd120-parity-analysis.md).
- β
13 of 13 testable INSTRUCTION-B areas pass the automated gate: the first
400 instructions of each area match the ND-110 reference trace (
make test-instr). RUN and 48-bit floating are not among the 13. Each area was also run by hand to its own end of test with zero error lines; those logs were not kept (CAMPAIGN-STATUS.md). - β
OPCOM console works;
INSTRUCTION-Bloads and runs from the Verilog paper tape device; DMA bus mastering works against the real arbiter. - β Golden-console and latch-vs-FF regression gates guard all of it.
cd Verilog
make test # every self-checking test bench, fail-fast
make test-instr # the INSTRUCTION-B trace gate
make test-full # adds the heavy system gatesThese are the original Norsk Data test programs, not our own test benches. Each row says where the result was measured.
| Program | Result | Measured on |
|---|---|---|
| CONFIGURATION | β
Passes with NO ERRORS DETECTED, and names the machine correctly (ND-120/CX, 32-bit float, MMS-2, cache, ALD 400B, print number 3202) |
Verilator, Tang |
| INSTRUCTION | β Passes. In Verilator, 13 of 13 testable areas pass the automated trace gate. On the board, the full run over interrupt levels 1-9 passed clean (no log in the repository) | Verilator, Tang |
| PAGING | β Passes 11 of 11, incl. test 3 (PGU/WIP), test 4 (alternative PIT) and test 11 (physical address generation) | Tang |
| MEMORY | β
Passes. The corrupted-banner fault was the cache data output not gated by HIT |
Tang |
CACHE (CACHE-1X0-A00) |
β Passes all 8 tests, incl. test 3 "Inhibit limits" | Nexys 4 DDR |
| TPE Monitor B01 | β
Boots from a floppy image (1560& at the OPCOM # prompt) and reaches TPE> - the harness the diagnostics run from |
Verilator, Tang |
| RUN | == END OF TEST == once (commit 3acef36); no error count kept, and RUN is in neither make test-instr nor the test registry |
Verilator |
| 48-BITS-FLOATING | β Not applicable - the PROM microcode is the 32-bit float version (why) | - |
| DISC-TEMA J02 | β Not passing. Transfers real data off the disc image, matching the reference model register for register, but still reports Memory address Register not as expected. Unexplained - the one known open diagnostic |
Verilator, Tang |
The five that pass clean on the board - CONFIGURATION, INSTRUCTION, PAGING, MEMORY and CACHE - are the machine's own acceptance suite: the CPU names itself correctly, runs every instruction group correctly, the MMU translates and faults correctly, and main memory is sound.
These programs found the real CPU bugs:
- INSTRUCTION caught a multiply bug (every product's low word was zero) and a shift bug (all rotate and sign-extending shifts ran as plain shifts);
- PAGING caught an MMU fault where the physical-page map RAM was never written;
- CONFIGURATION caught a trap-vector fault that sent a page fault plus PGU to an unused vector, which then jumped to itself forever;
- CACHE needed four fixes, all single-input copying errors from the
schematics: the PAL 44511A
CWRfeedback latch, that PAL's pin-19 polarity, a dropped Am9150 used-bit write, and a DGAEPANSdata-window leak.
Measured on the Nexys 4 DDR with the operator panel's own MIPS counter, running
SINTRAN III. The cache is a build option (cache / nocache,
ND120_NO_CACHE - see build-defines.md).
| Build | CPU clock | Cache | MIPS running SINTRAN | Clocks per instruction |
|---|---|---|---|---|
| 15 | 45.45 MHz | off | 2.44 | 18.6 |
| 16 | 33.33 MHz | on | > 7.0 | < 4.8 |
The cache gives about 2.9x the throughput - on a clock 26% slower. This
machine is limited by memory speed, not by the clock: with the cache off, every
instruction fetch is a DDR2 read, and DDR2 does not get faster when the CPU
clock rises. A one-word loop (124000, a JMP to itself) took 17.1 clocks
per instruction uncached at both 45.45 and 33.33 MHz.
With the cache in, the routed worst path is 28.039 ns - a ceiling near
35.6 MHz. That one path (WRF -> ALU -> TVGEN -> ACAL -> WCS address) is
the most valuable thing to speed up on the board:
timing.md.
The microcode comes from an ND-120 3202 CPU board, version 14/L.
The repository has the PROM images, the microcode sources (.uc) and the listings for versions K and L.
The ND-120/CX CPU board has an on-board MC68705-U3 CPU. The front panel has an MC68705-P3 - a smaller chip with fewer I/O pins (Motorola 68HC05 family).
- P3 version = 28 pins, 2x 8-bit I/O ports, 1x 4-bit I/O port
- U3 version = 40 pins, 4x 8-bit I/O ports
We have ROM dumps from both the U3 (from the 3202D CPU board) and the P3 (from an ND-5000C panel controller), taken apart with GHIDRA: ROM dumps and analysis.
The schematics are in the Logisim folder, drawn with Logisim-Evolution 3.8.0.
Most Verilog files were first made from the Logisim drawings with the Logisim-Evolution FPGA tools. They are no longer regenerated - the Verilog and the schematics are both kept by hand now, so a fix has to be made in both places. All Verilog is in the Verilog folder.
Norsk Data built the ND-100 range of 16-bit minicomputers. The ND-120 is the 1988 CPU card for that range, print number 3202: it puts the processor into two gate arrays - the DELILAH CPU gate array and a decoder gate array - where the earlier ND-110 used discrete TTL chips. It runs the same instruction set as the ND-110, faster, and can address more memory. Its operating system is SINTRAN III.
The board was designed by Lasse Bockelie and Chris Cherrington. Its original design documents survived, and that is what makes this rebuild possible: the machine and its operating system run again, on FPGA boards you can buy today. More on the card: 3202 on NDWiki.
All of it is also on the docs site, https://retrocorelabs.github.io/nd-120/, with a page tree on the left and search.
Paths in this repository are always relative to the repository root. Where a
document points at one of the other ND repositories, it writes
$ND_REPOS/<repo>/... - set ND_REPOS to the folder that holds your ND
checkouts.
| Document | Description |
|---|---|
| README.md | This file - overview and quick start |
| BUILDING.md | Build, test and troubleshooting |
| DEVELOPMENT.md | Architecture, coding rules and how to contribute |
| HARDWARE.md | Hardware details, part by part |
| HISTORY.md | Project history, milestone by milestone |
| Verilog/TODO.md | Open work |
| Topic | Documentation |
|---|---|
| FPGA boards | Verilog/fpga/README.md |
| Verilog modules | Verilog/MODULES.md - one page per module: description, symbol, schematic drawn from the Verilog, ports and source |
| Module hierarchy | Verilog/HIERARCHY.md - what sits inside what, for the simulation and every FPGA board, from a yosys elaboration |
| Build options | Verilog/docs/build-defines.md |
| Design notes | Verilog/docs/README.md |
| Design documents | DesignDocuments/Readme.md |
| Norsk Data manuals | NorskData-Doc/Readme.md - functional description, instruction set, microprogramming guide |
Latest release: bitstreams-2026-09
(2 September 2026) - ready-built bitstreams for the MEGA65 and the MiSTer.
| Area | Status |
|---|---|
| CPU, decoder, board and PAL chips in Verilog | β Boots SINTRAN III |
| Tang Nano 20K, Nexys 4 DDR, MiSTer | β Boot SINTRAN III from an SD card |
| CPU self-test | β 0 errors |
| Original diagnostics | β CONFIGURATION, INSTRUCTION, PAGING, MEMORY, CACHE pass on the board |
| Cache | β ~2.9x throughput on the Nexys |
- MEGA65 and QMTECH: first runs on real boards
- DISC-TEMA J02: the
Memory address Register not as expectedfault - RUN: a proven clean run, and a gate that keeps it that way
- SD-card write workloads at full speed
- Cache and a fast clock together on the Nexys (~9.5 MIPS if the 28 ns path can be cut)
- The Cmod A7 SRAM bridge, so a small Xilinx board can run the OS
The live task list is Verilog/TODO.md.
- Lasse Bockelie - provided the original 1988 design documents
- Matthieu Benoit - read the ROM data out of the MC68705 chips
- NDWiki community - ND-120 documentation
- GHIDRA team - reverse engineering tools
- NDWiki - everything Norsk Data
- Logisim-Evolution - the schematic tool used here
- MiSTer2MEGA65 - the framework behind the MEGA65 port
- GitHub Issues: github.com/RetroCoreLabs/nd-120/issues
Historical note: a 1988 minicomputer CPU card, rebuilt from its own design documents, running its own operating system on a hobby FPGA board.
Start exploring: Quick Start | FPGA Boards | Documentation
MIT for the Verilog, Logisim and tools in this repository. The original design documents and manuals are Norsk Data material, kept here for preservation.