You are currently viewing ADC  Interface with Xilinx Spartan FPGA

ADC Interface with Xilinx Spartan FPGA

Spread the love

ADC interfacing with Spartan 6 FPGA project Board


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

 Block diagram of ADC

 Fig1: Block diagram of ADC 

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

a) Flash ADC

b) Dual slope ADC

c) Successive approximation ADC 

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

Pin diagram of MCP3202

Fig2: Pin diagram of MCP3202

Pin details

Pin NoDetails

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 Spartan 6 FPGA project Board

The Spartan3an FPGA Project 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 Spartan 6 FPGA project Board

VHDL Code description

The code has been written as read samples from the variable POT on the Spartan 6 FPGA project Board 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 = P85;
NET "cs" LOC = P87;
NET "din" LOC = P92;
NET "do" LOC = P93;
NET "sc" LOC = P88;
NET "clk" LOC = P85;
NET "cs" LOC = P87;
NET "din" LOC = P92;
NET "do" LOC = P93;
NET "sc" LOC = P88;
NET "led[0]" LOC = P34;
NET "led[10]" LOC = P61;
NET "led[11]" LOC = P62;
NET "led[1]" LOC = P35;
NET "led[2]" LOC = P38;
NET "led[3]" LOC = P40;
NET "led[4]" LOC = P41;
NET "led[5]" LOC = P43;
NET "led[6]" LOC = P44;
NET "led[7]" LOC = P45;
NET "led[8]" LOC = P58;
NET "led[9]" LOC = P59; 

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.