Reference Design
Active Project
Nanosoc ADC Integration
SoClabs

ADC Integration in nanoSoC

Rationale

The aim of this project is to define a mixed signal subsystem for the nanosoc reference design

The mixed signal subsystem should be able to sample analog signals at a regular sampling rate, and transmit a digital representation of this signal to the rest of the nanosoc system. In order to interface with real-world signals in a digital System on Chip ("SoC"), an analog to digital conversion ("ADC") is needed. 

Technical overview

From the digital side, there needs to be an interface for the system that can be used to read and write to registers within the ADC, these include data as well as some control registers. On the analog side there needs to be a way of sampling the analog signal and converting it to a digital representation.

Analog to digital conversion

For this project the analog to digital converter portion of the subsystem has been chosen to be a successive approximation register ("SAR") type ADC. These type of ADCs are common in microcontroller SoCs which is in line with the design target for nanoSoC. They provide a good, power efficient ADCs for reasonable speed, accuracy (common use ranges from 8 to 16 bit resolution) and implementation area. 

These type of ADC work by comparing the input signal, which is held on a Track and Hold to a signal produced by a digital to analog converter ("DAC"). This DAC is fed digital values by the ADC control logic which represent an estimate of the voltage. Each estimate is viewed by the Comparitor as above or below the input signal and feedback to the controller which adjusts the estimate until the system converges when the two match and the digital value is stored in the output register. In nanoSoC that is available for transmission on the Advance Peripheral Bus ("APB"). 

Block diagram of SAR ADC

Specifications

For nanoSoC these are the target specifications that have been determined for the ADC:

  • 8 bit resolution, this is a reasonable trade of between accuracy, speed of convergence, area and power.
  • 100 kHz sampling rate, due to the design an SAR ADCs power dissipation scales with the sample rate.
  • 0-1.2V conversion
  • Low differential nonlinearity and integral nonlinearity. In general the linearity of the overall ADC is limited by the linearity of the DAC.
  • Low power (<1mW)

 

FPGA prototyping

To be added

 

Architecture

Digital to Analog Convertor

For simplicity, the DAC design is based on a R-2R summing amplifier. For a more detailed explanation of how this circuit works, you can find a good resource here

DAC Schematic

The schematic above shows the implemented R-2R DAC subsystem. Due to the sizing restrictions of the resistors in the TSMC65nm PDK, in order to get the correct resistor values, parallel resistors are used for the R values, with each resistor having a value of 2R (the actual value is 335 Ohm).

The Operational Amplifier ("opamp") design is the same one used in the TSMC 65nm PLL. As the gain of this opamp setup is 1, the available bandwidth of this should be around 240 MHz. This is consistent with the simulations of the DAC, as the settling time for the conversion of the MSB is around 4ns. An SAR ADC's speed is limited by the settling time of the DAC. This suggests that this DAC circuit will work well for an ADC sampling frequency of 100 kHz.

 

Simulation of DAC

Simulating the DAC with increasing binary input shows a fairly linear increase in voltage from ~0V to ~1.2V. By simulating the change in voltage 1 bit at a time, the actual voltage for each bit can be measured. The results from this are shown below for each bit from MSB to LSB. The integral nonlinearity is -8.14 LSBs, this is the sum of all differences in number of LSBs. 

Ideal Voltage (mV)Actual Voltage (mV)Difference (mV)Difference (LSBs)
600.00590.22-9.78-2.09
300.00291.78-8.22-1.75
150.00142.33-7.67-1.64
75.0069.09-5.91-1.26
37.5034.07-3.43-0.73
18.7516.94-1.81-0.39
9.388.47-0.91-0.19
4.694.29-0.40-0.09

Digital Interface

For the digital interface:

  • APB read and write
  • Clock divider control
  • Enable/disable ADC (with clock gating), to enable power saving where the data acquisition is not continuous or to isolate measurements.
  • Busy status register
  • Interrupt enable

