332 Simplified 6502 Processor

332 : Simplified 6502 Processor

Design render
  • Author: Sanjay Jayaram, Sri Charan Tadepalli, Dennis Chen
  • Description: A Simplified 6502 processor that does less than the original
  • GitHub repository
  • Open in 3D viewer
  • Clock: 40000000 Hz

Foreword

The 6502 resources we found compiled online did not reflect the hardware as much as expected most likely due to the fact that the provided information was for developers using the 6502 and not the actual design manual itself.

We also found that the 6502 was made with some strange practices in mind - at the time, microprocessor design space was not as advanced and explored; for instance, modern CPUs do not use multi-phase clock signals.

Thus, we decided to make some educated guesses and edits to 'improve' the design for our use cases, and make things easier. Finally, our code freeze occured before we could add any ADDR X type instructions (incrementing for arrays), which were deemed non-essential as they could be implemented via software (through program editing).

Overall though, our intention is for our 6502 to remain relatively authentic.

How it works

This project implements a custom 8-bit microprocessor inspired by the 6502 architecture. The design is built around a central Arithmetic Logic Unit (ALU), a collection of registers, and a microcoded instruction decoder that executes a subset of the 6502 instruction set.

block diagram

Core Architecture

The processor's operation is coordinated by several key functional blocks:

  • Instruction Decode: This is the control center of the CPU. It's a complex finite state machine that reads an instruction from the data bus, interprets its opcode and addressing mode, and generates the internal control signals required to execute it over a series of clock cycles.
  • Registers:
    • Program Counter (PC): A 16-bit register that holds the memory address of the next instruction to be fetched.
    • Accumulator (A): An 8-bit register used for most arithmetic and logical operations.
    • Index Registers (X and Y): Two 8-bit registers commonly used for indexed addressing modes and as general-purpose counters or temporary storage.
    • Processor Status Register (P): Contains a set of flags (e.g., Carry, Zero, Negative) that reflect the result of the most recent ALU operation.
  • Arithmetic Logic Unit (ALU): The computational core of the processor. It performs all arithmetic (add, increment, decrement), logical (AND, OR, XOR, shift, rotate), and comparison (CPX, CMP, CPY) operations. It takes inputs from the internal buses and updates the Processor Status Register flags based on the outcome of its calculation.
  • Internal Buses (Bus 1 & Bus 2): Two internal 8-bit buses that serve as the data highways connecting the registers and ALU, allowing for the transfer of operands and results within the CPU.
  • I/O Buffers:
    • Address Bus (AB): An internal 16-bit bus that holds the address for memory operations. Its value is selected from either the PC, a calculated memory address, or the ALU output.
    • Input Data Latch: Temporarily holds data read from the main data bus, typically an instruction operand or address byte.
    • Data Bus Buffer: Temporarily holds data from an internal register before it is written out to the main data bus.

Operational Cycle

The processor operates on a classic Fetch-Decode-Execute cycle controlled by the instruction decoder's state machine:

  1. Fetch: The address in the Program Counter (PC) is placed on the Address Bus to read the next instruction byte from memory. This byte is loaded into the instruction decoder. The PC is then incremented.
  2. Decode: The decoder logic analyzes the instruction. Based on the opcode, it determines which operation to perform and which addressing mode to use (e.g., Zero Page, Absolute, Immediate). This determines the subsequent states the machine will enter.
  3. Execute: The decoder sequences through one or more states to complete the instruction. This multi-cycle process may involve:
    • Fetching additional bytes from memory for operands or addresses.
    • Loading data from registers onto the internal buses to be used as ALU inputs.
    • Triggering an ALU operation.
    • Capturing the ALU output and flags.
    • Storing the result back into a register (A, X, or Y) or writing it to a memory location.

IO Pattern/Clock pattern

clock diagram

A unique characteristic of this design is its clocking scheme. The internal CPU logic runs at half the frequency of the external clk input.

This is a deliberate design choice to manage the physical pin limitations of the hardware.

  • Address Bus: The 16-bit address bus (ab) is too wide for the available output pins. It is therefore multiplexed and output via the 8-bit uo_out port over two consecutive clock cycles.

  • Data Bus: The 8-bit bidirectional data bus is handled by the uio_in, uio_out, and uio_oe pins, whether to read or write to memory is multiplexed with the data we want on the bus(though this is a vestige of before we realized we could just use uio_oe and that is the recommended method now, thus you can just ignore the rw flag on the off cycle)

  • External Memory: We make the assumption that as soon as the full address has been put to the uo_out port, the external memory can return with the value, or finish a write transaction By the start of the next clock cycle

Addressing Modes

The processor supports a variety of addressing modes to provide flexibility in accessing data. The specific mode for an instruction is implicitly defined by its opcode.

In the descriptions below, a "CPU Cycle" refers to a complete state transition in the processor's core logic. Due to the I/O multiplexing scheme, each CPU Cycle takes two cycles of the main input clk.


1. Implied and Register Addressing

These are the simplest modes. The instruction operates directly on a register or has no operand, so the instruction itself is a single byte.

  • Example: TAX (Transfer Accumulator to X Register)
  • Instruction Format: 8A
  • CPU Cycles: 2
  • Cycle-by-Cycle Breakdown:
    • Cycle 1 (Fetch Opcode): The PC is placed onto the address bus, and 8A is read. The PC is incremented.
    • Cycle 2 (Execute): The value in the Accumulator is placed into X using bus1 as the intermediary

2. Accumulator Addressing

