How to simulate Apple Lisa CPU in FPGA using Verilog on Linux 2025
Recreating Vintage CPU Architecture in Modern FPGA Hardware
Retro computing enthusiasts and hardware engineers face a unique challenge: how do you study or preserve historical computer architectures like the Apple Lisa without access to the original hardware? The answer lies in FPGA (Field-Programmable Gate Array) simulation, which allows you to translate the original CPU design into synthesizable hardware description language code.
This guide walks you through the process of simulating the Apple Lisa CPU architecture in an FPGA environment on Linux, covering the Motorola 68000 processor that powered the Lisa system.
Understanding the Apple Lisa CPU Architecture
The Apple Lisa computer (1983) used a Motorola 68000 processor running at 5 MHz. This 16-bit/32-bit hybrid processor is an excellent candidate for FPGA recreation because:
- Well-documented instruction set
- Moderate complexity suitable for hobbyist FPGA boards
- Rich historical information available from original Apple documentation
- Existing open-source 68K implementations as reference
Before diving into implementation, understand the 68000's core components:
- ALU (Arithmetic Logic Unit): Handles basic arithmetic and logical operations
- Registers: 8 data registers (D0-D7) and 8 address registers (A0-A7)
- Bus Interface: 16-bit data bus, 24-bit address bus
- Control Unit: Microcode decoder for instruction execution
Prerequisites and Tools Setup on Linux
You'll need several tools installed before starting FPGA development:
# For Xilinx Vivado (most common for Lisa projects)
sudo apt-get install -y build-essential git python3 python3-pip
# Install Yosys for synthesis (open-source alternative)
sudo apt-get install -y yosys nextpnr-ice40
# For simulation and testing
sudo apt-get install -y verilator gtkwave
# Clone the OpenCores 68K implementation
git clone https://github.com/opencores/m68k.git
cd m68k
If you're using Vivado, download it from Xilinx's website (free WebPACK license available for hobbyists). For open-source workflows, Yosys and nextPNR provide a complete free toolchain.
Step-by-Step FPGA Implementation
1. Obtain or Create the Verilog RTL
Start with the OpenCores 68K implementation, which provides cycle-accurate RTL:
// Basic 68000 CPU wrapper for FPGA
module m68k_cpu (
input clk,
input reset,
output [23:0] address_bus,
inout [15:0] data_bus,
output reg as_n, // Address Strobe
output reg uds_n, // Upper Data Strobe
output reg lds_n, // Lower Data Strobe
output reg rw_n, // Read/Write
input dtack_n // Data Transfer Acknowledge
);
// Internal registers and state machine
reg [31:0] pc; // Program Counter
reg [31:0] sp; // Stack Pointer (A7)
reg [31:0] d_regs [7:0]; // Data registers
reg [31:0] a_regs [7:0]; // Address registers
reg [15:0] sr; // Status Register
always @(posedge clk) begin
if (reset) begin
pc <= 32'h0;
sp <= 32'h0;
sr <= 16'h2700; // Supervisor mode
end
end
endmodule
2. Configure Your FPGA Development Board
Common boards for this project:
| Board | FPGA Family | Price | Best For | |-------|------------|-------|----------| | DE0-CV | Cyclone V | $50 | Beginners, Altera tools | | IceStick | iCE40 | $25 | Open-source toolchains | | Arty A7 | Artix-7 | $100 | Professional projects | | Ulx3s | ECP5 | $80 | High complexity |
For Linux users, the IceStick + open-source flow is recommended due to eliminating vendor tool licensing complexity.
3. Create Test Benches in SystemVerilog
Before synthesis, verify your CPU behavior with simulation:
// test_m68k.sv - Testbench for 68K CPU
module test_m68k();
reg clk, reset;
wire [23:0] address_bus;
wire [15:0] data_bus;
wire as_n, uds_n, lds_n, rw_n;
reg dtack_n;
m68k_cpu cpu_inst (
.clk(clk),
.reset(reset),
.address_bus(address_bus),
.data_bus(data_bus),
.as_n(as_n),
.uds_n(uds_n),
.lds_n(lds_n),
.rw_n(rw_n),
.dtack_n(dtack_n)
);
initial begin
clk = 0;
reset = 1;
dtack_n = 1;
#100 reset = 0;
#1000 $finish;
end
always #10 clk = ~clk; // 50MHz clock
initial begin
$dumpfile("cpu_sim.vcd");
$dumpvars(0, test_m68k);
end
endmodule
Run simulation with Verilator:
verilator --trace -cc test_m68k.sv m68k_cpu.v --exe sim_main.cpp
make -j -C obj_dir -f Vm68k_cpu.mk Vm68k_cpu
obj_dir/Vm68k_cpu
gtkwave cpu_sim.vcd
4. Synthesis and Place-and-Route
For Yosys workflow:
# Synthesis
yosys -p "read_verilog m68k_cpu.v; synth_ice40 -top m68k_cpu -json design.json"
# Place and route
nextpnr-ice40 --json design.json --asc design.asc --freq 5
# Generate bitstream
icepack design.asc design.bin
# Program FPGA
iceprog design.bin
5. Validation and Debugging
Create a simple ROM with Lisa-compatible boot code:
module boot_rom (
input [23:0] address,
output reg [15:0] data,
input oe_n
);
reg [15:0] rom [0:16383]; // 32KB boot ROM
initial begin
$readmemh("lisa_boot.hex", rom);
end
always @(*) begin
if (!oe_n && address < 24'h4000)
data = rom[address[14:1]];
else
data = 16'hZZZZ;
end
endmodule
Common Pitfalls When Simulating 68K in FPGA
Clock Timing Issues: The 68000 has strict timing requirements. Use generated clocks from PLL modules rather than direct clock divisions.
Memory Arbitration: Implement proper DTACK (Data Transfer Acknowledge) signaling. Delays in this signal cause CPU stalls.
Instruction Decoding Complexity: The 68000's variable-length instructions (2-10 bytes) require careful state machine design. Use existing decoders as reference.
Performance Expectations
On modern FPGA boards, you can typically achieve:
- Original Speed: 5 MHz (historically accurate)
- Overclocked: 50+ MHz with optimizations
- Synthesis Time: 10-30 minutes on Linux
Next Steps
Once your basic CPU core works:
- Add MMU (Memory Management Unit) support for OS functionality
- Implement Motorola 68901 (MFP) chipset for interrupts
- Connect display controller for framebuffer output
- Load actual Lisa operating system ROM images
This approach lets you preserve computing history while learning modern hardware design practices.
Recommended Tools
- DigitalOceanCloud hosting built for developers — $200 free credit for new users
- GitHubWhere the world builds software