Interconnect fabric

The nanosoc reference design bus matrix is generated using the Arm Academic Access tools as described in Building system-optimised AMBA interconnect. The bus system within the SoC should be carefully planned to manage bandwidth and access latency. The nanosoc design uses a Multi-layer interconnect that allows multiple bus transaction Initiators (traditionally called 'Masters') to communicate concurrently with the particular memory-mapped target responder peripherals or subsystems (traditionally called 'Slaves')
The Advanced Peripheral Bus ("APB") is not pipelined and is used to connect to low bandwidth peripherals and is optimized for low power consumption and reduced interface complexity. An AHB-APB bridge acts as a responder on the nanosoc AHB bus synchronizing the time domains of the high-speed AHB bus with the lower-speed clocks used by peripherals.

This project will utilise the simple APB bus interface for integration of real-world analog signals into nanosoc. In order to add this to the nanosoc peripheral region, an extra port has been added to the AHB MUX, to include a AHB to APB bridge and APB Mux for multiple ADC's to be added in the system. We end up with a subsystem as shown below for the ADC integration in nanosoc

nanosoc peripheral subsystem with added ADC regions

Address Map

The address for a peripheral is determined by the bus to which the peripheral is attached. nanosoc has a defined address map with the range allocated to the System Peripheral Region. We are going to add an ADC region at the end of the nanosoc peripheral bus region as shown below

nanosoc system io address map
start-addressend-addressnotes
0x400000000x40000FFFTimer 0
0x400010000x40001FFFTimer 1
0x400020000x40003FFFDual Timer
0x400040000x40004FFFUART 0
0x400050000x40005FFFUART 1
0x400060000x40006FFFUART 2
0x400080000x40008FFFWatchdog Timer
0x4000E0000x4000EFFFUSRT 2
0x4000F0000x4000FFFFDMA 0 Base
0x400100000x40010FFFGPIO 0
0x400110000x40011FFFGPIO 1
0x4001F0000x4001FFFFSystem Control
0x40020000x4002FFFADC Region

CPU Interrupts

Define the system interrupt for a measurement.

Integration Modelling

To develop the integration of an ADC in nanosoc, a simplified verilog-AMS model of an ADC was used. Verilog-AMS allows for the simulation of analog and mixed signal modules alongside digital verilog or other HDL's. The benefit of using verilog-AMS is that it is also technology independent so can be simulated without needing access to PDK's, the disadvantage is that it is not synthesizable, however the analog/mixed signal modules can easily be replaced with macro's of the final IP's. 

The development of the ADC subsystem was done within the nanosoc test environment. The benefit of this is that it was easy to develop and run C code from the Cortex-M0, without the need for creating a testbench that could handle APB transfers.

APB Register interface behavioural modelling

The APB register interface is handled by a simple state machine. This FSM waits in the APB_IDLE state until the PSEL signal goes high, and checks whether PWRITE is asserted or not. If PWRITE is high it will go into the APB_WRITE state, otherwise the APB_READ state. Within these states it either writes to or reads from the register as pointed to by PADDR. You can see in APB_WRITE that PSLVERR is asserted if certain read only registers are attempted to be written to. And currently the only registers that are R/W are the clock divider (CLK_DIV) and ENABLE (which enables the ADC if bit 0 is written as 1).

PREADY is asserted high if the state machine is in either APB_READ or APB_WRITE, otherwise it is 0. 

// APB interface
localparam  APB_IDLE = 2'd0,
            APB_WRITE = 2'd1,
            APB_READ = 2'd2;

reg [1:0] apb_current_state;
reg [1:0] apb_next_state;

always @(posedge PCLK or negedge PRESETn) begin
    if(~PRESETn) begin
        apb_current_state <= APB_IDLE;
        PSLVERR_reg <= 1'b0;
    end else begin
        apb_current_state <= apb_next_state;
    end
end

