584 Tiny PLL

584 : Tiny PLL

Design render
  • Author: LegumeEmittingDiode
  • Description: 4-channel fractional-N frequency synthesizer
  • GitHub repository
  • Clock: 10000000 Hz

How it works

Overview

This project showcases tiny_pll, a completely self-contained fractional-N frequency synthesizer using less than 6% of the area of a 1x1 TinyTapeout tile. The design goals of this project were as follows:

  1. The design should be as simple as possible to reduce the chance of failure.
  2. The design should be as small as possible so it can be incorporated into future Tiny Tapeout designs with minimal area overhead.

There are 4 tiny_pll instances in this project. Each instance multiplies the frequency of a reference clock by a rational number A/B, where A and B can be between 1 and 15. Such a block has two main use cases:

  1. Generating several internal clocks from a single off-chip oscillator (e.g., for a large digital design with multiple clock domains)
  2. Generating one or more internal clocks at a higher frequency than what can be provided to the tile through the mux and GPIO pins

tiny_pll is designed for a 10 MHz reference input, which implies an output frequency between 67 kHz and 150 MHz. The 4 output clocks are connected to the GPIO pins uo[3:0]. In reality, the maximum output frequency is limited by 4 factors:

  1. The speed of the Caravel I/O cells, which itself is a factor of the off-chip load capacitance
  2. The routing between the TT mux and the I/O cells
  3. The speed of the TT mux
  4. The routing between the project tile and the TT mux The minimum output frequency is limited to roughly 1 MHz due to the minimum speed of the VCO.

A 1-bit delta-sigma ADC is included to allow measurement of the analog control voltage on uo[4].

This design is inherently mixed-signal due to the analog nature of the PLL. Consequently, the top-level layout is implemented as a custom analog/digital section for the PLL and ADC, surrounded by RTL which implements the control/status registers (CSRs) and various clock buffering and multiplexing functions. Schematics were created using xschem and simulated with ngspice; custom layout was done using klayout with the Efabless sky130 PDK; digital synthesis and PnR was done using a custom OpenROAD flow; and magic and netgen were used for LVS, DRC and parasitic extraction.

PLL

The top-level schematic of tiny_pll is shown below: PLL schematic

The PLL uses a standard fractional-N architecture, where an input and output frequency divider are used to set the frequency multiplication with respect to the reference clock input. The output frequency is A/B * f_ref, where A is the division ratio of XDIV_FB, B is the division ratio of XDIV_OUT and f_ref is the input clock frequency. Documentation for the PLL subcells is included below.

Throughout the schematics, the pins VPB and VNB are included to connect the bulk terminals of all PMOS and NMOS devices, respectively. This is done to ensure the corresponding terminals of the standard cell instances at each level of hierarchy are propagated to the top level and connected to VPWR and VGND.

Divider

Divider schematic

Frequency dividers are implemented using a 4-bit binary counter followed by 4 XOR gates to check for equality with a division ratio input lmt[3..0]. When the counter output is equal to lmt, div_rstb is immediately asserted, which resets the counter to 0 at the rising edge of clk_in. As a result, the maximum division ratio from clk_in to eq is 15, when lmt == 4'b1111.

Since the counter is reset as soon as its output is equal to the division ratio, a very short pulse is produced at the eq node, with a duration equal to the propagation delay of the counter. This could potentially be a timing concern for XDF, but since the counter delay is at least 3 gate delays, the flip-flop was observed to operate as intended across process, voltage and temperature (PVT) in simulation.

The D flip-flop (DFF) at the output is included to ensure an output duty cycle close to 50%. As a result, the actual output frequency is f_ref / (2*lmt), which implies a division ratio from clk_in to clk_out between 2 and 30.

The tie cell sky130_fd_sc_hd__conb_1 is used when gates must be connected to VPWR or VGND to avoid potential ESD issues.

Phase-frequency detector (PFD)

PFD schematic

The PFD is composed of two DFFs, clocked by the divided VCO output and the reference input, respectively. Since the input of both DFFs is tied to 1, each DFF can be implemented using two S-R latches, each of which uses two nor2 gates. The full PFD thus uses 8 nor2 gates, one nand2 and one inv_1, which is considerably smaller than using discrete DFF standard cells with the D inputs tied to VPWR.

A NAND followed by an inverter is used instead of a single AND to slightly increase the minimum output pulse width and avoid charge pump glitches.

Charge pump

Charge pump schematic

The charge pump uses two current sources (MNSRC and MPSRC), which can be interchangeably switched to the output with the up and down inputs. The charge pump current is nominally 1 uA and is set by the bias generator. The switches use nearly minimum width to reduce area, and minimum length to reduce capacitance. The PMOS switch uses 2x the W/L of the NMOS switch to ensure roughly equal drain-source saturation voltages (VDSAT).

