A 12-bit Successive Approximation Register (SAR) Analog-to-Digital Converter IP block configured for the sky130 process node.
Integrates the ChipFoundry sky130_ef_ip__adc3v_12bit analog macro with a custom digital SAR controller (sar_ctrl.v) and a Wishbone bus wrapper (adc_wb_wrapper.v) for easy integration into SoC projects such as Caravel. No complex custom analog driver development is required — the IP includes its own resistor divider and follower buffer amplifier for voltage reference and common-mode buffering.
Two ways to use it inside a user project wrapper:
- Direct LA/GPIO Control (
ADC_TOP) — control the ADC pins manually via Logic Analyzer (LA) signals or GPIOs. - Wishbone Bus Interface (
adc_wb_wrapper) — map the ADC's control, config, status, and output data directly to CPU-accessible Wishbone registers.
Comes with a comprehensive Python/ngspice/iverilog verification and characterization suite, behavioral analog simulation models, and layout physical files (GDS, LEF, Netlists).
Apache-2.0.
- What it does
- Register map
- Repository layout
- Integration
- Parameters & port reference
- Physical design & layout
- Simulation & characterization
- Common pitfalls
- Reference design
- License
The ADC block is a 12-bit Successive Approximation Register (SAR) Analog-to-Digital Converter. It combines:
- res_div: A passive resistor ladder providing the internal reference and common-mode voltages.
- follower_amp: An active follower amplifier providing a low-impedance buffer for the reference/common-mode voltages to prevent transient droop.
- sky130_ef_ip__adc3v_12bit: ChipFoundry's analog macro containing the capacitive DAC array and analog comparator.
- sar_ctrl: Successive Approximation Register (SAR) digital controller that implements the binary search algorithm.
- adc_wb_wrapper: A Wishbone slave bus wrapper interfacing the ADC to the SoC bus.
Behaviour during a conversion:
- Idle: The ADC remains in
IDLEstate. - Start: A rising edge on the Start of Conversion (
soc) pin/bit triggers the conversion cycle. - Sample & Reset: The controller enters
SAMPLEandRSTstates, sampling the input voltageadc_inon the capacitor array forswidthclock cycles. - Conversion: The controller performs binary search iterations over 12 clock cycles (
CONVstate) based on the output of the analog comparator. - Done: Upon finishing, the controller assets End of Conversion (
eoc) high and outputs the stable 12-bit digital code on thedatabus.
The analog macro uses a trim divisor of 4069 rather than the traditional 4096. As a result, codes 4069–4095 are unreachable by design. This scaling is compensated for in the characterization and conversion calculations:
For Wishbone bus integration, the registers are mapped to offsets of the block's base address:
| Name | Offset | Width | Type | Description |
|---|---|---|---|---|
CTRL_REG |
16'h0000 |
32 | R/W | Control Register: - [0]: soc (Start of Conversion)- [1]: adc_en (ADC Enable)- [2]: ena_follower_amp (Enable Follower Amp) |
STATUS_REG |
16'h0004 |
32 | R | Status Register: - [1]: eoc (End of Conversion)- [31:2] & [0]: Reserved |
DATA_REG |
16'h0008 |
32 | R | Data Register: - [11:0]: adc_data (12-bit output code) |
CONFIG_REG |
16'h000C |
32 | R/W | Configuration Register: - [3:0]: swidth (Sample width in clock cycles, default 4'h4) |
adc_ip/
gds/
ADC_TOP.gds # GDSII physical layout (res_div, follower_amp, and analog macro)
lef/
ADC_TOP.lef # LEF macro definition (physical boundary, pin locations)
pnl/
ADC_TOP.pnl.v # Post-netlist structural netlist for physical synthesis
rtl/
ADC_TOP.pnl.v # RTL-level schematic netlist for simulation/synthesis
ADC_TOP_blackbox.v # Blackbox port definition of the top-level macro
adc_analog_stubs.v # Behavioral analog stubs for fast simulation
adc_sim_stubs.v # Stub models for res_div and follower_amp
adc_wb_wrapper.v # Wishbone bus interface wrapper
sar_ctrl.v # Successive Approximation Register (SAR) digital controller
sky130_ef_ip__adc3v_12bit.v # Behavioral model of the ChipFoundry 12-bit ADC macro
The simplest physical integration. Wire it directly to Logic Analyzer (LA) signals and/or GPIO pins in your wrapper. Pad mode is configured directly.
ADC_TOP i_adc_top (
`ifdef USE_POWER_PINS
.DVPWR (vccd1),
.DVGND (vssd1),
.AVPWR (vdda1),
.AVGND (vssa1),
`endif
.ena_follower_amp (la_data_in[0]),
.ena_adc (la_data_in[1]),
.adc_reset (la_data_in[2]),
.adc_hold (la_data_in[3]),
.adc_dac_val (la_data_in[15:4]),
.adc_cmp (la_data_out[0]),
.adc_in (analog_io[16])
);Recommended for SoC designs. Access and control the ADC directly using CPU register reads and writes.
adc_wb_wrapper u_adc_wb (
`ifdef USE_POWER_PINS
.VPWR (vccd1),
.VGND (vssd1),
.AVPWR (vdda1),
.AVGND (vssa1),
`endif
.clk_i (wb_clk_i),
.rst_i (wb_rst_i),
.adr_i (wbs_adr_i),
.dat_i (wbs_dat_i),
.dat_o (wbs_dat_o),
.sel_i (wbs_sel_i),
.cyc_i (wbs_cyc_i),
.stb_i (wbs_stb_i),
.ack_o (wbs_ack_o),
.we_i (wbs_we_i),
.adc_in (analog_io[16])
);| Signal | Dir | Width | Description |
|---|---|---|---|
clk_i |
in | 1 | Wishbone Clock |
rst_i |
in | 1 | Wishbone Reset (Active High) |
adr_i |
in | 32 | Wishbone Address Bus |
dat_i |
in | 32 | Wishbone Data Input Bus |
dat_o |
out | 32 | Wishbone Data Output Bus |
sel_i |
in | 4 | Wishbone Byte Select |
cyc_i |
in | 1 | Wishbone Cycle |
stb_i |
in | 1 | Wishbone Strobe |
ack_o |
out | 1 | Wishbone Acknowledge |
we_i |
in | 1 | Wishbone Write Enable |
adc_in |
in | 1 | Analog Input signal pin |
| Parameter / Signal | Dir | Width / Default | Description |
|---|---|---|---|
SIZE |
- | 8 (override to 12) |
Bit resolution of the SAR controller |
clk |
in | 1 | Reference Clock |
rst_n |
in | 1 | Active-low Reset |
soc |
in | 1 | Start of Conversion (Active High pulse) |
cmp |
in | 1 | Analog comparator feedback input |
en |
in | 1 | Controller Enable |
swidth |
in | 4 | Sample time width in clock cycles |
sample_n |
out | 1 | Active-low sample control (Hold = ~sample_n) |
data |
out | SIZE |
Completed conversion parallel data output |
eoc |
out | 1 | End of Conversion flag |
dac_rst |
out | 1 | Reset signal for the analog DAC array |
| Signal | Dir | Width | Description |
|---|---|---|---|
AVPWR |
inout | 1 | Analog 3.3V Power Supply |
AVGND |
inout | 1 | Analog Ground |
DVPWR |
inout | 1 | Digital 1.8V Power Supply |
DVGND |
inout | 1 | Digital Ground |
adc_in |
in | 1 | Analog Input to converter |
ena_follower_amp |
in | 1 | Enable the internal reference buffer |
ena_adc |
in | 1 | Enable the analog macro |
adc_reset |
in | 1 | Reset analog macro |
adc_hold |
in | 1 | Hold input signal (from SAR controller) |
adc_dac_val |
in | 12 | Digital-to-Analog input values |
adc_cmp |
out | 1 | Analog comparator result output |
The macro layout is hard-macro verified for sky130:
- GDSII (
gds/ADC_TOP.gds): Hardened analog block containing matched resistor ladder array layout (res_div), unity-gain follower amplifier (follower_amp), and ChipFoundry analog core. - LEF (
lef/ADC_TOP.lef): Physical abstract detailing block boundary, routing obstruction grids, and pins (matching PDK specifications). - PNL (
pnl/ADC_TOP.pnl.v&rtl/ADC_TOP.pnl.v): Physical Netlist. - Contact Shift: Layout updates include a contact shift of
Y=+0.8µm(layout-extracted verified) to optimize routing path impedance. This results in 9.3% lower parasitic routing capacitance than the reference layout, improving settling time under corner variations.
The reference integration of this ADC block within the Caravel architecture is detailed in CF_ADC_Integration.
Licensed under the Apache License, Version 2.0 (the "License"). You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.