always @(*) begin
    case(apb_current_state)
        APB_IDLE: begin
            PSLVERR_reg = 1'b0;
            if(PSEL) begin
                if(PWRITE) begin
                    apb_next_state = APB_WRITE;
                end else begin
                    apb_next_state = APB_READ;
                end
            end
            else begin
                apb_next_state = APB_IDLE;
            end
        end
        APB_WRITE: begin
            case(PADDR)
                10'h000: PSLVERR_reg = 1'b1;
                10'h001: PSLVERR_reg = 1'b1;
                10'h002: CLK_DIV = PWDATA;
                10'h003: ENABLE_reg = PWDATA[7:0];
                10'h3F0: PSLVERR_reg = 1'b1;
                10'h3F1: PSLVERR_reg = 1'b1;
                10'h3F2: PSLVERR_reg = 1'b1;
                10'h3F3: PSLVERR_reg = 1'b1;
                10'h3F4: PSLVERR_reg = 1'b1;
                10'h3F5: PSLVERR_reg = 1'b1;
                10'h3F6: PSLVERR_reg = 1'b1;
                10'h3F7: PSLVERR_reg = 1'b1;
            endcase
            apb_next_state = APB_IDLE;
        end
        APB_READ: begin
            case(PADDR)
                10'h000: PRDATA_reg = DATA_reg;
                10'h001: PRDATA_reg = STATUS_reg;
                10'h002: PRDATA_reg = CLK_DIV;
                10'h003: PRDATA_reg = {24'd0, ENABLE_reg};
                10'h3F0: PRDATA_reg = {24'd0, ID_reg[63:56]};
                10'h3F1: PRDATA_reg = {24'd0, ID_reg[55:48]};
                10'h3F2: PRDATA_reg = {24'd0, ID_reg[47:40]};
                10'h3F3: PRDATA_reg = {24'd0, ID_reg[39:32]};
                10'h3F4: PRDATA_reg = {24'd0, ID_reg[31:24]};
                10'h3F5: PRDATA_reg = {24'd0, ID_reg[23:16]};
                10'h3F6: PRDATA_reg = {24'd0, ID_reg[15:8]};
                10'h3F7: PRDATA_reg = {24'd0, ID_reg[7:0]};
                default: PRDATA_reg = 32'hDEADDEAD;
            endcase 
            apb_next_state = APB_IDLE;
        end
    endcase
end

assign PREADY = (apb_current_state==APB_READ|apb_current_state==APB_WRITE)? 1'b1:1'b0;

This module is instantiated within nanosoc_sysio_adc_ss, which is a child of nanosoc_region_sysio. To add this to nanosoc, a new port in the AHB mux was added, and an APB bus was created off this port. To verify this module, some simple read/write tests were executed:

  • Read from ID registers and verify contents
  • Read from CLK_DIV register for the default 0x0A (as set by the reset condition not shown in above code)
  • Write to CLK_DIV and then read contents to ensure they have changed
  • Write to ENABLE register 
  • Read from DATA register.

 

Pinlist

Define the pin configuration for the external signal to interface to the ADC function.

 

SAR ADC Verilog-AMS modelling

parameter integer bits = 8;// from [1:24];	// resolution (bits)
parameter real fullscale = 1.2;		// input range is from 0 to fullscale (V)
electrical EXTIN;
real sample, midpoint, cmp;
integer i;
reg [bits-1:0] buffer;
reg [bits-1:0] out;

assign DATA=out;
assign midpoint = fullscale/2.0;

assign cmp = buffer[7]*(fullscale/2.0) + buffer[6]*(fullscale/4.0) + buffer[5]*(fullscale/8.0) + buffer[4]*(fullscale/16.0)
	 + buffer[3]*(fullscale/32.0) + buffer[2]*(fullscale/64.0) + buffer[1]*(fullscale/128.0) + buffer[0]*(fullscale/256.0);
