____ _ __ __ ____ _ _
/ ___| _ __ __ _ _ __| | _| \/ |/ ___| | | |
\___ \| '_ \ / _` | '__| |/ / |\/| | | | | | |
___) | |_) | (_| | | | <| | | | |___| |_| |
|____/| .__/ \__,_|_| |_|\_\_| |_|\____|\___/
|_|
An open-source AVR-architecture 8-bit microcontroller clone designed for fabrication on SkyWater 130nm technology using the OpenLane ASIC flow.
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
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
- 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
| 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 |
- 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
| 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
# 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 the testbench
make sim
# View waveforms
make wave# From the OpenLane root directory
make mount
# Inside the Docker container
./flow.tcl -design SparkMCU/openlane/spark_mcu_top# 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| 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 |
Successfully completed full OpenLane flow (synthesis β signoff) with the following results:
| 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) |
| 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) |
| Check | Result |
|---|---|
| Magic DRC | β 0 errors |
| LVS (Netgen) | β Circuits match uniquely |
| Antenna Check | β Pass (with diode insertion strategy 4) |
# 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) 1Fixed two critical issues that prevented the OpenLane flow from completing:
-
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. -
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. -
CELL_PAD: 4 β 6 β Slightly increased cell padding for better detailed placement legalization.
This project is open-source hardware, released under the Apache 2.0 License.
- SkyWater PDK by Google/SkyWater
- OpenLane by Efabless
- AVR Architecture by Microchip/Atmel