You are on page 1of 21

ADC using SAR via DAC and make an A/D converter with

SAR (using LTC1257)

JANUARY 24, 2021


Abstract
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. A digital-to-analog converter (DAC), as
the name implies, is a data converter which generates an analog output from a digital input. A
DAC converts a limited number of discrete digital codes to a corresponding number of discrete
analog output values. In this project we have implemented ADC using SAR via DAC and make
an A/D converter with SAR (using LTC1257) and present the results of the simulations through
Vector Waveform Results as well demonstration on FPGA board using VHDL in ALTERA
Quartus II and the results will be shown on the FPGA board, we will also verify our results through
the Vector waveform results and RTL diagram.

Keywords: ADC, DAC, VHDL, Altera Quartus II

Page | 1
Table of Contents
Introduction ................................................................................................................................... 4

Problem Description ..................................................................................................................... 5

VHDL CODE ................................................................................................................................ 5

top_level...................................................................................................................................... 5

ADC_controller ......................................................................................................................... 7

DAC_controller ....................................................................................................................... 11

clk_enable................................................................................................................................. 15

Analysis & Synthesis ................................................................................................................... 16

RTL Diagram .............................................................................................................................. 16

Technology Map Viewer............................................................................................................. 17

Vector Waveform Results .......................................................................................................... 18

PIN Planner ................................................................................................................................. 18

FPGA Uploading ......................................................................................................................... 19

Conclusion ................................................................................................................................... 20

Page | 2
List of Figures

Figure 1 A three-bit DAC ............................................................................................................. 4

Figure 2 A four-bit DAC .............................................................................................................. 4

Figure 3 Analysis and Synthesis ................................................................................................ 16

Figure 4 RTL Diagram ............................................................................................................... 17

Figure 5 Technology Map Viewer ............................................................................................. 17

Figure 6 Vector Waveform Results ........................................................................................... 18

Figure 7 Pin Planner ................................................................................................................... 19

Figure 8 FPGA Uploading ......................................................................................................... 19

Page | 3
Introduction
A digital-to-analog converter (DAC), as the name implies, is a data converter which generates an
analog output from a digital input. A DAC converts a limited number of discrete digital codes to
a corresponding number of discrete analog output values. Because of the finite precision of any
digitized value, the finite word length is a source of error in the analog output. This is referred to
as quantization error. Any digital value is really only an approximation of the real-world analog
signal. The more digital bits represented by the DAC, the more accurate the analog output signal.
Basically, one LSB of the converter will represent the height of one step in the successive analog
output. You can think of a DAC as a digital potentiometer that produces an analog output that is a
fraction of the full-scale analog voltage determined by the value of the digital code applied to the
converter. Similar to ADCs, the performance of a DAC is determined by the number of samples it
can process and the number of bits used in the conversion process. For example, a three-bit
converter as shown in Figure 1 will have less performance than the four-bit converter shown in
Figure 2.

Figure 1 A three-bit DAC

Figure 2 A four-bit DAC

Page | 4
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.

Problem Description
Our task is to implement ADC using SAR via DAC and make an A/D converter with SAR (using
LTC1257) with PWM and present the results of the simulations through Vector Waveform Results
as well demonstration on FPGA Board. As a software solution we used Altera Quartus II which is
approved and tested for all FPGA systems. Source code was written in VHDL and the simulations
were made and presented in Vector Wave form results.