always @(posedge adc_clk or negedge resetn) begin
	if(~resetn) begin
		i <= 7;
		buffer <= 8'h80;
		out <= 8'h00;
	end else begin
		if(i==0) begin
			if (sample>cmp) 
				out <= {buffer[7:1], 1'b1};
			else
				out <= {buffer[7:1], 1'b0};
			buffer <= 8'h80;
			i <= 7;
			sample = 0.51;
		end else begin
			if (sample>cmp) 
				buffer[i]<=1'b1;
			else
				buffer[i]<=1'b0;
			if(i!=0)
				buffer[i-1]<=1'b1;
			i <= i-1;
		end
	end
end

The main bulk of the ADC model is shown in the above code. You can see from this that at each clock cycle, the sample which is captured every 8 clock cycles, is compared against the output of a DAC. An N-bit SAR ADC will require N comparison periods and will not be ready for the next conversion until the current one is complete.

SAR ADC verilog AMS simulation

To test the verilog-AMS model, a constant 0.51V was applied to the input. At each clock edge, the sampled value is compared to ''cmp'' which is effectively the DAC output. This DAC output is generated from the value in 'buffer'. It can be seen from this model, that after 8 clock cycles the output is captured as 0x6C, which for a 1.2V full scale ADC gives a corresponding voltage of 0.50625 V, just below the applied 0.51 V. 

Over the APB Interface the read output is 0x6C, confirming that both the ADC model works, and that APB register access is working as expected

Physical Design and Verification

The physical layout and verification of the ADC's individual subsystem is currently under development (as on November 2024). The first, and most complex, component is the Op-Amp. Physical design involves placing the fundamental components from the technology node PDK (transistors, resistors, capacitors etc.) and routing the nets to connect these components.

Once a layout is complete, verification takes place. First is the Design Rule Checks ("DRC") and Layout Versus Schematic ("LVS"). DRC checks the layout against the design rules from the foundry, and LVS checks the layout against the prior design stage higher level abstract representation (eg. netlist)  to check that they are both equivalent. During the layout process we also add dummy devices which are placed to improve the uniformity across the device, as devices at the edge of a geometry are likely to be slightly distorted compared to the centre. Usually this applies to things like gate thickness and dopant profiles.

Mixed Signal Verification

Currently the mixed signal component under development has been tested as a separate entity. The digital side being tested using a simplified verilog-A model. Verilog-A is the analog-only subset of Verilog-AMS hardware description language. Verilog-A has been used to describe primitive circuit components (resistors, capacitors etc.) that a SPICE class simulation tool uses to build up a system of nonlinear differential equations that are solved when the simulation is executed.  , The analog side is being tested with basic digital switches, but not with the full control system expected for the final project delivery. 

 

Design and validation testbench

To be added

 

First working version

ADC V1 schematic

A first version of the ADC's schematic is shown above. A detailed schematic of each of the components will be added at a later date. 

For a first iteration it (sort of) works. The implementation uses the same opamp used in the DAC for the comparator.  The working principle is after a active low pulse on the nRST pin the analog switch + capacitor will hold the value of Vin at that time and pass to the comparator. The SAR begins with the MSB high, and all other bits low. The DAC converts this to an analogue signal and compares against the held version of Vin. If V_DAC is greater than Vin, the comparator output will be low, and the SAR will de-assert that bit in the next clock cycle (and vice versa if V_DAC is smaller than Vin). On the next clock cycle, the MSB-1 bit will be asserted and so on until the lowest bit is reached (8 bits, 8 cycles) The value of Q will then not change until another nRST is asserted.  

ADC working output

The above illustrates the behaviour defined in the expected simulation result. However it also shows that there is some error in the final DAC value. In this example a Vin of 800mV has been used, and the DAC output is 812mV. Given the binary output on Q (10110110), for an ideal DAC, this should actually correspond to 853 mV. An error of over 53mV (equates to 11.3 LSBs).

The power consumption is also higher than would be ideal.

Total Average Power (mW)4.47
SAR Average Power (mW)0.013
DAC Average Power (mW)4.31
Sample and hold Average Power (nW)2.23
Comparator Average Power (mW)0.15

From the breakdown above it is clear most significant usage of power is in the DAC.

The very simplistic opamp used here has a common-mode input voltage range of about 0.3-1.2V. This directly correlates to what the comparator can "see" as a difference in the DAC output and Vin. So the actual conversion range of this ADC is only 0.3-1.2.

Comparing to the initial specification, the results of the initial implementation are:

8 bit resolutionPass
100 kHz sampling ratePass
0-1.2V conversionFail
Low differential nonlinearity and integral nonlinearitySomewhat Fail
Low power (<1mW)Fail

The conclusion of this first iteration, is that the SAR and sample & hold circuitry are working, but the DAC and comparator need more work.

Version 2

The second iteration of this design will focus heavily on:

  • Increasing the common-mode input voltage range of the comparator

  • Decreasing the power consumption of the DAC

  • Ideally reducing the error in the DAC conversion

 

Project Milestones

  1. Behavioural Design

    Target Date

    Design of the components of the Analog-digital converter

  2. Behavioural Modelling

    Target Date

    Model the analog behaviour of the subsystem and confirm it meets the requirements

  3. Mixed Signal Simulations

    Target Date

    Simulation of the full mixed signal subsystem

  4. Integration with nanoSoC

    Target Date

    Integration of the top level interface within nanoSoC with mixed signal simulations

  5. Physical Design

    Design Flow
    Target Date

    Physical design of ADC

  6. Mixed Signal verification

    Target Date

Team

Research Area
Low power system design
Role
Consultant

Additional Project for:

Reference Design
nanoSoC demo: kNN project
nanoSoC
A simple, low cost, entry level microcontroller SoC extendable for custom accelerators or simple signal processing, ideal for PhD or other students.

Comments

Although the actual work of Integration with nanosoc comes later in the milestone I feel we should complete the Architecture definition as soon as we can. This will help contestants in the educational/collaboration track with their own Architecture definitions.

Hi Ayodeji,

I think from the front end side, the best place to start is to consider what kind of sensors you want to connect to, and what requirements they have. Particularly - voltage range, input type (single ended or differential are most common),  are they active or passive, how frequently you want to read the sensor, and what digital resolution you need.
I think once you have this information you can start thinking about what the requirements are on the analog front end. For instance if you have a differential input, you will need some sort of differential amplifier that feeds into the ADC. 

Once you have done this if you could add this information on your project we can continue to assist you there
We will make this work public on the accelerator project repository shortly, I'm just trying to get it working in a way that doesn't break the digital only flow, so you can possibly integrate this into your design as well

Daniel

 

There have been some recent discussions of how to improve the design of nanoSoC to enable finer power management of parts of the system to enable more precise measurement of energy consumption.

It would be interesting to understand the potential for the sensor subsystem. One option might be to have a power management function that distributes the AHB clock to only a selected set of peripherals where the external environment can determine the set to select. This might be configured as part of the SoC startup or perhaps as  masks that can be set at run time to distribute the clock to a limited number of selected peripherals.

There was some discussion on whether to use simple registers to keep the gate count low, as is a key driver for nanoSoC or to use a specific power management controller.

Any power management design may need to consider what other considerations need to be taken, for example,  any voltage regulators that can be set to run in low-power mode, if any of the sensor system needs some energy even in an idel state. 

The  interrupt mechanism that causes the re-selection of the peripheral device to return to active operation and any latency associated with this action.

Add new comment

To post a comment on this article, please log in to your account. New users can create an account.

Project Creator
Daniel Newbrook

Digital Design Engineer at University of Southampton
Research area: IoT Devices
ORCID Profile

Submitted on

Actions

Log-in to Join the Team