
Sleepy Chip is a dual-mode digital audio synthesizer featuring a 3-waveform oscillator with streaming capability and delta-sigma DAC output. It provides both traditional synthesis (oscillator + waveform mixing) and direct sample streaming in a compact 1x1 Tiny Tapeout tile.
SPI Interface 24-bit Phase Waveform Mode
(3 pins) Accumulator Generators Selection
(DDS core)
uio[0]: MOSI ┌─→ ┌──────────┐ ┌──────────┐ ┌──────┐
uio[1]: SCK │ │ Frequency│─────────→│ Square │────┐ │ │
uio[2]: CS │ │ Register │ │ Sawtooth │ ├───→│ MUX │
│ │ │ │ Triangle │ │ │ │
┌──────────┴──┐ │ 24-bit │ └──────────┘ │ │ OSC/ │
│ SPI RX │ │ 50 MHz │ │ │STREAM│─┐
│ Registers │ └──────────┘ ┌──────────┐ │ │ │ │
│ (8 regs) │ │ Mixer │────┘ └──────┘ │
└─────────────┘ │ (3-ch) │ │
│ └──────────┘ │
│ │
│ Streaming Sample │
│ Register (0x10) ──────────────────────────────────────────────┘
│ │
│ ┌──────────┐ ┌────────────┐ │
│ Volume Register │ Volume │ │ Delta- │ │
└───────────────────────────────→│ Control │◄───│ Sigma DAC │◄┘
│ 8-level │ │ (1-bit) │
└──────────┘ └─────┬──────┘
│
▼
uo_out[0]
(Audio Output)
Dual Operating Modes:
Oscillator Mode - Traditional synthesis with 3 waveforms:
Streaming Mode - Direct sample playback:
Common Features:
| Address | Name | Bits | Description |
|---|---|---|---|
| 0x00 | Control | [0]: OSC_EN<br>[1]: STREAM_MODE<br>[2]: SW_GATE<br>[3]: SQUARE_EN<br>[4]: SAW_EN<br>[5]: TRI_EN | Oscillator enable, mode selection, waveform enables |
| 0x02 | Freq Low | [7:0] | Frequency control word low byte |
| 0x03 | Freq Mid | [7:0] | Frequency control word middle byte |
| 0x04 | Freq High | [7:0] | Frequency control word high byte (24-bit total) |
| 0x05 | Duty Cycle | [7:0] | Square wave PWM duty cycle (0x00=0%, 0xFF=100%) |
| 0x06 | Volume | [7:5] | Volume level (8 discrete levels, bit-shift based) |
| 0x10 | Stream Sample | [7:0] | Streaming mode sample value (0x00-0xFF) |
| 0x12 | Status | [0]: GATE<br>[1]: OSC_RUN | Read-only status register |
Phase Accumulator:
Volume Control:
Delta-Sigma DAC:
Resource Usage:
ui_in[7:0])| Pin | Name | Function | Description |
|---|---|---|---|
ui_in[0] |
GATE | Gate Input | Hardware gate trigger (OR'd with software gate) |
ui_in[1] |
HW_RST | Reset | Hardware reset (active high, AND'd with rst_n) |
ui_in[7:2] |
- | Reserved | Unused (future expansion) |
uo_out[7:0])| Pin | Name | Function | Description |
|---|---|---|---|
uo_out[0] |
DAC_OUT | Audio | 1-bit delta-sigma audio output |
uo_out[1] |
GATE_LED | Status | Gate status indicator (HW gate OR SW gate) |
uo_out[2] |
OSC_RUN | Status | Oscillator running indicator |
uo_out[3] |
SYNC | Debug | Sync pulse (phase MSB, frequency/waveform visualization) |
uo_out[7:4] |
- | Reserved | Unused (future expansion) |
uio[7:0])| Pin | Name | Function | Description |
|---|---|---|---|
uio[0] |
MOSI | SPI Data | SPI Master Out Slave In (data from controller) |
uio[1] |
SCK | SPI Clock | SPI clock input from controller |
uio[2] |
CS | SPI Select | SPI chip select (active low) |
uio[7:3] |
- | Reserved | Unused (future expansion) |
Note: All bidirectional pins are configured as inputs (SPI is RX-only, no MISO output to save area).
uio[0] - MOSIuio[1] - SCKuio[2] - CS (active low)uo_out[0] (DAC_OUT) to RC low-pass filter# SPI write function: write_register(address, data)
# 1. Enable oscillator with sawtooth waveform
write_register(0x00, 0b00010001) # OSC_EN=1, STREAM=0, SAW_EN=1
# 2. Set frequency to 440 Hz (A4 note)
write_register(0x02, 0x00) # Freq low
write_register(0x03, 0x40) # Freq mid
write_register(0x04, 0x02) # Freq high = 0x024000
# 3. Set volume to full
write_register(0x06, 0xFF)
# Result: Clean 440 Hz sawtooth wave on audio output
# 1. Switch to streaming mode
write_register(0x00, 0b00000010) # OSC_EN=0, STREAM_MODE=1
# 2. Stream different sample values
for sample in [0x00, 0x40, 0x80, 0xC0, 0xFF]:
write_register(0x10, sample)
time.sleep(0.001) # 1ms per sample = 1 kHz sample rate
# 3. Set volume
write_register(0x06, 0x80) # 50% volume
# Result: Direct sample playback at your chosen rate
Oscillator Mode:
Streaming Mode:
Test all 8 volume levels:
volumes = [0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF]
names = ["Mute", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "Full"]
for vol, name in zip(volumes, names):
write_register(0x06, vol)
print(f"Volume: {name}")
time.sleep(0.5)
RC Low-Pass Filter (required):
DAC_OUT (uo_out[0]) ──┬─── 10kΩ ───┬─── to audio amp
│ │
GND 680pF
│
GND
Audio Amplifier (recommended):
SPI Controller (required):
Alternative cutoff frequencies:
┌──────────────┐
│ Arduino/ │ MOSI ──→ uio[0]
│ Raspberry Pi │ SCK ──→ uio[1]
│ (SPI Master) │ CS ──→ uio[2]
└──────────────┘
┌──────────────┐
│ Sleepy Chip │ uo[0] ──→ RC Filter ──→ LM386 ──→ Speaker
│ (TT09) │ uo[1] ──→ GATE LED
│ │ uo[2] ──→ OSC LED
└──────────────┘
All modules validated with comprehensive testbenches:
Mode: SPI Mode 0 (CPOL=0, CPHA=0) Speed: Up to ~1 MHz SCK Format: 2-byte transactions: [address][data]
Basic Write:
Burst Write (auto-increment):
To calculate frequency word for a desired frequency:
freq_word = (desired_freq_Hz * 2^24) / 50_MHz
Examples:
src/ directorytest/ directory| # | Input | Output | Bidirectional |
|---|---|---|---|
| 0 | GATE | DAC_OUT | SPI_MOSI |
| 1 | HW_RST | GATE_LED | SPI_SCK |
| 2 | OSC_RUN | SPI_CS | |
| 3 | SYNC | ||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 |