VHDL CODE
top_level
library ieee; architecture arch of top_level is
use ieee.std_logic_1164.all;
signal ADC2DAC_data : std_logic_vector(11
downto 0);
entity top_level is
signal start : std_logic;
port( clk : in std_logic;
signal sample_clk : std_logic;
reset : in std_logic;
D_out : in std_logic; -- ADC
CS_ADC : out std_logic; -- ADC
component clk_enable is
SCK_ADC : out std_logic; -- ADC
port( clk : in std_logic;
D_in : out std_logic; -- ADC
reset : in std_logic;
SDI : out std_logic; -- DAC
sample_clk : out std_logic);
SCK_DAC : out std_logic; -- DAC
end component clk_enable;
LDAC : out std_logic; -- DAC
CS_DAC : out std_logic); --DAC
component DAC_controller is
end entity;
port( clk : in std_logic;
start : in std_logic;

Page | 5
data : in std_logic_vector(11 reset => reset,
downto 0);
sample_clk => start);
reset : in std_logic;
finished : out std_logic;
ADC_controller_comp: component
CS : out std_logic; ADC_controller
SDI : out std_logic; port map( clk => clk,
SCK : out std_logic; start => start,
LDAC : out std_logic); reset => reset,
end component DAC_controller; D_out => D_out,
-- finished => finished --
component ADC_controller is CSn => CS_ADC,
port( clk : in std_logic; SCL => SCK_ADC,
start : in std_logic; D_in => D_in,
reset : in std_logic; data => ADC2DAC_data);
D_out : in std_logic;
finished : out std_logic; DAC_controller_comp: component
DAC_controller
CSn : out std_logic;
port map( clk => clk,
SCL : out std_logic;
start => start,
D_in : out std_logic;
data => ADC2DAC_data,
data : out std_logic_vector(11 downto
0)); reset => reset,
end component ADC_controller; -- finished => '0';
CS => CS_DAC,
begin SDI => SDI,
SCK => SCK_DAC,
clk_enable_comp: component clk_enable LDAC => LDAC);
port map( clk => clk, end arch;

Page | 6
ADC_controller

library ieee; begin


use ieee.std_logic_1164.all; if rising_edge(clk) then
if reset = '1' then
entity ADC_controller is count_ce <= 0;
port( clk : in std_logic; serial_clock_enable <= '0';
start : in std_logic;
reset : in std_logic; elsif start = '1' then
D_out : in std_logic; count_ce <= 0;
serial_clock_enable <= '0';
finished : out std_logic;
CSn : out std_logic; elsif start = '0' and started = '1' then
SCL : out std_logic;
D_in : out std_logic; if count_ce < 30 then
data : out std_logic_vector(11 downto count_ce <= count_ce + 1;
0));
serial_clock_enable <= '0';
end entity;
architecture arch of ADC_controller is
elsif count_ce = 30 then
signal count_ce : integer range 0 to 30
serial_clock_enable <= '1';
:= 0;
count_ce <= 0;
signal count : integer range 0 to 36 :=
0; end if;
signal reg_data : std_logic_vector(11 end if;
downto 0);
end if;
signal serial_clock_enable : std_logic;
end process;
signal conf_bits : std_logic_vector(3
downto 0) := "1101"; -- Status
signal started : std_logic; process(clk)

begin begin

process(clk) -- SPI Clock if rising_edge(clk) then


if reset = '1' then

Page | 7
finished <= '0'; count <= count + 1;
CSn <= '1'; when 3 => CSn <= '0';
SCL <= '0'; SCL <= '0';
D_in <= '0'; D_in <= conf_bits(2);
started <= '0'; count <= count + 1;
count <= 0; when 4 => CSn <= '0';
reg_data <= (others => '0'); SCL <= '1';
D_in <= conf_bits(2);
elsif start = '1' then count <= count + 1;
count <= 0; when 5 => CSn <= '0';
CSn <= '1'; SCL <= '0';
SCL <= '0'; D_in <= conf_bits(1);
D_in <= '0'; count <= count + 1;
started <= '1'; when 6 => CSn <= '0';
SCL <= '1';
elsif started = '1' and start = '0' then D_in <= conf_bits(1);
count <= count + 1;
if serial_clock_enable = '1' then when 7 => CSn <= '0';
case count is SCL <= '0';
when 0 => CSn <= '1'; D_in <= conf_bits(0);
SCL <= '0'; count <= count + 1;
count <= count + 1; when 8 => CSn <= '0';
when 1 => CSn <= '0'; SCL <= '1';
SCL <= '0'; D_in <= conf_bits(0);
D_in <= conf_bits(3); count <= count + 1;
count <= count + 1;
when 2 => CSn <= '0'; when 9 => CSn <= '0';
SCL <= '1'; SCL <= '0'; -- Null bit
needed as per ADC datasheets
D_in <= conf_bits(3);
count <= count + 1;

Page | 8
when 10 => CSn <= '0'; reg_data(8) <= D_out;
SCL <= '1'; count <= count + 1;
count <= count + 1; -- Null bit when 18 => CSn <= '0';
as per ADC datasheets
SCL <= '1';
when 11 => CSn <= '0';
reg_data(8) <= D_out;
SCL <= '0';
count <= count + 1;
reg_data(11) <= D_out;
when 19 => CSn <= '0';
count <= count + 1;
SCL <= '0';
when 12 => CSn <= '0';
reg_data(7) <= D_out;
SCL <= '1';
count <= count + 1;
reg_data(11) <= D_out;
when 20 => CSn <= '0';
count <= count + 1;
SCL <= '1';
when 13 => CSn <= '0';
reg_data(7) <= D_out;
SCL <= '0';
count <= count + 1;
reg_data(10) <= D_out;
when 21 => CSn <= '0';
count <= count + 1;
SCL <= '0';
when 14 => CSn <= '0';
reg_data(6) <= D_out;
SCL <= '1';
count <= count + 1;
reg_data(10) <= D_out;
when 22 => CSn <= '0';
count <= count + 1;
SCL <= '1';
when 15 => CSn <= '0';
reg_data(6) <= D_out;
SCL <= '0';
count <= count + 1;
reg_data(9) <= D_out;
when 23 => CSn <= '0';
count <= count + 1;
SCL <= '0';
when 16 => CSn <= '0';
reg_data(5) <= D_out;
SCL <= '1';
count <= count + 1;
reg_data(9) <= D_out;
when 24 => CSn <= '0';
count <= count + 1;
SCL <= '1';
when 17 => CSn <= '0';
reg_data(5) <= D_out;
SCL <= '0';

Page | 9
count <= count + 1; count <= count + 1;
when 25 => CSn <= '0'; when 32 => CSn <= '0';
SCL <= '0'; SCL <= '1';
reg_data(4) <= D_out; reg_data(1) <= D_out;
count <= count + 1; count <= count + 1;
when 26 => CSn <= '0'; when 33 => CSn <= '0';
SCL <= '1'; SCL <= '0';
reg_data(4) <= D_out; reg_data(0) <= D_out;
count <= count + 1; count <= count + 1;
when 27 => CSn <= '0'; when 34 => CSn <= '0';
SCL <= '0'; SCL <= '1';
reg_data(3) <= D_out; reg_data(0) <= D_out;
count <= count + 1; count <= count + 1;
when 28 => CSn <= '0'; when 35 => CSn <= '0';
SCL <= '1'; SCL <= '0';
reg_data(3) <= D_out; count <= count + 1;
count <= count + 1; when 36 => CSn <= '1';
when 29 => CSn <= '0'; finished <= '1';
SCL <= '0'; started <= '0';
reg_data(2) <= D_out; data <= reg_data; -- Send data
when finished is set
count <= count + 1;
when others => count <= 0;
when 30 => CSn <= '0';
end case;
SCL <= '1';
reg_data(2) <= D_out;
end if;
count <= count + 1;
end if;
when 31 => CSn <= '0';
end if;
SCL <= '0';
end process;
reg_data(1) <= D_out;
end arch;

Page | 10
DAC_controller

library ieee; signal count_ce : integer range 0 to 30


:= 0;
use ieee.std_logic_1164.all;

entity DAC_controller is
port( clk : in std_logic;
begin
start : in std_logic; -- changed to
sample_clk in implementation
data : in std_logic_vector(11 process(clk) -- Create serial clock
downto 0); that controls SCL in the process below.
reset : in std_logic; begin
if rising_edge(clk) then
finished : out std_logic; if reset = '1' then
CS : out std_logic; count_ce <= 0;
SDI : out std_logic; serial_clock_enable <= '0';
SCK : out std_logic; -- serial clock?
LDAC : out std_logic); elsif start = '1' then
count_ce <= 0;
end entity; serial_clock_enable <= '0';

architecture arch of DAC_controller is elsif start = '0' and started = '1' then

signal reg_data : std_logic_vector(11 if count_ce < 30 then


downto 0);
count_ce <= count_ce + 1;
signal count : integer range 0 to 34 :=
serial_clock_enable <= '0';
0;
signal started : std_logic;
elsif count_ce = 30 then
signal config_bits : std_logic_vector(3
downto 0) := "0001"; serial_clock_enable <= '1';
signal serial_clock_enable : std_logic; count_ce <= 0;

Page | 11
end if; case count is
end if; when 0 => CS <= '1';
end if; SCK <= '0';
end process; SDI <= '0';
count <= count + 1;
when 1 => CS <= '0';
process(clk) -- Process to handle SCK <= '0';
the output
SDI <= config_bits(3);
begin
count <= count + 1;
if rising_edge(clk) then
when 2 => CS <= '0';
if reset = '1' then
SCK <= '1';
finished <= '0';
SDI <= config_bits(3);
CS <= '1';
count <= count + 1;
SDI <= '0';
when 3 => CS <= '0';
SCK <= '0';
SCK <= '0';
started <= '0';
SDI <= config_bits(2);
reg_data <= (others => '0');
count <= count + 1;
when 4 => CS <= '0';
SCK <= '1';
elsif start = '1' then
SDI <= config_bits(2);
reg_data <= data;
count <= count + 1;
count <= 0;
when 5 => CS <= '0';
CS <= '1';
SCK <= '0';
SDI <= '0';
SDI <= config_bits(1);
SCK <= '0';
count <= count + 1;
started <= '1';
when 6 => CS <= '0';
SCK <= '1';
elsif started = '1' and start = '0' then
SDI <= config_bits(1);
count <= count + 1;
if serial_clock_enable = '1' then

Page | 12
when 7 => CS <= '0'; SCK <= '1';
SCK <= '0'; SDI <= reg_data(9);
SDI <= config_bits(0); count <= count + 1;
count <= count + 1; when 15 => CS <= '0';
when 8 => CS <= '0'; SCK <= '0';
SCK <= '1'; SDI <= reg_data(8);
SDI <= config_bits(0); count <= count + 1;
count <= count + 1; when 16 => CS <= '0';
when 9 => CS <= '0'; SCK <= '1';
SCK <= '0'; SDI <= reg_data(8);
SDI <= reg_data(11); count <= count + 1;
count <= count + 1; when 17 => CS <= '0';
when 10 => CS <= '0'; SCK <= '0';
SCK <= '1'; SDI <= reg_data(7);
SDI <= reg_data(11); count <= count + 1;
count <= count + 1; when 18 => CS <= '0';
when 11 => CS <= '0'; SCK <= '1';
SCK <= '0'; SDI <= reg_data(7);
SDI <= reg_data(10); count <= count + 1;
count <= count + 1; when 19 => CS <= '0';
when 12 => CS <= '0'; SCK <= '0';
SCK <= '1'; SDI <= reg_data(6);
SDI <= reg_data(10); count <= count + 1;
count <= count + 1; when 20 => CS <= '0';
when 13 => CS <= '0'; SCK <= '1';
SCK <= '0'; SDI <= reg_data(6);
SDI <= reg_data(9); count <= count + 1;
count <= count + 1; when 21 => CS <= '0';
when 14 => CS <= '0'; SCK <= '0';

Page | 13
SDI <= reg_data(5); count <= count + 1;
count <= count + 1; when 29 => CS <= '0';
when 22 => CS <= '0'; SCK <= '0';
SCK <= '1'; SDI <= reg_data(1);
SDI <= reg_data(5); count <= count + 1;
count <= count + 1; when 30 => CS <= '0';
when 23 => CS <= '0'; SCK <= '1';
SCK <= '0'; SDI <= reg_data(1);
SDI <= reg_data(4); count <= count + 1;
count <= count + 1; when 31 => CS <= '0';
when 24 => CS <= '0'; SCK <= '0';
SCK <= '1'; SDI <= reg_data(0);
SDI <= reg_data(4); count <= count + 1;
count <= count + 1; when 32 => CS <= '0';
when 25 => CS <= '0'; SCK <= '1';
SCK <= '0'; SDI <= reg_data(0);
SDI <= reg_data(3); count <= count + 1;
count <= count + 1; when 33 => CS <= '0';
when 26 => CS <= '0'; SCK <= '0';
SCK <= '1'; SDI <= '0';
SDI <= reg_data(3); count <= count + 1;
count <= count + 1; when 34 => CS <= '1';
when 27 => CS <= '0'; finished <= '1';
SCK <= '0'; started <= '0';
SDI <= reg_data(2); when others => count <= 0;
count <= count + 1; end case;
when 28 => CS <= '0';
SCK <= '1'; end if;
SDI <= reg_data(2); end if;

Page | 14
end if; LDAC <= '0';
end process;
end arch;

clk_enable

library ieee; if rising_edge(clk) then


use ieee.std_logic_1164.all; if reset = '1' then
sample_count <= 0;
entity clk_enable is sample_clk <= '0';
port( clk : in std_logic;
reset : in std_logic; elsif sample_count < 2500 then
sample_clk : out std_logic); sample_count <= sample_count + 1;
end entity; sample_clk <= '0';

architecture arch of clk_enable is elsif sample_count = 2500 then


sample_count <= 0;
signal sample_count : integer range 0 to sample_clk <= '1';
2500 := 0;

end if;
begin
end if;
process(clk)
end process;
begin
end arch;

Page | 15
Analysis & Synthesis

To check the results on Vector Waveform we need to first perform analysis and synthesis, to
check that there is no error in the program and we can then verify our design through Vector
Waveform (VWF) results and RTL Diagram.

Figure 3 Analysis and Synthesis

RTL Diagram

In the figure below RTL diagram is shown basically register-transfer level (RTL) is
a design abstraction which models a synchronous digital circuit in terms of the flow of digital
signals (data) between hardware registers, and the logical operations performed on those signals

Page | 16
Figure 4 RTL Diagram

Technology Map Viewer

Figure 5 Technology Map Viewer

Page | 17
Vector Waveform Results

The vector waveform results below demonstrate the effectiveness of our approach and it can be
seen that the desire performance can be achieved through the implementation on Quartus and
FPGA

Figure 6 Vector Waveform Results

PIN Planner

Below in the Pin Planner we have assigned the input and output pins to see the demonstration on
FPGA Board

Page | 18
Figure 7 Pin Planner

FPGA Uploading

In last we upload our program on FPGA board to check the hardware demonstration of the
program.

Figure 8 FPGA Uploading

Page | 19
Conclusion
We have implemented this project using VHDL in Altera Quartus II. The simulation results
demonstrate the effectiveness of the approach and it can be seen that the desired level of
performance can be attained using FPGA. The Vector Waveform Results demonstrate the efficacy
of the proposed approach.

Page | 20

You might also like