Loop filter

Loop filter schematic

The loop filter is implemented using a series R/C combination to compensate the loop transfer function such that a zero is placed below the crossover frequency to ensure stability, and a pole is placed above the crossover frequency to ensure fast settling time. A second capacitor XC2 is included to reduce ripple in the control voltage, which in turn reduces phase noise at the PLL output. Component values were selected using a linearized model developed using schematic-only simulations of the VCO to determine the voltage-to-frequency gain. The loop bandwidth was chosen to be on the order of 100 kHz, with a phase margin of 65 degrees at an output frequency of 10 MHz. The resulting R/C values are R = 100 kOhm and C1 = 1 pF.

In reality, the loop characteristics vary significantly across output frequency due to the nonlinear gain of the VCO, which was observed to have a nearly exponential voltage-to-frequency characteristic in simulation. This is likely due to the VCO current sources operating in the subthreshold region, where the ID/VGS characteristic is near-exponential.

The loop filter resistor is implemented using the urpm high-resistance poly implant, which is roughly 2 kOhm/square. While e-test values are not provided for this resistor in sky130, the value is not critical, and significant variations (+/-50%) were observed to result in a stable loop in simulation.

The loop filter capacitors are implemented using NMOS devices with drain and source shorted to VGND. This is due to the significantly higher capacitance density of MOS devices relative to MIM capacitors (~8 vs ~2 fF/um^2). The MOS capacitance is highly nonlinear and increases at high control voltages due to the inversion charge, but again the capacitor value is not critical and this nonlinearity does not cause instability in the feedback loop.

The loop filter consumes nearly 50% of the area of the PLL. Various methods were explored to reduce loop filter area, including:

  1. MIM capacitors could be used and placed on top of the other circuit blocks to reduce area
  2. A capacitance multiplier could be used to allow a smaller intrinsic capacitance

The MIM capacitor method is possible, but there is some ambiguity in the sky130 design rules as to whether a MIM capacitor can be placed over met1 and the base layers (see capm.10 in the sky130 periphery rules. Additionally, this could result in unwanted noise from the digital blocks coupling into the capacitors, which could degrade phase noise performance. Further, the capacitors would have to be divided up to lie between the power rails on met4 which would increase their area.

A capacitance multiplier was implemented using a 100 fF capacitor with a 10:1 multiplication ratio, but the final layout was the same size as the MOS capacitor implementation and was thus exlcuded from the final design. The capacitance multiplier was additionally seen to have poor high-frequency response compared to a MOS or MIM capacitor, which resulted in unacceptably high control voltage ripple.

Voltage-controlled oscillator (VCO)

VCO schematic

The VCO is a 3-stage current-starved ring oscillator using standard cell inverters. The current sources are minimum-length to maximize W/L, which in turn minimizes VDSAT, and minimize capacitance. The output resistance of these current sources is irrelevant since it only matters that the oscillator current is limited, and not the particular limit value. A triode device MNCTL is used to control the source/sink current of the VCO. LVT NMOS devices are used to ensure the operating control voltage is somewhere near half supply at an output frequency of 10 MHz, which helps ensure the maximum output frequency can be met across process variations. Four "keeper" devices (MNEN1, MNEN2, MNEN3 and MPEN) are included to disable the circuit with zero static power consumption.

Bias generator

Bias generator schematic

The bias generator is a self-biased current mirror, which provides a roughly supply-independent current for the charge pump. The exact current is highly dependent on the poly resistor XRES, but is designed to be nominally 1 uA at 25 degrees C. A startup circuit is included to ensure the bias generator does not fall into an undesirable operating point where IOUT = 0. The diode devices MPSU1 and MPSU2 charge the kick node to VPWR when the circuit is enabled, which pulls bias_p low and establishes a current in the mirror devices. Once the mirror is active, MNSU1 pulls kick low and disables the startup circuit. Multiple "keeper" devices are included to disable the circuit with zero static power consumption.

IO

#InputOutputBidirectional
0csr_data_in[0]: Data input for PLL control registersclk_out[0]: Channel 0 PLL clock outputclk_csr: Clock input for PLL control registers
1csr_data_in[1]: Data input for PLL control registersclk_out[1]: Channel 1 PLL clock output
2csr_data_in[2]: Data input for PLL control registersclk_out[2]: Channel 2 PLL clock output
3csr_data_in[3]: Data input for PLL control registersclk_out[3]: Channel 3 PLL clock output
4csr_addr_in[0]: Address input for PLL control registersadc_out: Channel 0 control voltage ADC output
5csr_addr_in[1]: Address input for PLL control registers
6csr_addr_in[2]: Address input for PLL control registers
7csr_addr_in[3]: Address input for PLL control registers

Chip location

Controller Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Analog Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Analog Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux tt_um_chip_rom (Chip ROM) tt_um_factory_test (TinyTapeout 8 Factory Test) tt_um_oscillating_bones (Oscillating Bones) tt_um_urish_charge_pump (Dickson Charge Pump) tt_um_bgr_agolmanesh (Bandgap Reference) tt_um_tnt_diff_rx (TT08 Differential Receiver test) tt_um_rejunity_vga_logo (VGA Tiny Logo (1 tile)) tt_um_tommythorn_maxbw (Asynchronous Multiplier) tt_um_mattvenn_r2r_dac_3v3 (Analog 8 bit 3.3v R2R DAC) tt_um_urish_simon (Simon Says memory game) tt_um_rebeccargb_universal_decoder (Universal Binary to Segment Decoder) tt_um_mattvenn_rgb_mixer (RGB Mixer demo5) tt_um_rebeccargb_hardware_utf8 (Hardware UTF Encoder/Decoder) tt_um_find_the_damn_issue (Find The Damn Issue) tt_um_brandonramos_VGA_Pong_with_NES_Controllers (VGA Pong with NES Controllers) tt_um_kb2ghz_xalu (4-bit minicomputer ALU) tt_um_rebeccargb_intercal_alu (INTERCAL ALU) tt_um_a1k0n_demo (Demo by a1k0n) tt_um_rburt16_bias_generator (Bias Generator) tt_um_zec_square1 ("SQUARE-1": VGA/audio demo) tt_um_jmack2201 (Sprite Bouncer with Looping Background Options) tt_um_ran_DanielZhu (Dice) tt_um_gfg_development_tinymandelbrot (TinyMandelbrot) tt_um_LnL_SoC (Lab and Lectures SoC) tt_um_htfab_pi_snake (Pi Snake) tt_um_tt08_aicd_playground (AICD Playground) tt_um_toivoh_demo (Sequential Shadows [TT08 demo competition]) tt_um_quarren42_demoscene_top (asic design is my passion) tt_um_crispy_vga (Crispy VGA) tt_um_MichaelBell_canon (TT08 Pachelbel's Canon demo) tt_um_shuangyu_top (Calculator) tt_um_wokwi_407306064811090945 (DDR throughput and flop aperature test) tt_um_08_sws (Sine Wave Synthesizer) tt_um_favoritohjs_scroller (VGA Scroller) tt_um_tt08_wirecube (Wirecube) tt_um_vga_glyph_mode (Glyph Mode) tt_um_a1k0n_vgadonut (VGA donut) tt_um_roy1707018 (RO) tt_um_analog_factory_test (TT08 Analog Factory Test) tt_um_sign_addsub (CMOS design of 4-bit Signed Adder Subtractor) tt_um_tinytapeout_logo_screensaver (VGA Screensaver with Tiny Tapeout Logo) tt_um_patater_demokit (Patater Demo Kit Waggling Rainbow on a Chip) tt_um_algofoogle_tt08_vga_fun (TT08 VGA FUN!) tt_um_simon_cipher (simon_cipher) tt_um_thexeno_rgbw_controller (Color Controller) tt_um_demosiine_sda (DemoSiine) tt_um_bytex64_munch (Munch) tt_um_alexjaeger_ringoscillator (5MHz Ring Oscillator) tt_um_cfib_demo (cfib Demoscene Entry) tt_um_wokwi_407852791999030273 (Simple 8 Bit ALU) tt_um_Richard28277 (4-bit ALU) tt_um_betz_morse_keyer (Morse Code Keyer) tt_um_nvious_graphics (nVious Graphics) tt_um_tiny_pll (Tiny PLL) tt_um_ezchips_calc (8-Bit Calculator) tt_um_hack_cpu (HACK CPU) tt_um_noritsuna_Vctrl_LC_oscillator (Voltage Controlled LC-Oscillator) tt_um_ring_divider (Divided Ring Oscillator) tt_um_2048_vga_game (2048 sliding tile puzzle game (VGA)) tt_um_morningjava_r2r_from_matt (Bucket Brigade) tt_um_ephrenm_tsal (TSAL_TT) tt_um_kapilan_alarm (Alarm Clock) tt_um_stochastic_addmultiply_CL123abc (Stochastic Multiplier, Adder and Self-Multiplier) tt_um_wokwi_407760296956596225 (tt08-octal-alu) tt_um_dlfloatmac (DL float MAC) tt_um_wakki_0123_Raw_Transistors (Raw_Transistors) tt_um_faramire_rotary_ring_wrapper (Rotary Encoder WS2812B Control) tt_um_devstdin_LDO_OSC (LDO BG IREF OSC) tt_um_frequency_counter (Frequency Counter SSD1306 OLED) tt_um_rom_test (TT08 SKY130 ROM 'YOLO' Test) tt_um_i2c_peripheral_stevej (i2c peripherals: leading zero count and fnv-1a hash) tt_um_yuri_panchul_schoolriscv_cpu_with_fibonacci_program (schoolRISCV CPU with Fibonacci program) tt_um_yuri_panchul_adder_with_flow_control (Adder with Flow Control) tt_um_brailliance (Brailliance) tt_um_nyan (nyan) tt_um_MichaelBell_mandelbrot (VGA Mandelbrot) tt_um_ssp_opamp (2-stage Opamp Designs) tt_um_fountaincoder_top_ad (pulse_add) tt_um_edwintorok (Rounding error) tt_um_mac (MAC) tt_um_dpmu (DPMU) tt_um_JAC_EE_segdecode (7 Segment Decode) tt_um_wokwi_408118380088342529 (Traffic-light-sequence) tt_um_shiftreg_test (TT08 SKY130 Shift Register 'YOLO' Test) tt_um_yuri_panchul_sea_battle_vga_game (Sea Battle) tt_um_benpayne_ps2_decoder (PS2 Decoder) tt_um_meriac_play_tune (Super Mario Tune on A Piezo Speaker) tt_um_comm_ic_bhavuk (Comm_IC) tt_um_daosvik_aesinvsbox (AES Inverse S-box) tt_um_wokwi_408216451206371329 (Logic Test) tt_um_micro_tiles_container (Micro tile container) tt_um_cattuto_sr_latch (TT08 - experiments with latch-based shift registers) tt_um_rejunity_vga_test01 (VGA Drop (audio/visual demo)) tt_um_silice (Warp) tt_um_wokwi_408231820749720577 (Abacus Lock) tt_um_jayjaywong12 (mulmul) tt_um_emmyxu_obstacle_detection (Obstacle Detection) tt_um_neural_navigators (Neural Net ASIC) tt_um_a1k0n_nyancat (VGA Nyan Cat) tt_um_rebeccargb_styler (Styler) tt_um_resfuzzy (resfuzzy) tt_um_cejmu (CEJMU Beers and Adders) tt_um_16_mic_beamformer_arghunter (16 Mic Beamformer) tt_um_pdm_pitch_filter_arghunter (PDM Pitch Filter) tt_um_pdm_correlator_arghunter (PDM Correlator) tt_um_ddc_arghunter (DDC) tt_um_i2s_to_pwm_arghunter (I2S to PWM ) tt_um_georgboecherer_vco (Analog Voltage Controlled Oscillator) tt_um_supermic_arghunter (Supermic ) tt_um_dmtd_arghunter (DMTD ) tt_um_htfab_bouncy_capsule (Bouncy Capsule) tt_um_samuelm_pwm_generator (PWM generator) tt_um_mattvenn_analog_ring_osc (Ring Oscillators) tt_um_toivoh_demo_deluxe (Sequential Shadows Deluxe [TT08 demo competition]) tt_um_vga_clock (VGA clock) tt_um_z2a_rgb_mixer (RGB Mixer demo) tt_um_faramire_stopwatch (Simple Stopwatch) tt_um_micro_tiles_container_group2 (Micro tile container (group 2)) tt_um_johshoff_metaballs (Metaballs) tt_um_top (Flame demo) tt_um_NicklausThompson_SkyKing (SkyKing Demo) tt_um_Electom_cla_4bits (4-bit CLA) tt_um_vga_cbtest (Generate VGA output for Color Blindness Test) tt_um_zoom_zoom (Zoom Zoom) tt_um_dpmunit (DPM_Unit) tt_um_clock_divider_arghunter (Clock Divider ) tt_um_dlmiles_poc_fskmodem_hdlctrx (FSK Modem +HDLC +UART (PoC)) tt_um_emilian_muxpga (TinyFPGA resubmit for TT08) tt_um_pyamnihc_dummy_counter (Dummy Counter) tt_um_whynot (Why not?) tt_um_sudana_ota5t_1 (5-T OTA) tt_um_dlmiles_tt08_poc_uart (UART) tt_um_dendraws_donut (donut) tt_um_wokwi_408237988946759681 (Counter) tt_um_tmkong_rgb_mixer (RGB Mixer) Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available