Skip to content

Latest commit

Β 

History

17 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

============================================================================

SparkMCU - AVR-Compatible Microcontroller on SkyWater 130nm

============================================================================

  ____                   _    __  __  ____ _   _ 
 / ___| _ __   __ _ _ __| | _|  \/  |/ ___| | | |
 \___ \| '_ \ / _` | '__| |/ / |\/| | |   | | | |
  ___) | |_) | (_| | |  |   <| |  | | |___| |_| |
 |____/| .__/ \__,_|_|  |_|\_\_|  |_|\____|\___/ 
       |_|                                        

An open-source AVR-architecture 8-bit microcontroller clone designed for fabrication on SkyWater 130nm technology using the OpenLane ASIC flow.

πŸ—οΈ Architecture Overview

SparkMCU implements a subset of the ATmega328P instruction set architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      SparkMCU SoC                              β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                    AVR CPU Core                          β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚  β”‚  β”‚ Register β”‚  β”‚   ALU    β”‚  β”‚  Instruction Decoder  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  File    β”‚  β”‚  8-bit   β”‚  β”‚   (ATmega328P ISA)    β”‚  β”‚  β”‚
β”‚  β”‚  β”‚ 32x8-bit β”‚  β”‚          β”‚  β”‚                       β”‚  β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚  β”‚  β”‚   PC     β”‚  β”‚   SP     β”‚  β”‚   SREG (Flags)        β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  16-bit  β”‚  β”‚  16-bit  β”‚  β”‚ I T H S V N Z C      β”‚  β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                          β”‚                                      β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                         β”‚
β”‚              β”‚    Data Bus (8-bit)   β”‚                          β”‚
β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                         β”‚
β”‚                          β”‚                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ Flash  β”‚  β”‚  SRAM  β”‚  β”‚  β”‚  GPIO  β”‚  β”‚  Interrupt Ctrl β”‚   β”‚
β”‚  β”‚ 32KB*  β”‚  β”‚  2KB*  β”‚  β”‚  β”‚ B,C,D  β”‚  β”‚  INT0/1, PCINT  β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                          β”‚                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”                        β”‚
β”‚  β”‚  UART  β”‚  β”‚  SPI   β”‚  β”‚  β”‚Timer/  β”‚                        β”‚
β”‚  β”‚ USART0 β”‚  β”‚ Master β”‚  β”‚  β”‚Counter0β”‚                        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜                        β”‚
β”‚                          β”‚                                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                    Physical Pins

πŸ“ Project Structure

SparkMCU/
β”œβ”€β”€ rtl/                          # RTL source files
β”‚   β”œβ”€β”€ core/                     # CPU core
β”‚   β”‚   β”œβ”€β”€ spark_pkg.v           # Global defines & parameters
β”‚   β”‚   β”œβ”€β”€ spark_alu.v           # Arithmetic Logic Unit
β”‚   β”‚   β”œβ”€β”€ spark_regfile.v       # 32x8 Register File
β”‚   β”‚   β”œβ”€β”€ spark_decoder.v       # Instruction Decoder
β”‚   β”‚   └── spark_cpu.v           # CPU pipeline controller
β”‚   β”œβ”€β”€ memory/                   # Memory subsystem
β”‚   β”‚   β”œβ”€β”€ spark_pmem.v          # Program Memory (Flash ROM)
β”‚   β”‚   β”œβ”€β”€ spark_dmem.v          # Data Memory (SRAM)
β”‚   β”‚   └── spark_bus_ctrl.v      # Bus controller / memory mapper
β”‚   β”œβ”€β”€ peripherals/              # I/O peripherals
β”‚   β”‚   β”œβ”€β”€ spark_gpio.v          # GPIO Port (B, C, D)
β”‚   β”‚   β”œβ”€β”€ spark_uart.v          # UART (USART0)
β”‚   β”‚   β”œβ”€β”€ spark_spi.v           # SPI Master/Slave
β”‚   β”‚   β”œβ”€β”€ spark_timer0.v        # 8-bit Timer/Counter 0
β”‚   β”‚   └── spark_intctrl.v       # Interrupt Controller
β”‚   └── spark_mcu_top.v           # Top-level SoC integration
β”œβ”€β”€ testbench/
β”‚   └── spark_mcu_tb.v            # Comprehensive testbench
β”œβ”€β”€ firmware/                     # Sample AVR firmware
β”‚   β”œβ”€β”€ blink.S                   # Assembly LED blink
β”‚   └── uart_echo.c              # C UART echo program
β”œβ”€β”€ openlane/                     # OpenLane ASIC flow
β”‚   └── spark_mcu_top/
β”‚       β”œβ”€β”€ config.tcl            # OpenLane configuration (Tcl)
β”‚       β”œβ”€β”€ config.json           # OpenLane configuration (JSON)
β”‚       β”œβ”€β”€ pin_order.cfg         # Pin placement
β”‚       └── constraint.sdc        # Timing constraints
β”œβ”€β”€ Makefile                      # Build system
β”œβ”€β”€ .gitignore                    # Git ignore rules
└── README.md                     # This file

πŸ› οΈ Features

CPU Core

  • ISA: AVR (ATmega328P compatible subset)
  • Data width: 8-bit
  • Address space: 16-bit (64KB)
  • Pipeline: Multi-cycle (Fetch β†’ Decode β†’ Execute β†’ Memory β†’ Writeback)
  • Registers: 32 general-purpose 8-bit registers (R0-R31)
  • Pointer registers: X (R27:R26), Y (R29:R28), Z (R31:R30)
  • Stack: Hardware stack in SRAM, 16-bit stack pointer

Supported Instructions

Category Instructions
Arithmetic ADD, ADC, SUB, SBC, SUBI, SBCI, INC, DEC, NEG, MUL
Logic AND, ANDI, OR, ORI, EOR, COM
Compare CP, CPC, CPI, CPSE
Branch RJMP, RCALL, RET, RETI, JMP, CALL, IJMP, ICALL
Conditional BRBS, BRBC (BREQ, BRNE, BRCS, BRCC, etc.)
Data Transfer MOV, MOVW, LDI, LD, LDD, ST, STD, LDS, STS, LPM
Bit LSR, LSL, ASR, ROR, ROL, SWAP, BST, BLD
Stack PUSH, POP
I/O IN, OUT, SBI, CBI, SBIC, SBIS
Skip SBRC, SBRS, CPSE
SREG BSET, BCLR (SEC, CLC, SEI, CLI, etc.)
System NOP, SLEEP, WDR

Peripherals

  • GPIO: 3 ports (B: 8-bit, C: 6-bit, D: 8-bit) with pin change interrupts
  • UART: Full-duplex, configurable baud rate, 5-9 data bits, parity, interrupts
  • SPI: Master mode, configurable CPOL/CPHA, 4 prescaler settings
  • Timer0: 8-bit, Normal/CTC/Fast PWM/Phase-Correct PWM, 2 compare units
  • Interrupts: 21 vectors, priority-encoded, INT0/INT1 edge/level detect

Memory Map (ATmega328P Compatible)

Address Range Description
0x0000-0x001F Register File (R0-R31)
0x0020-0x005F I/O Registers (64 addresses)
0x0060-0x00FF Extended I/O Registers
0x0100-0x08FF SRAM window in architecture

* Current ASIC build configuration uses reduced memory for PnR convergence:

  • Program memory: 256 words (16-bit)
  • Data SRAM: 128 bytes

πŸš€ Getting Started

Prerequisites

# Simulation tools
sudo apt install iverilog gtkwave

# OpenLane (for ASIC flow)
git clone https://github.com/The-OpenROAD-Project/OpenLane.git
cd OpenLane
make
make pdk

# AVR toolchain (for firmware)
sudo apt install gcc-avr avr-libc

Run Simulation

# Run the testbench
make sim

# View waveforms
make wave

Run OpenLane ASIC Flow

# From the OpenLane root directory
make mount

# Inside the Docker container
./flow.tcl -design SparkMCU/openlane/spark_mcu_top

Compile Firmware

# Assembly
avr-as -mmcu=atmega328p -o firmware/blink.o firmware/blink.S
avr-ld -o firmware/blink.elf firmware/blink.o
avr-objcopy -O ihex firmware/blink.elf firmware/blink.hex

# C
avr-gcc -mmcu=atmega328p -Os -o firmware/uart_echo.elf firmware/uart_echo.c
avr-objcopy -O ihex firmware/uart_echo.elf firmware/uart_echo.hex

🎯 Target Technology

Parameter Value
Process SkyWater 130nm (sky130A)
Std Cell Library sky130_fd_sc_hd
Target Clock 16 MHz (62.5 ns period)
Supply Voltage 1.8V

πŸ“Š ASIC Implementation Results

Successfully completed full OpenLane flow (synthesis β†’ signoff) with the following results:

Floorplan & Placement

Metric Value
Die Area ~969 Β΅m Γ— 980 Β΅m (~0.95 mmΒ²)
Core Utilization 35.7%
Target Density 40%
Cell Count 29,548 standard cells
Tapcells 12,213 (FP_TAPCELL_DIST = 14)
Floorplan Sizing Relative (auto-computed from utilization)

Routing

Metric Value
Total Wirelength 1,658,260 Β΅m
Total Vias 273,811
Routing Congestion 29.70% overall usage, 0 overflow
DRT Violations 0 (converged at iteration 35)

Signoff

Check Result
Magic DRC βœ… 0 errors
LVS (Netgen) βœ… Circuits match uniquely
Antenna Check βœ… Pass (with diode insertion strategy 4)

Key OpenLane Configuration

# Floorplan β€” auto-sized from utilization target
set ::env(FP_SIZING) "relative"
set ::env(FP_CORE_UTIL) 35
set ::env(PL_TARGET_DENSITY) 0.40
set ::env(CELL_PAD) 6

# Tapcell β€” sky130 default spacing
set ::env(FP_TAPCELL_DIST) 14

# Clock
set ::env(CLOCK_PERIOD) "62.5"   ;# 16 MHz

# Routing
set ::env(ROUTING_CORES) 4
set ::env(GRT_ADJUSTMENT) 0.15
set ::env(GRT_ALLOW_CONGESTION) 1

πŸ”§ Changelog

2026-03-24 β€” Config Fixes for PnR Convergence

Fixed two critical issues that prevented the OpenLane flow from completing:

  1. FP_TAPCELL_DIST: 2 β†’ 14 β€” The original value of 2 Β΅m inserted 828,920 tapcells (vs 29,548 design cells), overwhelming the detailed placer. Changed to 14 Β΅m (sky130 default), reducing tapcells to 12,213.

  2. FP_SIZING: absolute β†’ relative β€” The hardcoded 3200Γ—3200 Β΅m die area resulted in only 4.44% utilization (vs 35% target). Switched to relative sizing so OpenLane auto-computes the die area from the utilization target, producing a properly-sized ~969Γ—980 Β΅m die.

  3. CELL_PAD: 4 β†’ 6 β€” Slightly increased cell padding for better detailed placement legalization.

πŸ“œ License

This project is open-source hardware, released under the Apache 2.0 License.

πŸ™ Acknowledgments

About

An open-source AVR-architecture 8-bit microcontroller clone designed for fabrication on SkyWater 130nm technology using the OpenLane ASIC flow.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages