You have no items in your shopping cart.

Subtotal: 0.00

ADC Interfacing with Spartan3an FPGA Starter Kit

ADC interfacing with Spartan3an FPGA Starter Kit


The Analog to digital converter (ADC) is used to convert analog signal into digital signal. To process the analog signal onto digital devices like as FPGA which should be converted as digital form. The analog form means such as voltage or current. After the signal conversion, data is processed using FPGA.

ADC converter

The ADC input is analog signal such a current or voltage form and output as binary form (0 or 1). ADC conversion is given below Fig 1


Fig1: Block diagram of ADC

Many type of ADC available for conversion of signal. There are

  1. a) Flash ADC
  2. b) Dual slope ADC
  3. c) Successive approximation ADC
  4. d) Sigma- delta ADC

12 Bit SPI ADC

These ADCs are SPI Bus based which is a serial communication Protocol. So the number of pins in IC is very low. The MCP3202 IC is based on SAR Conversion technique. It has only 8 pins which are showed below Fig2.

Successive approximation register method

In this type of ADC contain the register (SAR), initially the MSB bit of SAR will be 1. Then the register monitor comparator output if the binary values of SAR greater or less then analog input and adjusted the binary value according to it.

Pin diagram


Fig2: Pin diagram of MCP3202

Pin details

Pin No



















Pin Description

Shutdown/chip select (SHDN/CS)

The SHDN/CS pin is used to initiate the communication between the FPGA and ADC. If this pin is low, the conversation will initiate. If the pin is high, the device will go standby mode.


There are two independent channels which are called as CH0/CH1. These channels can be programmed as two independent channels in single mode or a single pseudo differential input where one is IN+ and other one is IN-.


This pin is connected to GND.

Serial input (Din)

This pin is used as clock in to input channel configuration data.

Serial data out (Dout)

This pin can be used as shit out the result of the serial conversion. The data will be change on the falling edge of each clock.

Serial clock (SCK)

The serial clock is used to initiate the conversion and it gives the clock for each bit of conversion.


This both pins are common for supply and reference input of the ADC.

Interfacing SPI ADC with Spartan3an FPGA Starter Kit

The Spartan3an FPGA Starter Kit has 2-channel 12 Bit SPI ADC, indicated as in Figure. As you know in synchronous serial communication there is a clock line (SCK in case of SPI) which synchronizes the transfer.

The clock is always controlled by the MASTER. In our case the FPGA is the MASTER and the MCP3202 is a slave on the bus. SPI is full duplex, which means data can be sent and received simultaneously.

A SPI transfer is initiated by the MASTER pulling the CS line low. The CS line sits at HIGH during idle state. Now master can write to the bus in 8bit (or 1 byte) chunks.

One most important thing to note about SPI is that for every byte MASTER writes to SLAVE the MASTER receives one byte in return. So the only transaction possible is exchange of data.


Fig3: Interfacing ADC with Spartan3AN FPGA Project kit

VHDL Code description

The code has been written as read samples from the variable POT on the Spartan3an FPGA Starter Kit and compare with reference (Vdd/Vref) voltage. Finally the equivalent Binary values are generated with help of Vref. The output of ADC would be 12 bit value which is shown on the 12 LEDs. Here the jumper has been used to select the internal &external analog input. Among the two channels one channel for POT analog input and another one for Temperature sensor.

VHDL code for ADC

library IEEE;




entity adc_ch0 is

port ( clk : in std_logic;

cs : out std_logic;

sc : out std_logic;

do : out std_logic;

din : in std_logic;

led : out std_logic_vector(11 downto 0));

end adc_ch0;

architecture Behavioral of adc_ch0 is

type state is (spi,conversion,transmission);

signal presentstate : state := spi;

signal f : std_logic;

type arr is array (0 to 12) of std_logic_vector(9 downto 0);

signal store : arr;



--variable i : std_logic_vector(12 downto 0) := "0000000000000";

variable i,j,k : integer := 0;

variable tot : std_logic_vector(11 downto 0) := "000000000000";


if clk'event and clk = '1' then

if presentstate = spi then

if i <= 50 then ---"0000000110010" then

i := i + 1;

sc <= '1';

elsif i > 50 and i < 100 then ---"0000000110010" and i < "0000001100100" then

i := i + 1;

sc <= '0';

elsif i = 100 then ---"0000001100100" then

i := 0; ----"0000000000000";

if j < 18 then

j := j + 1;

elsif j = 18 then

presentstate <= conversion;

j := 0;

end if;

end if;

if j = 0 or j >= 18 then

cs <= '1';


cs <= '0';

end if;

if i > 40 and i < 60 then --- "0000000101000" and i < "0000000111100" then

case j is

when 0 =>

do <= '0';

when 1 =>

do <= '1';

when 2 =>

do <= '1';

when 3 =>

do <= '0'; -----channel bit

when 4 =>

do <= '1';

when others =>


end case;

end if;

if i >= 0 and i < 10 then --"0000000000000" and i < "0000000001010" then

case j is

when 6 =>

tot(11) := din;

when 7 =>

tot(10) := din;

when 8 =>

tot(9) := din;

when 9 =>

tot(8) := din;

when 10 =>

tot(7) := din;

when 11 =>

tot(6) := din;

when 12 =>

tot(5) := din;

when 13 =>

tot(4) := din;

when 14 =>

tot(3) := din;

when 15 =>

tot(2) := din;

when 16 =>

tot(1) := din;

when 17 =>

tot(0) := din;

when others =>


end case;

end if;

end if;


if presentstate = conversion then

cs <= '1';

led <= tot;

if i < 5000 then --"1001110001000" then

i := i + 1;

elsif i = 5000 then --"1001110001000" then

i := 0; ---"0000000000000";

presentstate <= spi;

end if;

end if;

end if;

end process;

end Behavioral;


User Constraint File

NET "clk" LOC = "p57" ;

NET "cs" LOC = "p110" ;

NET "din" LOC = "p114" ;

NET "do" LOC = "P113" ;

NET "led<0>" LOC = "p16" ;

NET "led<1>" LOC = "p15" ;

NET "led<2>" LOC = "p13" ;

NET "led<3>" LOC = "p12" ;

NET "led<4>" LOC = "p11" ;

NET "led<5>" LOC = "p10" ;

NET "led<6>" LOC = "p8" ;

NET "led<7>" LOC = "p7" ;

NET "sc" LOC = "p111" ;