In this mode, the instruction operates directly on the Accumulator. Like Implied addressing, it is a single-byte instruction. It is primarily used for shift and rotate operations.

  • Example: ASL A (Arithmetic Shift Left on Accumulator)
  • Instruction Format: 0A
  • CPU Cycles: 4
  • Cycle-by-Cycle Breakdown:
    • Cycle 1 (Fetch Opcode): The PC is placed onto the address bus, and 0A is read. The PC is incremented.
    • Cycle 2 (Execute): The value in the accumulator is sent to the ALU, which is given the ASL Opcode and performs the Left Shift operation. The result is calculated and flags are updated.
    • Cycle 3 (Transfer Result): The output from the ALU is written to bus2 and the Accumulator is told to read from bus2
    • Cycle 4 (Hold): The accumulator reads from bus2 with the final value

3. Immediate Addressing

The operand for the instruction is the literal value contained in the byte immediately following the opcode.

  • Example (Load): LDA #44 (Load Accumulator with the value $44)

  • Instruction Format: A9 44

  • CPU Cycles: 5

  • Cycle-by-Cycle Breakdown:

    • Cycle 1 (Fetch Opcode): The PC is placed onto the address bus, and A9 is read. The PC is incremented.
    • Cycle 2 (Read from Memory): The PC is placed on the address bus. The data at that location is read into the Input Data Latch. The PC is Incremented
    • Cycle 3 (Transfer Result): The data from the latch is written to bus1 and the Accumulator is told to read from bus1
    • Cycle 4 (Hold): The accumulator reads from bus1 with the final value
    • Cycle 5 (None): The cpu does nothing here due to the fixed machine state path
  • Example (Read-Modify-Write to Accumulator): ORA #44 (OR Accumulator with the value $44)

  • Instruction Format: 09 44

  • CPU Cycles: 5

  • Cycle-by-Cycle Breakdown:

    • Cycle 1 (Fetch Opcode): The PC is placed onto the address bus, and 09 is read. The PC is incremented.
    • Cycle 2 (Read from Memory): The PC is placed on the address bus. The data at that location is read into the Input Data Latch. The PC is Incremented
    • Cycle 3 (Execute): The data from the latch and the value in the Accumulator is sent to the ALU, which is given the AND Opcode and performs the Left Shift operation. The result is calculated and flags are updated.
    • Cycle 3 (Transfer Result): The output from the ALU is written to bus2 and the Accumulator is told to read from bus2
    • Cycle 4 (Hold): The accumulator reads from bus2 with the final value

4. Relative Addressing

Like the previous addressing mode, the operand for the instruction is the literal value contained in the byte immediately following the opcode. The operand is an unsigned number who's value is added to the program counter if the branch condition is true.

  • Example (Load): BNE #44 (Increment program counter by $44 if the zero flag is not set)
  • Instruction Format: D0 44
  • CPU Cycles: 4
  • Cycle-by-Cycle Breakdown:
    • Cycle 1 (Fetch Opcode): The PC is placed onto the address bus, and D0 is read. The PC is incremented.
    • Cycle 2 (Read from Memory): The PC is placed on the address bus. The data at that location is read into the Input Data Latch. The PC is Incremented
    • Cycle 3 (Increment Program Counter): The data from the latch is written to bus1 and the program counter increments by the value in bus1 if the instruction decode block indicates the condition is met
    • Cycle 4 (None): The cpu does nothing here due to the fixed machine state path

5. Zero-Page Addressing

This mode provides faster memory access by using a single byte to specify an address within the first 256 bytes of memory (Page 0, addresses $0000 to $00FF).

  • Example (Load): LDA $44 (Load Accumulator from address $0044)

  • Instruction Format: A5 44

  • CPU Cycles: 4

  • Cycle-by-Cycle Breakdown:

    • Cycle 1 (Fetch Opcode): Fetches the opcode ($A5). PC is incremented.
    • Cycle 2 (Fetch ZP Address): Fetches the operand ($44), which is the low byte of the effective address. PC is incremented.
    • Cycle 3 (Read from Memory): The full address ($0044) is placed on the address bus. The data at that location is read into the Input Data Latch.
    • Cycle 4 (Writeback): The value is loaded from the Input Data Latch into the Accumulator.
  • Example (Read-Modify-Write To Accumulator): AND $44 (AND the Accumulator and the byte at address $0044 and write to the Accumulator)

  • Instruction Format: 25 44

  • CPU Cycles: 6

  • Cycle-by-Cycle Breakdown:

    • Cycle 1 (Fetch Opcode): The PC is placed onto the address bus, and 25 is read. The PC is incremented.
    • Cycle 2 (Fetch ZP Address): Fetches the operand ($44), which is the low byte of the effective address. PC is incremented.
    • Cycle 3 (Read from Memory): The full address ($0044) is placed on the address bus. The data at that location is read into the Input Data Latch.
    • Cycle 4 (Execute): The data from the latch and the value in the Accumulator is sent to the ALU, which is given the AND Opcode and performs the Left Shift operation. The result is calculated and flags are updated.
    • Cycle 5 (Transfer Result): The output from the ALU is written to bus2 and the Accumulator is told to read from bus2
    • Cycle 6 (Hold): The accumulator reads from bus2 with the final value
  • Example (Read-Modify-Write To Memory): ASL $44 (Arithmetic Shift Left on the byte at address $0044)

  • Instruction Format: 06 44

  • CPU Cycles: 7

  • Cycle-by-Cycle Breakdown:

    • Cycle 1 (Fetch Opcode): The PC is placed onto the address bus, and 0A is read. The PC is incremented.
    • Cycle 2 (Fetch ZP Address): Fetches the operand ($44), which is the low byte of the effective address. PC is incremented.
    • Cycle 3 (Read from Memory): The full address ($0044) is placed on the address bus. The data at that location is read into the Input Data Latch.
    • Cycle 4 (Execute): The data from the latch is sent to the ALU, which is given the ASL Opcode and performs the Left Shift operation. The result is calculated and flags are updated.
    • Cycle 5 (Transfer to Buffer): The output value from the ALU is loaded into the Data Bus Buffer
    • Cycle 6 (Writeback to Memory): The HB of the address ($00) is placed on the address bus, and the Data Bus Buffer content is written to the IO Bus.
    • Cycle 7 (Write Address LB to address bus): The LB of the address ($44) is placed on the address bus, and the IO Bus content is written to memory(this step is mostly off chip)

6. Absolute Addressing

This mode uses a full 16-bit address to access any location in the 64KB memory space. The address follows the opcode as two bytes in little-endian format (low byte first).

  • Example (Read-Modify-Write To Accumulator): EOR $1234 (XOR the Accumulator and the byte at address $1234 and write to the Accumulator)

  • Instruction Format: 4d 44

  • CPU Cycles: 7

  • Cycle-by-Cycle Breakdown:

    • Cycle 1 (Fetch Opcode): The PC is placed onto the address bus, and 25 is read. The PC is incremented.
    • Cycle 2 (Fetch Address Low Byte): Fetches the low byte of the address ($34) and writes it to an internal buffer. PC is incremented.
    • Cycle 3 (Fetch Address High Byte): Fetches the high byte of the address ($12). The full address $1234 is now assembled. PC is incremented.
    • Cycle 3 (Read from Memory): The full address ($0044) is placed on the address bus. The data at that location is read into the Input Data Latch.
    • Cycle 4 (Execute): The data from the latch and the value in the Accumulator is sent to the ALU, which is given the AND Opcode and performs the Left Shift operation. The result is calculated and flags are updated.
    • Cycle 5 (Transfer Result): The output from the ALU is written to bus2 and the Accumulator is told to read from bus2
    • Cycle 6 (Hold): The accumulator reads from bus2 with the final value
  • Example (Read-Write-Modify to Memory): STA $1234 (Store Accumulator at address $1234)

  • Instruction Format: 8D 34 12

  • CPU Cycles: 8

  • Cycle-by-Cycle Breakdown:

    • Cycle 1 (Fetch Opcode): The PC is placed onto the address bus, and 8D is read. The PC is incremented.
    • Cycle 2 (Fetch Address Low Byte): Fetches the low byte of the address ($34) and writes it to an internal buffer. PC is incremented.
    • Cycle 3 (Fetch Address High Byte): Fetches the high byte of the address ($12). The full address $1234 is now assembled. PC is incremented.
    • Cycle 4 (Read from Memory): The hardware reads from the target address ($1234). For a store instruction, this read is superfluous but occurs due to the fixed state machine path.
    • Cycle 5 (Execute): The ALU performs no meaningful operation for a store instruction.
    • Cycle 6 (Transfer to Buffer): The value in the Accumulator is placed on bus2 and loaded into the Data Bus Buffer.
    • Cycle 7 (Writeback to Memory): The HB of the address ($12) is placed on the address bus, and the Data Bus Buffer content is written to the IO Bus.
    • Cycle 8 (Write Address LB to address bus): The LB of the address ($34) is placed on the address bus, and the IO Bus content is written to memory(this step is mostly off chip)

How to test

Verifying a processor design like this 6502 requires a robust testing strategy. The following sections describe two detailed approaches for ensuring its correctness, each with its own strengths.

Cycle-Accurate Testbench Emulation

This approach uses a testbench that acts as an intelligent and perfect memory system. Instead of simulating a passive RAM block, the testbench actively interacts with the CPU on a cycle-by-cycle basis. It precisely controls the data fed to the processor and meticulously verifies the signals coming out of it at every stage of an instruction's execution.

This methodology provides extremely granular control and visibility, allowing for the verification of both the logical outcome of an instruction and its exact timing. A typical test for a single instruction follows these steps:

  1. Initiate Instruction: The testbench begins by placing the instruction's opcode onto the uio_in pins at the exact moment the CPU is ready to fetch it.
  2. Monitor Address Bus: The processor outputs the 16-bit address of the memory location it intends to access (e.g., the address held in the Program Counter). This address is multiplexed onto the 8-bit uo_out port over two clock cycles (High Byte, then Low Byte). The testbench reads both bytes, reassembles the full address, and asserts that it is correct for the current step in the operation.
  3. Emulate Memory Read: When the CPU needs to fetch an operand, such as an address byte or an immediate value, the testbench waits for the correct address to appear on uo_out and for the rw signal to indicate a read operation. It then immediately places the required data onto the uio_in pins, perfectly emulating a memory device responding to a read request.
  4. Verify Memory Write: If an instruction results in a memory write (like STA or a read-modify-write instruction such as ASL), the testbench verifies several key signals to confirm the write is correct:
    • The correct destination address is present on the uo_out port.
    • The correct data value is being driven by the CPU onto the uio_out pins.
    • The I/O direction pin, uio_oe, is asserted high to enable the output driver.
    • The rw (read/write) signal is driven low to indicate a write cycle.
  5. Check Final State: Once the instruction is complete, the testbench runs subsequent instructions to read the contents of the affected register (Accumulator, X, or Y) or memory location. This allows verification that the instruction had the intended final effect on the processor's state.

This is the method that our instruction specific cocotb tests follow.

System-Level Program Execution

An alternative testing philosophy involves a more traditional, system-level simulation. In this scenario, the CPU is tested as one component within a larger, simulated system that more closely resembles a real-world computer. This approach is less focused on the individual cycles of an instruction and more on the processor's ability to execute a sequence of instructions correctly.

The process for this type of test would be:

  1. Instantiate a Full System: The test setup would include the CPU Verilog model alongside a Verilog model of a RAM block and any other necessary peripherals.
  2. Pre-load Program: Before the simulation begins, a complete program—a binary sequence of machine code—is loaded into the simulated RAM model.
  3. Free-Run Execution: The CPU is reset and then allowed to run freely. It will begin fetching instructions from the simulated RAM, starting from the reset vector address, and execute the program autonomously without direct cycle-by-cycle intervention from the testbench.
  4. Verify Final State: After a predetermined number of clock cycles or upon reaching a NOP or halt instruction, the simulation is paused. The testbench then reads the final state of the CPU's internal registers and specific, relevant memory locations within the simulated RAM. This final state is compared against a known-good result to determine if the program executed successfully.

This method excels at verifying the processor's capability to run larger, more complex software, but provides less direct insight into the low-level timing and signal behavior of individual instructions.

This is the method that our fuzzing cocotb tests follow.

Examples of these testing methods can be found in our test.py file, any function that include the word fuzz in their name follow method 2 and every other test follows method 1

Programming Guide

This guide provides the essential information needed to write assembly-level programs for this 6502-inspired processor. Adhering to these guidelines is critical for ensuring your code runs correctly.

Startup and Initialization

On power-up or after a reset, the processor's internal state is initialized as follows:

  • Program Counter (PC): The PC is set to $0000. The processor will immediately attempt to fetch its first instruction from this memory address.

  • Mandatory NOP Instruction: For proper initialization and predictable execution, the first instruction at memory address $0000 must be a NOP ($EA). The processor uses this initial two-cycle instruction to correctly align its internal state machine. Your program's main logic should begin at address $0001.

Contiguous Memory Layout

Your program's machine code (the binary opcodes and operands) must be stored as a continuous block in memory. The processor fetches instructions sequentially, and after an instruction completes, the Program Counter will point to the very next memory address. It expects to find the opcode of the next instruction at that exact location.

You cannot leave empty or unused bytes between your instructions, as the processor would attempt to interpret whatever data is in that gap as a valid instruction, leading to a crash or undefined behavior (though given how we have designed the CPU, it will most likely just be a NOP).

For example, if a 3-byte instruction like STA $0210 starts at address $0003, it will occupy addresses $0003 (opcode), $0004 (operand low byte), and $0005 (operand high byte). The very next instruction in your program should begin at address $0006.

Known Hardware Limitations

  • Page Boundary Bug: There is a known limitation in this hardware implementation that prevents reliable memory access to the final byte of any memory page. Programmers must ensure that no instruction opcodes, operands, or data addresses are placed at a memory location ending in $FF (e.g., $00FF, $01FF, $C3FF, etc.). Accessing these specific addresses will lead to unpredictable behavior and program failure.

Example Program: 8-Bit Multiplication

Here is a program that multiplies two 8-bit numbers using repeated addition. This demonstrates looping, branching, and memory manipulation. The program multiplies the number at address $00FA by the number at $00FB and stores the 8-bit result at $00FC.

; Program to multiply Number A ($FA) by Number B ($FB).
; The final 8-bit result is stored in $FC.

; --- Memory Setup ---
; $FA: Multiplicand (Number A)
; $FB: Multiplier   (Number B, used as the loop counter)
; $FC: Result      (Initialized to 0)

; --- Initialization ---
$0000: EA      ; Mandatory NOP for startup.

$0001: A9 00 ; LDA #$00. Clear the accumulator.
$0003: 85 FC ; STA $FC. Initialize the result location at $FC to zero.

; --- Main Loop and Comparison ---
$0005: A5 FB ; Load the counter (B) from memory into the accumulator.
$0007: C9 00 ; CMP #$00. Compare the accumulator's value with the 
             ; immediate value 0.
             ; This sets the Zero flag if the counter has reached zero.
$0009: F0 0C ; BEQ end_program. If the Zero flag is set (counter is 0),
             ; branch to the end.
             ; Branch target: Current PC+2+offset = $000B + $0C = $0017.

; --- Loop Body (Executes if B is not zero) ---
$000B: C6 FB ; DEC $FB. Decrement the counter value in memory.
$000D: A5 FC ; LDA $FC. Load the current running total from memory into
             ;the accumulator.
$000F: 65 FA ; ADC $FA. Add number A to the running total.
$0011: 85 FC ; STA $FC. Store the new total back into the result location.
$0013: 4C 05 00 ; JMP loop. Jump unconditionally back to the start
                ;of the loop.

; --- End of Program ---
; The final result is already in memory at $FC. We can halt here.
$0016: 4C 16 00    ; JMP end_program. Halt the CPU by jumping 
                   ;to the same address indefinitely.

This program correctly follows all guidelines: it starts with a NOP at $0000, the machine code is laid out sequentially without gaps, and it avoids placing any code or data at an xxFF address.

Addendum 1

Table of Supported Instructions:

Instruction Name Instruction Format Time Taken Flags Changed
ARITHMETIC ZPG INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
ASL ZPG (Arithmatic Shift Left) 06 addr-lb 7 N Z C - - -
LSR ZPG (Logical Shift Right) 46 addr-lb 7 0 Z C - - -
ROL ZPG (Roll Byte Left) 26 addr-lb 7 N Z C - - -
ROR ZPG (Roll Byte Right) 46 addr-lb 7 N Z C - - -
INC ZPG (Increment Byte) e6 addr-lb 7 N Z - - - -
DEC ZPG (Decrement Byte) c6 addr-lb 7 N Z - - - -
AND ZPG (AND Byte with Acc) 35 addr-lb 6 N Z - - - -
ORA ZPG (OR Byte with Acc) 05 addr-lb 6 N Z - - - -
EOR ZPG (XOR Byte with Acc) 55 addr-lb 6 N Z - - - -
ADC ZPG (Add Byte with Acc) 65 addr-lb 6 N Z C - - -
SBC ZPG (Subtract Byte with Acc) e5 addr-lb 6 N Z C - - -
----------------------------------- -------------------- ----------------- ---------------
STORE ZPG INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
STY ZPG (Store Y) 84 addr-lb 7 - - - - - -
STA ZPG (Store Accumulator) 85 addr-lb 7 - - - - - -
STX ZPG (Store X) 86 addr-lb 7 - - - - - -
----------------------------------- -------------------- ----------------- ---------------
LOAD ZPG INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
LDY ZPG (Load Y) a4 addr-lb 6 - - - - - -
LDA ZPG (Load Accumulator) a5 addr-lb 6 - - - - - -
LDX ZPG (Load X) a6 addr-lb 6 - - - - - -
----------------------------------- -------------------- ----------------- ---------------
COMPARE INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
CPX ZPG (Compare X with ZPG) e4 addr-lb 6 N Z C - - -
CPX ABS (Compare X with ABS) ec addr-lb addr-hb 7 N Z C - - -
CPX IMM (Compare X with IMM) e0 imm 5 N Z C - - -
CMP ZPG (Compare Acc with ZPG) c5 addr-lb 6 N Z C - - -
CMP ABS (Compare Acc with ABS) cd addr-lb addr-hb 7 N Z C - - -
CMP IMM (Compare Acc with IMM) c9 imm 5 N Z C - - -
CPY ZPG (Compare Y with ZPG) c4 addr-lb 6 N Z C - - -
CPY ABS (Compare Y with ABS) cc addr-lb addr-hb 7 N Z C - - -
CPY IMM (Compare Y with IMM) c0 imm 5 N Z C - - -
----------------------------------- -------------------- ----------------- ---------------
BRANCH INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
BPL REL (Branch if Negative flag is 0) 10 rel 4 - - - - - -
BMI REL (Branch if Negative flag is 1) 30 rel 4 - - - - - -
BCC REL (Branch if Carry flag is 0) 90 rel 4 - - - - - -
BCS REL (Branch if Carry flag is 1) b0 rel 4 - - - - - -
BNE REL (Branch if Zero flag is 0) d0 rel 4 - - - - - -
BEQ REL (Branch if Zero flag is 1) f0 rel 4 - - - - - -
----------------------------------- -------------------- ----------------- ---------------
TRANSFER INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
TXA (Transfer from X to Acc) 8a 2 - - - - - -
TYA (Transfer from Y to Acc) 98 2 - - - - - -
TAX (Transfer from Acc to X) aa 2 - - - - - -
TAY (Transfer from Acc to Y) a8 2 - - - - - -
----------------------------------- -------------------- ----------------- ---------------
ARITHMETIC ABS INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
ASL ABS (Arithmatic Shift Left) 0e addr-lb addr-hb 8 N Z C - - -
LSR ABS (Logical Shift Right) 4e addr-lb addr-hb 8 0 Z C - - -
ROL ABS (Roll Byte Left) 2e addr-lb addr-hb 8 N Z C - - -
ROR ABS (Roll Byte Right) 4e addr-lb addr-hb 8 N Z C - - -
INC ABS (Increment Byte) ce addr-lb addr-hb 8 N Z - - - -
DEC ABS (Decrement Byte) ee addr-lb addr-hb 8 N Z - - - -
AND ABS (AND Byte with Acc) 3d addr-lb addr-hb 7 N Z - - - -
ORA ABS (OR Byte with Acc) 0d addr-lb addr-hb 7 N Z - - - -
EOR ABS (XOR Byte with Acc) 5d addr-lb addr-hb 7 N Z - - - -
ADC ABS (Add Byte with Acc) 6d addr-lb addr-hb 7 N Z C - - V
SBC ABS (Subtract Byte with Acc) ed addr-lb addr-hb 7 N Z C - - V
----------------------------------- -------------------- ----------------- ---------------
STORE ABS INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
STY ABS (Store Y) 8c addr-lb addr-hb 8 - - - - - -
STA ABS (Store Accumulator) 8d addr-lb addr-hb 8 - - - - - -
STX ABS (Store X) 8e addr-lb addr-hb 8 - - - - - -
----------------------------------- -------------------- ----------------- ---------------
LOAD ABS INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
LDY ABS (Load Y) ac addr-lb addr-hb 7 - - - - - -
LDA ABS (Load Accumulator) ad addr-lb addr-hb 7 - - - - - -
LDX ABS (Load X) ae addr-lb addr-hb 7 - - - - - -
----------------------------------- -------------------- ----------------- ---------------
ARITHMETIC IMM INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
ASL IMM (Arithmatic Shift Left) 09 imm 5 N Z C - - -
LSR IMM (Logical Shift Right) 49 imm 5 0 Z C - - -
ROL IMM (Roll Byte Left) 29 imm 5 N Z C - - -
ROR IMM (Roll Byte Right) 49 imm 5 N Z C - - -
SBC IMM (Subtract Byte against Acc) e9 imm 5 N Z C - - V
----------------------------------- -------------------- ----------------- ---------------
LOAD IMM INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
LDY IMM (Load Y) a0 imm 5 - - - - - -
LDA IMM (Load Accumulator) a9 imm 5 - - - - - -
LDX IMM (Load X) a2 imm 5 - - - - - -
----------------------------------- -------------------- ----------------- ---------------
INC/DEC REGISTER INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
INX (Increment X) e8 4 - - - - - -
INY (Increment Y) c8 4 - - - - - -
DEX (Decrement X) ca 4 - - - - - -
DEY (Decrement Y) 88 4 - - - - - -
----------------------------------- -------------------- ----------------- ---------------
ARITHMETIC ACC INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
ASL A (Arithmatic Shift Left Acc) 0a 4 N Z C - - -
LSR A (Logical Shift Right Acc) 4a 4 N Z C - - -
ROL A (Roll Byte Left Acc) 2a 4 N Z C - - -
ROR A (Roll Byte Right Acc) 6a 4 N Z C - - -
----------------------------------- -------------------- ----------------- ---------------
OTHER INSTRUCTIONS
----------------------------------- -------------------- ----------------- ---------------
NOP (No Op) ea 2 - - - - - -
JMP ABS (Jump) 4c addr-lb addr-hb 4 - - - - - -
CLC REL (Clear Carry Flag) 18 2 - - 0 - - -
SEC REL (Set Carry Flag) 38 2 - - 1 - - -

IO

#InputOutputBidirectional
0addr 0/8data 0
1addr 1/9data 1
2addr 2/10data 2
3addr 3/11data 3
4addr 4/12data 4
5addr 5/13data 5
6addr 6/14data 6
7addr 7/15data 7

Chip location

Controller Mux Mux Mux Mux Mux Mux Mux Mux Mux Analog Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Analog Mux Mux Mux Mux Analog Mux Mux Mux Mux Mux Mux tt_um_chip_rom (Chip ROM) tt_um_factory_test (Tiny Tapeout Factory Test) tt_um_oscillating_bones (Oscillating Bones) tt_um_rebelmike_incrementer (Incrementer) tt_um_rebeccargb_tt09ball_gdsart (TT09Ball GDS Art) tt_um_tt_tinyQV (TinyQV 'Asteroids' - Crowdsourced Risc-V SoC) tt_um_DalinEM_asic_1 (ASIC) tt_um_urish_simon (Simon Says memory game) tt_um_rburt16_bias_generator (Bias Generator) tt_um_librelane3_test (Tiny Tapeout LibreLane 3 Test) tt_um_10_vga_crossyroad (Crossyroad) tt_um_rebeccargb_universal_decoder (Universal Binary to Segment Decoder) tt_um_rebeccargb_hardware_utf8 (Hardware UTF Encoder/Decoder) tt_um_rebeccargb_intercal_alu (INTERCAL ALU) tt_um_rebeccargb_dipped (Densely Packed Decimal) tt_um_rebeccargb_styler (Styler) tt_um_rebeccargb_vga_timing_experiments (VGA Timing Experiments) tt_um_rebeccargb_colorbars (Color Bars) tt_um_rebeccargb_vga_pride (VGA Pride) tt_um_cw_vref (Current-Mode Bandgap Reference) tt_um_tinytapeout_logo_screensaver (VGA Screensaver with Tiny Tapeout Logo) tt_um_rburt16_opamp_3stage (OpAmp 3stage) tt_um_gamepad_pmod_demo (Gamepad Pmod Demo) tt_um_micro_tiles_container (Micro tile container) tt_um_virantha_enigma (Enigma - 52-bit Key Length) tt_um_jamesrosssharp_1bitam (1bit_am_sdr) tt_um_jamesrosssharp_tiny1bitam (Tiny 1-bit AM Radio) tt_um_MichaelBell_rle_vga (RLE Video Player) tt_um_MichaelBell_mandelbrot (VGA Mandelbrot) tt_um_murmann_group (Decimation Filter for Incremental and Regular Delta-Sigma Modulators) tt_um_betz_morse_keyer (Morse Code Keyer) tt_um_urish_giant_ringosc (Giant Ring Oscillator (3853 inverters)) tt_um_tiny_pll (Tiny PLL) tt_um_tc503_countdown_timer (Countdown Timer) tt_um_richardgonzalez_ped_traff_light (Pedestrian Traffic Light) tt_um_analog_factory_test (TT08 Analog Factory Test) tt_um_alexandercoabad_mixedsignal (mixedsignal) tt_um_tgrillz_sixSidedDie (Six Sided Die) tt_um_mattvenn_analog_ring_osc (Ring Oscillators) tt_um_vga_clock (VGA clock) tt_um_mattvenn_r2r_dac_3v3 (Analog 8 bit 3.3v R2R DAC) tt_um_mattvenn_spi_test (SPI test) tt_um_quarren42_demoscene_top (asic design is my passion) tt_um_micro_tiles_container_group2 (Micro tile container (group 2)) tt_um_z2a_rgb_mixer (RGB Mixer demo) tt_um_frequency_counter (Frequency counter) tt_um_urish_sic1 (SIC-1 8-bit SUBLEQ Single Instruction Computer) tt_um_tobi_mckellar_top (Capacitive Touch Sensor) tt_um_log_afpm (16-bit Logarithmic Approximate Floating Point Multiplier) tt_um_uwasic_dinogame (UW ASIC - Optimized Dino) tt_um_ece298a_8_bit_cpu_top (8-Bit CPU) tt_um_tqv_peripheral_harness (Rotary Encoder Peripheral) tt_um_led_matrix_driver (SPI LED Matrix Driver) tt_um_2048_vga_game (2048 sliding tile puzzle game (VGA)) tt_um_mac (MAC) tt_um_dpmunit (DPM_Unit) tt_um_nitelich_riscyjr (RISCY Jr.) tt_um_nitelich_conway (Conway's GoL) tt_um_pwen (Pulse Width Encoder) tt_um_mcs4_cpu (MCS-4 4004 CPU) tt_um_mbist (Design of SRAM BIST) tt_um_weighted_majority (Weighted Majority Voter / Trend Detector) tt_um_brandonramos_VGA_Pong_with_NES_Controllers (VGA Pong with NES Controllers) tt_um_brandonramos_opamp_ladder (2-bit Flash ADC) tt_um_NE567Mixer28 (OTA folded cascode) tt_um_acidonitroso_programmable_threshold_voltage_sensor (Programmable threshold voltage sensor) tt_um_DAC1 (tt_um_DAC1) tt_um_trivium_stream_processor (Trivium Stream Cipher) tt_um_analog_example (Digital OTA) tt_um_sortaALUAriaMitra (Sorta 4-Bit ALU) tt_um_RoyTr16 (Connect Four VGA) tt_um_jnw_wulffern (JNW-TEMP) tt_um_serdes (Secure SERDES with Integrated FIR Filtering) tt_um_limpix31_r0 (VGA Human Reaction Meter) tt_um_torurstrom_async_lock (Asynchronous Locking Unit) tt_um_galaguna_PostSys (Post's Machine CPU Based) tt_um_edwintorok (Rounding error) tt_um_td4 (tt-td04) tt_um_snn (Reward implemented Spiking Neural Network) tt_um_matrag_chirp_top (Tiny Tapeout Chirp Modulator) tt_um_sha256_processor_dvirdc (SHA-256 Processor) tt_um_pchri03_levenshtein (Fuzzy Search Engine) tt_um_AriaMitraClock (12 Hour Clock (with AM and PM)) tt_um_swangust (posit8_add) tt_um_DelosReyesJordan_HDL (Reaction Time Test) tt_um_upalermo_simple_analog_circuit (Simple Analog Circuit) tt_um_swangust2 (posit8_mul) tt_um_thexeno_rgbw_controller (RGBW Color Processor) tt_um_top_layer (Spike Detection and Classification System) tt_um_Alida_DutyCycleMeter (Duty Cycle Meter) tt_um_dco (Digitally Controlled Oscillator) tt_um_8bitalu (8-bit Pipelined ALU) tt_um_resfuzzy (resfuzzy) tt_um_javibajocero_top (MarcoPolo) tt_um_Scimia_oscillator_tester (Oscillator tester) tt_um_ag_priority_encoder_parity_checker (Priority Encoder with Parity Checker) tt_um_tnt_mosbius (tnt's variant of SKY130 mini-MOSbius) tt_um_program_counter_top_level (Test Design 1) tt_um_subdiduntil2_mixed_signal_classifier (Mixed-signal Classifier) tt_um_dac_test3v3 (Analog 8 bit 3.3v R2R DAC) tt_um_LPCAS_TP1 ( LPCAS_TP1 ) tt_um_regfield (Register Field) tt_um_delaychain (Delay Chain) tt_um_tdctest_container (Micro tile container) tt_um_spacewar (Spacewar) tt_um_Enhanced_pll (Enhance PLL) tt_um_romless_cordic_engine (ROM-less Cordic Engine) tt_um_ev_motor_control (PLC Based Electric Vehicle Motor Control System) tt_um_plc_prg (PLC-PRG) tt_um_kishorenetheti_tt16_mips (8-bit MIPS Single Cycle Processor) tt_um_snn_core (Adaptive Leaky Integrate-and-Fire spiking neuron core for edge AI) tt_um_myprocessor (8-bit Custom Processor) tt_um_sjsu (SJSU vga demo) tt_um_vedic_4x4 (Vedic 4x4 Multiplier) tt_um_braun_mult (8x8 Braun Array Multiplier) tt_um_r2r_dac (4-bit R2R DAC) tt_um_stochastic_integrator_tt9_CL123abc (Stochastic Integrator) tt_um_uart (UART Controller with FIFO and Interrupts) tt_um_lfsr_stevej (Linear Feedback Shift Register) tt_um_FFT_engine (FFT Engine) tt_um_tpu (Tiny Tapeout Tensor Processing Unit) tt_um_tt_tinyQVb (TinyQV 'Berzerk' - Crowdsourced Risc-V SoC) tt_um_IZ_RG_22 (IZ_RG_22) tt_um_32_bit_fp_ALU_S_M (32-bit floating point ALU) tt_um_AriaMitraGames (Games (Tic Tac Toe and Rock Paper Scissors)) tt_um_sc_bipolar_qif_neuron (Stochastic Computing based QIF model neuron) tt_um_mac_spst_tiny (Low Power and Enhanced Speed Multiplier, Accumulator with SPST Adder) tt_um_kb2ghz_xalu (4-bit minicomputer ALU) tt_um_emmersonv_tiq_adc (3 Bit TIQ ADC) tt_um_simonsays (Simon Says) tt_um_BNN (8-bit Binary Neural Network) tt_um_anweiteck_2stageCMOSOpAmp (2 Stage CMOS Op Amp) tt_um_6502 (Simplified 6502 Processor) tt_um_swangust3 (posit8_div) tt_um_jonathan_thing_vga (VGA-Video-Player) tt_um_wokwi_412635532198550529 (ttsky-pettit-wokproc-trainer) tt_um_vga_hello_world (VGA HELLO WORLD) tt_um_jyblue1001_pll (Analog PLL) tt_um_BryanKuang_mac_peripheral (8-bit Multiply-Accumulate (MAC) with 2-Cycle Serial Interface) tt_um_rebeccargb_tt09ball_screensaver (TT09Ball VGA Screensaver) tt_um_openfpga22 (Open FGPA 2x2 design) tt_um_andyshor_demux (Demux) tt_um_flash_raid_controller (SPI flash raid controller) tt_um_jonnor_pdm_microphone (PDM microphone) tt_um_digital_playground (Sky130 Digital Playground) tt_um_mod6_counter (Mod-6 Counter) tt_um_BMSCE_T2 (Choreo8) tt_um_Richard28277 (4-bit ALU) tt_um_shuangyu_top (Calculator) tt_um_wokwi_441382314812372993 (Sumador/restador de 4 bits) tt_um_TensorFlowE (TensorFlowE) tt_um_wokwi_441378095886546945 (7SDSC) tt_um_wokwi_440004235377529857 (Latched 4-bits adder) tt_um_dlmiles_tqvph_i2c (TinyQV I2C Controller Device) tt_um_markgarnold_pdp8 (Serial PDP8) tt_um_wokwi_441564414591667201 (tt-parity-detector) tt_um_vga_glyph_mode (VGA Glyph Mode) tt_um_toivoh_pwl_synth (PiecewiseOrionSynth Deluxe) tt_um_minirisc (MiniRISC-FSM) tt_um_wokwi_438920793944579073 (Multiple digital design structures) tt_um_sleepwell (Sleep Well) tt_um_lcd_controller_Andres078 (LCD_controller) tt_um_SummerTT_HDL (SJSU Summer Project: Game of Life) tt_um_chrishtet_LIF (Leaky Integrate and Fire Neuron) tt_um_diff (ttsky25_EpitaXC) tt_um_htfab_split_flops (Split Flops) tt_um_alu_4bit_wrapper (4-bit ALU with Flags) tt_um_tnt_rf_test (TTSKY25A Register File Test) tt_um_mosbius (mini mosbius) tt_um_robot_controller_top_module (AR Chip) tt_um_flummer_ltc (Linear Timecode (LTC) generator) tt_um_stress_sensor (Tiny_Tapeout_2025_three_sensors) tt_um_krisjdev_manchester_baby (Manchester Baby) tt_um_mbikovitsky_audio_player (Simple audio player) tt_um_wokwi_414123795172381697 (TinySnake) tt_um_vga_example (Jabulani Ball VGA Demo ) tt_um_stochastic_addmultiply_CL123abc (Stochastic Multiplier, Adder and Self-Multiplier) tt_um_nvious_graphics (nVious Graphics) tt_um_pe_simonbju (pe) tt_um_mikael (TinyTestOut) tt_um_brent_kung (brent-kung_4) tt_um_7FM_ShadyPong (ShadyPong) tt_um_algofoogle_vga_matrix_dac (Analog VGA CSDAC experiments) tt_um_tv_b_gone (TV-B-Gone) tt_um_sjsu_vga_music (SJSU Fight Song) tt_um_fsm_haz (FSM based RISC-V Pipeline Hazard Resolver) tt_um_dma (DMA controller) tt_um_3v_inverter_SiliconeGuide (Analog Double Inverter) tt_um_rejunity_lgn_mnist (LGN hand-written digit classifier (MNIST, 16x16 pixels)) tt_um_gray_sobel (Gray scale and Sobel filter for Edge Detection) tt_um_Xgamer1999_LIF (Demonstration of Leaky integrate and Fire neuron SJSU) tt_um_dac12 (12 bit DAC) tt_um_voting_machine (Digital Voting Machine) tt_um_updown_counter (8bit_up-down_counter) tt_um_openram_top (Single Port OpenRAM Testchip) tt_um_customalu (Custom ALU) tt_um_assaify_mssf_pll (24 MHz MSSF PLL) tt_um_Maj_opamp (2-Stage OpAmp Design) tt_um_wokwi_442131619043064833 (Encoder 7 segments display) tt_um_wokwi_441835796137492481 (TESVG Binary Counter and shif register ) tt_um_combo_haz (Combinational Logic Based RISC-V Pipeline Hazard Resolver) tt_um_tx_fsm (Design and Functional Verification of Error-Correcting FIFO Buffer with SECDED and ARQ ) tt_um_will_keen_solitaire (solitaire) tt_um_rom_vga_screensaver (VGA Screensaver with embedded bitmap ROM) tt_um_13hihi31_tdc (Time to Digital Converter) tt_um_dteal_awg (Arbitrary Waveform Generator) tt_um_LIF_neuron (AFM_LIF) tt_um_rebelmike_register (Circulating register test) tt_um_MichaelBell_hs_mul (8b10b decoder and multiplier) tt_um_SNPU (random_latch) tt_um_rejunity_atari2600 (Atari 2600) tt_um_bit_serial_cpu_top (16-bit bit-serial CPU) tt_um_semaforo (semaforo) tt_um_bleeptrack_cc1 (Cross stitch Creatures #1) tt_um_bleeptrack_cc2 (Cross stitch Creatures #2) tt_um_bleeptrack_cc3 (Cross stitch Creatures #3) tt_um_bleeptrack_cc4 (Cross stitch Creatures #4) tt_um_bitty (Bitty) tt_um_spi2ws2811x16 (spi2ws2811x8) tt_um_uart_spi (UART and SPI Communication blocks with loopback) tt_um_urish_charge_pump (Dickson Charge Pump) tt_um_adc_dac_tern_alu (adc_dac_BCT_addr_ALU_STI) tt_um_sky1 (GD Sky Processor) tt_um_fifo (ASYNCHRONOUS FIFO) tt_um_TT16 (Asynchronous FIFO) tt_um_axi4lite_top (Axi4_Lite) tt_um_TT06_pwm (PWM Generator) tt_um_hack_cpu (HACK CPU) tt_um_marxkar_jtag (JTAG CONTROLLER) tt_um_cache_controller (Simple Cache Controller) tt_um_stopwatchtop (Stopwatch with 7-seg Display) tt_um_adpll (all-digital pll) tt_um_tnt_rom_test (TT09 SKY130 ROM Test) tt_um_tnt_rom_nolvt_test (TT09 SKY130 ROM Test (no LVT variant)) tt_um_wokwi_414120207283716097 (fulladder) tt_um_kianV_rv32ima_uLinux_SoC (KianV uLinux SoC) tt_um_tv_b_gone_rom (TV-B-Gone-EU) Available Available Available Available Available Available Available Available Available Available Available Available Available