Skip to content
STIMSMITH

16-bit RISC Processor

Concept WIKI v1 · 8/6/2026

The 16-bit RISC Processor is a custom single-cycle RTL design under test (DUT 1) in the ConfigDrivenV framework, implemented in SystemVerilog as simple_cpu.v. It features a 4×16-bit register file, an 8-bit program counter, and a single-cycle execution FSM. The processor supports five opcodes (NOP, ADD, SUB, MOV, XOR, HALT) encoded in a 16-bit instruction format, and is verified by ConfigDrivenV with 100% pass rate on correct RTL and 100% bug detection on corrupted RTL.

16-bit RISC Processor

Overview

The 16-bit RISC Processor is one of two designs under test (DUTs) validated by the ConfigDrivenV Python-Integrated UVM verification framework. It is implemented as a custom RISC-style processor in SystemVerilog (file: simple_cpu.v) and serves as DUT 1 in the ConfigDrivenV testbench pipeline. ConfigDrivenV achieves 100% verification accuracy on the correct RTL (PASS=100, FAIL=0) across all 5 opcodes, all 4 destination registers, and the full signed immediate range, and 100% bug detection effectiveness on deliberately corrupted RTL [b6b66b496-5c1e-4ae0-a78a-2658594b58b2].

Architecture

The processor features the following datapath characteristics [1]:

  • Register File: 4 × 16-bit registers (R0, R1, R2, R3)
  • Program Counter: 8-bit
  • Execution Model: Single-cycle execution FSM

The 16-bit word size governs both the register width and the instruction word width, with modular overflow handled via bitwise AND with 0xFFFF in the Python golden reference model, faithfully replicating the synthesized hardware datapath behavior [2].

Instruction Set

The processor supports a minimal five-opcode ISA [1]:

Opcode Mnemonic Operation
0x0 NOP PC ← PC+1
0x1 ADD rd ← rd + imm
0x2 SUB rd ← rd − imm
0x3 MOV rd ← imm
0x4 XOR rd ← rd ⊕ imm
0xF HALT halt ← 1

Instruction Encoding

Instructions follow the 16-bit format [3]:

  • Bits [15:12]: opcode (4 bits)
  • Bits [9:8]: destination register rd (2 bits)
  • Bits [7:0]: immediate value imm (8 bits, signed range −128 to +127)

Verification Approach

ConfigDrivenV verifies the 16-bit RISC Processor using a two-layer pipeline [3]:

  1. Python Layer: Generates random instruction sequences and computes mathematically correct expected register states. Register state tracking is maintained through a four-element Python list; each arithmetic operation applies bitwise AND with 0xFFFF to enforce 16-bit width constraints [2].
  2. UVM Layer: Reads Python-generated files, drives the DUT, and performs automated comparison via a self-checking scoreboard.

File I/O Bridge

Communication between the Python layer and UVM testbench occurs through three text files [1]:

  • instr.hex: One instruction per line as a 4-digit hex value (16-bit instructions).
  • checkpoints.mem: One line per instruction with five space-separated hex fields representing PC, R0, R1, R2, R3 after each instruction completes.
  • golden.mem: Contains the four final register values.

The UVM test sequence reads these files using SystemVerilog $fscanf [2]:

fi = $fopen(instr_file, "r");
fc = $fopen(chkpt_file, "r");
$fscanf(fi, "%h", instr);
$fscanf(fc, "%h %h %h %h %h", pc, r0, r1, r2, r3);

Representative Checkpoint Format

Each line in checkpoints.mem represents the post-instruction state [2]:

0000 0000 0000 ffa2 0000   ; after instr 0
0001 000f 0000 ffa2 0000   ; after instr 1
0002 000f 0000 ffa2 0005   ; after instr 2

UVM Testbench Components

The CPU verification testbench comprises the following files [b02693db-011a-4664-a274-e2d5d421c19e, b5a349cf-7625-4030-b725-6cf21b6aa04a]:

File Component Role
cpu_if.sv Interface Bundles clk, rst, instr, pc, halt, r0–r3
cpu_seq_item.sv Sequence Item Holds instr, exp_r0–r3, act_r0–r3
cpu_driver.sv Driver Drives instr, reads actual registers
cpu_monitor.sv Monitor Passive DUT output observer
cpu_scoreboard.sv Scoreboard PASS/FAIL register comparator
cpu_agent.sv Agent Bundles driver+monitor+sequencer
cpu_env.sv Environment Connects via TLM analysis ports
cpu_test.sv Test Reads Python files, drives sequences
cpu_tb_pkg.sv Package Compilation order management
tb_top_cpu.sv Top Module DUT instantiation + UVM start

The scoreboard receives complete transaction objects from the driver containing Python-predicted values (exp_r0 through exp_r3) and actual DUT values (act_r0 through act_r3). Comparison uses the SystemVerilog === operator, which correctly handles 4-value logic (0, 1, X, Z) and avoids false passes when uninitialized X values propagate [2].

Verification Results

CPU verification results across 100 random instructions [b6b66b496-5c1e-4ae0-a78a-2658594b58b2]:

Experiment Instructions PASS FAIL Pass Rate
Correct RTL 100 100 0 100%
Buggy RTL (ADD→SUB) 100 0 100 0%

The correct RTL passed 100% of instructions spanning all 5 opcodes, all 4 destination registers, and the full signed immediate range (−128 to +127). The buggy RTL triggered FAIL for every instruction where ADD was selected, with each FAIL logging the expected vs. actual discrepancy precisely, enabling immediate bug localization.

Sample Scoreboard Output

PASS transaction [b6b66b496-5c1e-4ae0-a78a-2658594b58b2]:

UVM_INFO [SB] PASS | instr=26
r0=0002 r1=009b r2=0018 r3=006e

FAIL transaction (ADD→SUB bug injection) [b6b66b496-5c1e-4ae0-a78a-2658594b58b2]:

UVM_ERROR [SB] FAIL | instr=1
exp r2=ffa2 | got r2=005e

Comparison with Related Works

Among related UVM-based verification methodologies surveyed in the ConfigDrivenV paper, the 16-bit RISC Processor verification by ConfigDrivenV is distinguished by its use of a Python-constrained golden reference model with free EDA tools, achieving 100% pass rate [b6b66b496-5c1e-4ae0-a78a-2658594b58b2]:

Approach Stimulus Predictor Tools Result
Existing CPU ISA work Constrained random (SV) SV predictor Commercial Partial
ConfigDrivenV CPU+UART Python (Free) Python Free Tools 100%

Scalability

Test depth is controlled by a single Python variable NUM_INSTR, scaling verification from 30 to 1000 instructions without modifying any UVM code. Scalability results [b6b66b496-5c1e-4ae0-a78a-2658594b58b2]:

NUM_INSTR PASS (correct) FAIL (buggy) Est. Sim Time
30 30 30 ~1 s
50 50 50 ~2 s
100 100 100 ~3 s
200 200 200 ~5 s

CITATIONS

8 sources
8 citations
[1] The processor features a 4×16-bit register file, an 8-bit program counter, and a single-cycle execution FSM. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard
[2] The instruction set includes NOP (0x0), ADD (0x1), SUB (0x2), MOV (0x3), XOR (0x4), and HALT (0xF). ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard
[3] Instruction encoding follows the 16-bit format: bits [15:12] hold the opcode, bits [9:8] hold rd, and bits [7:0] hold the immediate value. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard
[4] Register state tracking is achieved through a four-element Python list, where each arithmetic operation applies bitwise AND with 0xFFFF to enforce 16-bit width constraints. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard
[5] The correct RTL passed 100% of instructions spanning all 5 opcodes, all 4 destination registers, and the full signed immediate range (-128 to +127); the buggy RTL achieved 0% pass rate. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard
[6] The UVM scoreboard uses the SystemVerilog === operator for comparison, which handles 4-value logic (0, 1, X, Z) correctly. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard
[7] Test depth is controlled by the NUM_INSTR variable, scaling verification from 30 to 1000 instructions without modifying any UVM code. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard
[8] The processor is implemented as simple_cpu.v and serves as DUT 1 in the ConfigDrivenV framework. ConfigDrivenV: A Python-Integrated UVM Testbench for Automated RTL Verification with Self-Checking Scoreboard