ADC Using SAR Via DAC With PWM
ADC Using SAR Via DAC With PWM
Figure 1 Pulse-width modulation: a) typical PWM waveforms, b) comparison of pure and "modified" sine
Problem Description
Our task is to implement ADC using SAR via DAC 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 file.
VHDL Code (PWM Generation)
library ieee; if (en = '1') then
use ieee.std_logic_1164.all; if (cnt = 0) then
use ieee.numeric_std.all; cnt <= to_unsigned(PERIOD-1,
use work.pwm_reg_pack.ALL; cnt'length);
entity pwm is clk_en <= '1';
port ( else
clk : in std_logic; cnt <= cnt - 1;
rst : in std_logic; end if;
en : in std_logic; end if;
duty : in end if;
std_logic_vector(DUTY_CYCLE_W-1 downto end process cnt_pr;
0); cnt_duty_pr : process(clk, rst)
pwm_out : out std_logic begin
); if (rst = '1') then
end entity pwm; cnt_duty <= (others => '0');
architecture rtl of pwm is pwm_out <= '0';
signal clk_en : std_logic; elsif (rising_edge(clk)) then
signal cnt : unsigned(PERIOD_W-1 if (clk_en = '1') then
downto 0); cnt_duty <= cnt_duty + 1;
signal cnt_duty : unsigned(DUTY_CYCLE_W- end if;
1 downto 0); if (cnt_duty < unsigned(duty)) then
begin pwm_out <= '1';
cnt_pr : process(clk, rst) else
begin pwm_out <= '0';
if (rst = '1') then end if;
cnt <= (others => '0'); end if;
clk_en <= '0'; end process cnt_duty_pr;
elsif (rising_edge(clk)) then end rtl;
clk_en <= '0';
Analysis & Synthesis (PWM Generation)
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.
VHDL Code
library IEEE; ); COMPONENT transmitter
use IEEE.STD_LOGIC_1164.ALL; END COMPONENT; PORT(
entity TOPCZECH is clk : IN
Port ( an : out COMPONENT CRC std_logic;
STD_LOGIC_VECTOR (3 downto PORT( enable : IN
0); clk : IN std_logic;
MHZ50 : in STD_LOGIC; std_logic;
R : in STD_LOGIC; data_en : IN sendRequest_T1 : IN
a_to_g : out std_logic; std_logic;
STD_LOGIC_VECTOR (6 downto dataIn : IN data_in_T1 : IN
0); std_logic_vector(71 downto 0); std_logic_vector(13 downto 0);
SW dataOut : OUT
: IN STD_LOGIC_VECTOR (3 std_logic_vector(15 downto 0); sendRequest_H1 : IN
downto 0); dataValid : OUT std_logic;
-- en : in STD_LOGIC; std_logic data_in_H1 : IN
LED ); std_logic_vector(12 downto 0);
: out STD_LOGIC_VECTOR (7 END COMPONENT;
downto 0); sendRequest_T2 : IN
TX std_logic;
: OUT STD_LOGIC; COMPONENT data_in_T2 : IN
DQ : inout STD_LOGIC Binary_To_BCD_16b std_logic_vector(13 downto 0);
); PORT(
end TOPCZECH; ENTERO : IN sendRequest_H2 : IN
std_logic_vector(15 downto 0); std_logic;
architecture Behavioral of POINT : IN data_in_H2 : IN
TOPCZECH is std_logic_vector(3 downto 0); std_logic_vector(12 downto 0);
BCD : OUT enable_LED :
std_logic_vector(18 downto 0); OUT std_logic;
COMPONENT DS18B20 BCDPOINT : serialDataOut :
PORT( OUT std_logic_vector(7 downto 0) OUT std_logic
clk1m : IN ); );
std_logic; END COMPONENT; END COMPONENT;
ds_data_bus :
INOUT std_logic; COMPONENT X7seg SIGNAL CLK1MHZ : STD_LOGIC;
crc_en : OUT PORT( SIGNAL DOK : STD_LOGIC;
std_logic; x : IN signal REQUEST : STD_LOGIC;
dataOut : OUT std_logic_vector(15 downto 0); SIGNAL DATA :
std_logic_vector(71 downto 0) clk : IN STD_LOGIC_VECTOR(71 downto
); std_logic; 0);
END COMPONENT; clr : IN SIGNAL DATA16 :
std_logic; STD_LOGIC_VECTOR(15 downto
COMPONENT an : OUT 0);
divider1MHz std_logic_vector(3 downto 0); SIGNAL DATA12 :
PORT( a_to_g : OUT STD_LOGIC_VECTOR(15 downto
clk_in : IN std_logic_vector(6 downto 0) 0);
std_logic; ); SIGNAL DATA4 :
clk_out : OUT END COMPONENT; STD_LOGIC_VECTOR(3 downto 0);
std_logic SIGNAL Y :
STD_LOGIC_VECTOR(18 downto enable_LED =>
0); U3: CRC PORT MAP( LED(6),
SIGNAL X : clk =>
STD_LOGIC_VECTOR(15 downto CLK1MHZ, sendRequest_T1
0); data_en => =>SW(0),
SIGNAL W : DOK, data_in_T1 =>
STD_LOGIC_VECTOR(7 downto 0); dataIn => DATA16(13 DOWNTO 0),
DATA,
dataOut => sendRequest_H1 =>
DATA16, SW(1),
dataValid data_in_H1 =>
=>REQUEST DATA16(12 DOWNTO 0),
begin );
sendRequest_T2 =>
DATA12 <= "0000" & DATA16(15 U4: Binary_To_BCD_16b SW(2),
DOWNTO 4 ); PORT MAP( data_in_T2 =>
DATA4 <= DATA16(3 DOWNTO 0 ENTERO => DATA16(13 DOWNTO 0),
); DATA12,
POINT => sendRequest_H2 =>
DATA4, SW(3),
U1: DS18B20 PORT BCD => Y, data_in_H2 =>
MAP( BCDPOINT => DATA16(12 DOWNTO 0),
clk1m => W serialDataOut
CLK1MHZ, ); => TX
crc_en => DOK, );
dataOut => U5: X7seg PORT MAP(
DATA, x => X,
ds_data_bus => clk => MHZ50,
DQ clr => R, X( 3 downto 0 ) <= W( 3 downto
); an => an, 0 );
a_to_g =>a_to_g X( 7 downto 4 ) <= W( 7 downto
U2: divider1MHz PORT ); 4 );
MAP( X( 11 downto 8) <= Y(3 downto 0
clk_in => U6: transmitter PORT );
MHZ50, MAP( X( 15 downto 12) <= Y(7 downto
clk_out => clk => MHZ50, 4 );
CLK1MHZ enable =>
); SW(0), end Behavioral;
-- write_command
reset citace <="11001100"; --
prechod do stavu WAIT_800ms,
cekani na ukonceni prikazu 44h
dataOut <= -- prikaz CCh - SKIP ROM
PRESENCE_ERROR_DATA; elsif (flag = 3)
state then
<=
-- nastaveni dat WRITE_BYTE;
indikujicich chybu na vystup --
treti prikaz
-- prechod do stavu
crc_en <= '1'; WRITE BYTE flag :=
4;
elsif (flag = 1)
then
-- write_command
zahajeni vypoctu CRC <="11001100";
--
state druhy prikaz
<= -- prikaz CCh - SKIP ROM
WAIT_800ms; flag :=
2; state
<=
-- WRITE_BYTE;
prechod do stavu WAIT_800ms write_command
<="01000100";
end if; -- prechod do stavu
WRITE BYTE
-- prikaz 44h - CONVERT
when SEND => TEMPERATURE elsif (flag = 4)
then
state
<=
-- pro precteni pameti scratchpad
ctvrty prikaz -- stav cekani
po dobu 800 ms case
flag := GET_DATA_CNT is
5; CRC_en <= '0';
write_command -- pozice ve
<="10111110"; stavu GET_DATA
--
reset priznaku pro zahajeni when
-- prikaz BEh - READ vypoctu CRC 0 to 71=>
SCRATCHPAD
S_reset <= '0';
state
<= --
WRITE_BYTE; cteni jednotlivych bitu pameti
scratchpad
-- spusteni
-- prechod do stavu citace
WRITE BYTE ds_data_bus <= '0';
if (i = 799999)
elsif (flag = 5) then
then
-- zahajeni
cteni na sbernici
-- -- konec periody citace
ukonceni vysilani prikazu
GET_DATA_CNT <=
flag := S_reset <='1'; GET_DATA_CNT + 1;
0;
--
inkrementace citace pro prave
cteny bit
-- -- resetovani citace
reset priznaku pro odesilany
prikaz state state <=
<= RESET; READ_BIT;
state
<= GET_DATA;
-- prechod do stavu
-- READ_BIT
navrat do stavu RESET
-- prechod do stavu when
GET_DATA end if; 72=>
end if;
when GET_DATA =>
--
when WAIT_800ms => pamet prectena (72 bitu)
-- stav bit_cnt := 0;
GET_DATA_CNT <= 0;
if (i = 13) then
dataOut <= data(71 -- stav
downto 0); pro cteni bitu
-- reset citace
-- spusteni
vypoctu CRC prectenych dat -- pozice ve stavu
READ_BIT read_bit_flag
<= 2;
state <= when
WAIT_800ms; 0=>
end if;
--
navrat do stavu WAIT_800ms when
2=>
when -- vyslani zacatku
others => casoveho slotu pro cteni
-- ulozeni
vzorku dat do registru
-- reset pozice ve stavu
READ_BIT
ds_data_bus <= 'Z'; bit_cnt := bit_cnt + 1;
-- navrat do stavu
GET_DATA -- stav pro
-- zvyseni citace pro zapis bajtu dat na sbernici
prave cteny bit
end if; -- sekvence
zapisu bajtu dat rizena citacem
read_bit_flag <= 3; when WRITE_BYTE_CNT
others =>
when case
3=> WRITE_BYTE_CNT is
-- chyba ve
stavu READ_BIT
-- pozice ve
-- dokonceni casoveho stavu WRITE_BYTE
slotu read_bit_flag <= 0;
when
0 to 7=>
S_reset <= '0';
-- reset pozice ve stavu
READ_BIT
-- odesilani
-- zapnuti bitu 0-7
citace bit_cnt := 0;
if
if (i = 63) then (write_command(WRITE_BYTE_C
-- reset citace NT) = '0') then --
pro prave cteny bit odesilany bit ma hodnotu log. 0
-- cekani 62 us
GET_DATA_CNT <= 0; state <=
WRITE_LOW;
S_reset<='1';
state <=
state when WRITE_BYTE => WRITE_HIGH;
<= GET_DATA;
-- prechod do
stavu WRITE_HIGH -- vyslani zacatku
write_low_flag <= 0; casoveho slotu pro zapis log. 0
end if;
ds_data_bus <= '0';
-- reset pozice ve stavu
WRITE_BYTE_CNT <= WRITE_LOW
WRITE_BYTE_CNT + 1;
-- zacatek casoveho slotu
-- inkrementace citace write_high_flag <= 0;
odesilaneho bitu
S_reset <= '0';
when
8=> -- reset pozice ve stavu
WRITE_HIGH
-- zapnuti
citace
state <=
-- odesilani bajtu RESET;
dokonceno if (i = 59) then
--
reset senzoru
WRITE_BYTE_CNT <= 0;
end -- cekani 60 us
case;
-- chyba ve
stavu WRITE_BYTE
-- pozice ve stavu
WRITE_LOW -- uvolneni sbernice pro
WRITE_BYTE_CNT <= 0; ukonceni casoveho slotu
when
0=>
ds_data_bus <= 'Z';
-- reset citace
odesilaneho bitu
-- uvolneni sbernice navrat do stavu WRITE_BYTE -- pozice ve stavu
WRITE_HIGH
when
S_reset <= '0'; others=> when
0=>
end if; --
reset senzoru
when -- cekani 10 us
2=> end case;
S_reset
when WRITE_HIGH => <= '1';
case when
state <= write_high_flag is 1=>
WRITE_BYTE;
--
-- reset pozice ve stavu RESET;
-- uvolneni sbernice pro WRITE_HIGH
ukonceni casoveho slotu
state -- reset
ds_data_bus <= 'Z'; <= WRITE_BYTE; senzoru
--
navrat do stavu WRITE BYTE end
-- uvolneni sbernice case;
when end if;
others => end process;
S_reset <= '0';
-- Proces citace se
synchronnim resetem
-- process(clk1m, S_reset)
-- zapnuti chyba zapisu log. 1
citace begin
if
WRITE_BYTE_CNT <= 0; (rising_edge(clk1m)) then
if (i = 53) then if
(S_reset = '1')then --
reset citace
-- reset citace
-- cekani 54 us odesilaneho bitu i <= 0;
-- vynulovani citace
S_reset write_high_flag <= 0; else
<= '1';
i <= i + 1;
--
-- reset citace -- reset pozice ve stavu inkrementace citace
WRITE_HIGH end if;
end if;
write_high_flag end process;
<= 2; state <=
RESET; end Behavioral;
dataOut <=
CRC_temp(2):= crc_state <= PRESENCE_ERROR_C;
CRC_val(3) XOR (dataIn(i) XOR CRC_CHECK; -- senzor neni
CRC_val(0)); pripojen, vystup nastaven na
-- prechod do stavu chybovou hodnotu
CRC_check
CRC_temp(3):= end if;
CRC_val(4) XOR (dataIn(i) XOR end if;
CRC_val(0)); end if;
i
CRC_val(3) := dataOut <= dataIn(15 := 0;
CRC_temp(3); downto 0);
-- data prijata spravne,
vystup nastaven na data -- reset prave
CRC_val(4) := obsahujici namerenou teplotu zpracovavaneho bitu dat
CRC_val(5);
else dataValid <=
'1'; crc_state <= case;
IDLE; end if;
-- end process;
indikace dokonceni vypoctu CRC -- navrat do
stavu IDLE end Behavioral;
end
parallelDataOut <=
stringToSend_H1 := stringToSend_H2 := std_logic_vector(to_unsigned(char
convertToChar(dataToSend_H1(7 "ER_H2" & ';'; acter'pos(charToSend), 8));
downto 4)) &
convertToChar(dataToSend_H1(3 end if;
downto 0)) & "% " & ';'; char_send_cnt :=
char_send_cnt + 1; --
else -- -- inkrementace odesilaneho bitu
chyba obdrzenych dat vytvoreni kompletniho
odesilaneho stringu
ctrl_state
stringToSend_H1 := <=
"ER_H1" & ';'; stringToSend := SEND_CHAR;
stringToSend_T1 & -- prechod do
end if; stringToSend_H1 & stavu SEND_CHAR
stringToSend_T2 &
stringToSend_H2 & CR & LF; -- else
zapis kompletni sekvence dat k
-- odeslani dat
vytvoreni stringu obsahujici data transmitRequest <= '0';
ze senzoru vlhkosti DHT22
ctrl_state <=
if PREPARE_CHAR; -- prechod do -- ukonceni odesilani dat
(dataToSend_H2(12) = '1') then -- stavu PREPARE_CHAR po odeslani 26 znaku
data obsahuji cislo chyby
when ctrl_state
stringToSend_H2 := "E " PREPARE_CHAR => <= IDLE;
&
convertToChar(dataToSend_H2(1 -- stav pro -- prechod do stavu IDLE
1 downto 8)) & pripravu seriovych dat
convertToChar(dataToSend_H2(7 end if;
downto 4)) &
convertToChar(dataToSend_H2(3 transmitRequest <= '0';
downto 0)) & ';'; when
-- zruseni pozadavku na SEND_CHAR =>
elsif odesilani znaku
(dataToSend_H2(12) = '0') then --
data obsahuji hodnotu namerene if -- stav
vlhkosti (char_send_cnt < 26) then pro odesilani bajtu dat
-- pocitani odeslanych
znaku if
stringToSend_H2 := (txIsReady = '1') then
convertToChar(dataToSend_H2(1
1 downto 8)) & charToSend := --
convertToChar(dataToSend_H2(7 stringToSend(char_send_cnt+1); - cekani na submodul UART
downto 4)) & '.' - vyber odesilaneho znaku
&convertToChar(dataToSend_H2(
3 downto 0)) & "%" & ';'; transmitRequest <= '1';
(sendRequest_T1 = '1') then
-- prichod dat ze senzoru -- Proces pro cekani na
-- pozadavek na odeslani teploty DS18B20 data ze senzoru ADT7420
bajtu dat process(clk)
dataToSend_T1 <= begin
data_in_T1; -- if
ctrl_state odebrani vzorku dat ze senzoru (rising_edge(clk)) then
<= teploty DS18B20 if
PREPARE_CHAR; (sendRequest_T2 = '1') then
-- navrat k dalsimu dataReady_T1 <= '1'; -- prichod dat ze senzoru
odesilani ve stavu teploty ADT7420
PREPARE_CHAR -- nastaveni priznaku
prichodu dat dataToSend_T2 <=
end if; else data_in_T2; --
odebrani vzorku dat ze senzoru
end case; if ctrl_state = teploty ADT7420
end if; PREPARE_SEQUENCE then
end if; dataReady_T2 <= '1';
end process; dataReady_T1
<= '0'; -- nastaveni priznaku
-- Proces pro cekani na -- zruseni prichodu dat
data ze senzoru DS18B20 priznaku prichodu dat else
process(clk)
begin end if; if ctrl_state =
if end if; PREPARE_SEQUENCE then
(rising_edge(clk)) then end if;
if end process;
dataReady_T2 <= '0'; -- zruseni priznaku
prichodu dat -- nastaveni priznaku -- prichod dat
prichodu dat ze senzoru vlhkosti DHT22
end if; else
end if; dataToSend_H2 <=
end if; if ctrl_state = data_in_H2; --
end process; PREPARE_SEQUENCE then odebrani vzorku dat ze senzoru
vlhkosti DHT22
-- Proces pro cekani na dataReady_H1
data ze senzoru DHT11 <= '0'; dataReady_H2 <= '1';
process(clk) -- zruseni
begin priznaku prichodu dat -- nastaveni priznaku
if prichodu dat
(rising_edge(clk)) then end if; else
if end if;
(sendRequest_H1 = '1') then end if; if ctrl_state =
-- prichod dat end process; PREPARE_SEQUENCE then
ze senzoru vlhkosti DHT11
-- Proces pro dataReady_H2
dataToSend_H1 <= cekani na data ze senzoru DHT22 <= '0';
data_in_H1; -- process(clk) -- zruseni
odebrani vzorku dat ze senzoru begin priznaku prichodu dat
vlhkosti DHT11 if
(rising_edge(clk)) then end if;
dataReady_H1 <= '1'; if end if;
(sendRequest_H2 = '1') then end if;
end process; STD_LOGIC;
enable enable
enable_LED <= '1' when : =>
enable = '1' else '0'; IN STD_LOGIC; enable,
-- clockCount :=
zastaveni generatoru clockCount + 1; -- reset citace
txIsReady
-- <= '1';
nastaveni seriove linky do when
vychoziho stavu -- submodul SEND_START_BIT =>
else pripraven k odeslani dalsich dat
-- stav
if (transmitRequest = pro odeslani start bitu
'1') then serialDataOut <= '1';
--
prichod pozadavku k odesilani -- serialDataOut <= '0';
nastaveni seriove linky do
go := '1'; vychoziho stavu --
zacatek start bitu
-- go
navzorkovani prichozich dat := '0';
txIsReady -- when
<= '0'; zruseni priznaku k zahajeni SEND_DATA_BITS =>
odesilani
-- stav
-- indikace k pro odesilani dat
nepripravenosti k dalsimu bitToSend
odesilani := 0;
serialDataOut <=
end if; -- reset citace dataToTx(bitToSend); --
pro odesilany bit nastaveni seriove linky podle
if (baudRateEnable = '1') jednotlivych bitu dat
then
-- txIsReady
prichod taktu pro rychlost <= '0'; if (bitToSend = 7) then
odesilani 115 200 Bd
-- submodul prave --
case(txState) is odesila data odeslan posledni bit dat
library IEEE;
use IEEE.STD_LOGIC_1164.ALL; sendRequest_H2 : IN -- viz transmitControler.vhd
STD_LOGIC; component transmitControler
entity transmitter is port ( clk
Port ( clk data_in_H2 : IN : IN
: IN STD_LOGIC_VECTOR(12 STD_LOGIC;
STD_LOGIC; DOWNTO 0);
enable : IN
enable STD_LOGIC;
: IN STD_LOGIC; serialDataOut : OUT
STD_LOGIC enable_LED : OUT
enable_LED : OUT ); STD_LOGIC;
STD_LOGIC; end transmitter; sendRequest_T1 : IN
STD_LOGIC;
sendRequest_T1 : IN architecture Structure of data_in_T1 : IN
STD_LOGIC; transmitter is STD_LOGIC_VECTOR (13 downto
0);
data_in_T1 : IN -- viz UART.vhd
STD_LOGIC_VECTOR(13 component UART sendRequest_T2 : IN
DOWNTO 0); port ( clk STD_LOGIC;
: IN data_in_T2 : IN
sendRequest_H1 : IN STD_LOGIC; STD_LOGIC_VECTOR (13 downto
STD_LOGIC; enable 0);
: IN STD_LOGIC;
data_in_H1 : IN serialDataOut : OUT sendRequest_H1 : IN
STD_LOGIC_VECTOR(12 STD_LOGIC; STD_LOGIC;
DOWNTO 0); parallelDataIn : IN data_in_H1 : IN
STD_LOGIC_VECTOR (7 STD_LOGIC_VECTOR (12 downto
sendRequest_T2 : IN downto 0); 0);
STD_LOGIC; transmitRequest : IN
STD_LOGIC; sendRequest_H2 : IN
data_in_T2 : IN txIsReady : OUT STD_LOGIC;
STD_LOGIC_VECTOR(13 STD_LOGIC); data_in_H2 : IN
DOWNTO 0); end component UART; STD_LOGIC_VECTOR (12 downto
0); =>
parallelDataOut : OUT enable,
STD_LOGIC_VECTOR (7 downto transmitRequest =>
0); transmitRequest, enable_LED
transmitRequest : OUT =>
STD_LOGIC; txIsready enable_LED,
txIsReady : IN =>
STD_LOGIC); txIsReady data_in_T1
end component ); =>
transmitControler; data_in_T1,
RTL Diagram
Technology Map Viewer
Conclusion
In this project we have implemented 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.
References
1.“Removal of Impulse Noise Using Switching Median Filter by designing its Reconfigurable
Architecture” – Manali Mukherjee, Mausumi Maitra, Kamarujjaman - International Conference
on Communication and Computing ICC–2014, Bangalore, June 12-14, 2014 (Elsevier Science
and Technology Publication).
2. A New Decision-Based Adaptive Filter for Removal of High Density Impulse Noise from
Digital Images - Kamarujjaman, Manali Mukherjee and Mausumi Maitra, ICDCCOM - 2014,
September 12-13, 2014, BIT Mesra (IEEE Explorer publication)
3. An Efficient Approach for Suppression of Impulse Noise from Digital Images using Decision-
Based Adaptive filter- Kamarujjaman Sk, Manali Mukherjee and Mausumi Maitra, Accepted in
ICECE-14, BUET, Bangladesh, to be held during December, 2014 (not presented due to lack of
fund).
4.Reconfigurable Architecture of Adaptive Median Filter – A FPGA Based Approach for Impulse
Noise Suppression – Manali Mukherjee, Kamarujjaman, Mausumi Maitra was published by
IEEE Xplore. Presented in 3rd International Conference on Computer, Communication, Control
and Information Technology (C3IT), 2015, was held in Academy of Technology, Adisaptagram,
during 7th – 8th February, 2015.
5.Kamarujjaman, Manali Mukherjee and Mausumi Maitra, “An efficient FPGA based de-noising
architecture for removal of high density impulse noise in images”, IEEE International
Conference on Research in Computational Intelligence and Communication Networks
(ICRCICN), RCCIIT, Kolkata, Sept., 2015.