--------------------------------------------------------------- -- Analog-To-Digital Converter -- Functional Simulation Model -- -- GoodKook@hitel.kol.co.kr -- goodkook@vlsi.kyunghee.ac.kr -- -- Digital Interface works similar to ADC0808 -- Conversion colck : 40ns -- Conversion time : 500ns -- 8ch analog input range 0~5v, 8-bits -- -- 1clk -- |<->| -- +---+ -- | | -- ALE ---+ +------------------- -- +---+ -- | | -- START -----+ +--------------------------- -- |<--------- Tcnv=500ns ------>| -- |<-Teoc->| | -- EOC --------------+ +----------- -- | | -- +----------//--------+ -- |<-2clk->| -- ---------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity ADC_8_bit is port ( analog_in0 : in real; analog_in1 : in real; analog_in2 : in real; analog_in3 : in real; analog_in4 : in real; analog_in5 : in real; analog_in6 : in real; analog_in7 : in real; adc_adr : in std_logic_vector(2 downto 0); adc_ale : in std_logic := '0'; adc_start : in std_logic := '0'; adc_eoc : out std_logic := '1'; adc_oe : in std_logic := '0'; digital_out : out std_logic_vector(7 downto 0) ); end ADC_8_bit; architecture original of ADC_8_bit is type byte is array (7 downto 0) of std_logic; constant conversion_time : time := 500 ns; constant conversion_clock : time := 40 ns; signal instantly_digitized_signal : std_logic_vector(7 downto 0); signal delayed_digitized_signal : std_logic_vector(7 downto 0); signal address : std_logic_vector(2 downto 0); signal analog_value : real; signal sadc_eoc : std_logic := '1'; ------------------------------------------------------------------- -- Convert unsigned integer to "width"-bits Std_Logic_vector ------------------------------------------------------------------- function to_std_logic_vector ( a : integer; width : integer ) return std_logic_vector is constant y_length : integer := width; constant a_threshold : integer := 2 ** (width-1); variable y_ref : integer; variable y : integer; variable y_std_logic_vector : std_logic_vector(y_length-1 downto 0); begin y := a; if (a >= 0) then y_ref := a_threshold; for i in y_length-1 downto 0 loop if (y < y_ref) then y_std_logic_vector(i) := '0'; else y := y - y_ref; y_std_logic_vector(i) := '1'; end if; y_ref := y_ref / 2; end loop; else for i in y_length-1 downto 0 loop y_std_logic_vector(i) := '0'; end loop; end if; return y_std_logic_vector; end to_std_logic_vector; -------------------------------------------------------------------- -- 8-Bit ADC -- -- ADC Analog Input : 0.0~5.0 Real (max_analog_value = 5.0) -- ADC digital_out : 8-bits (max_digital_value=256) -- -- ADC is simple arithmetic! -- max_digital_value -- digital_out = analog_in * ------------------ -- max_analog_value -- ------------------------------------------------------------------------ function ADC_8b_10v_bipolar ( analog_in : in real ) return byte is constant max_digital_value : integer := 256; constant max_analog_value : real := 5.0; variable digitized_signal : integer; variable digital_out : byte; begin if (analog_in < 0.0) then digitized_signal := 0; else digitized_signal := integer(analog_in * ( real(max_digital_value) / max_analog_value) ); if (digitized_signal > (max_digital_value - 1)) then digitized_signal := max_digital_value - 1; end if; end if; digital_out := byte(to_std_logic_vector(digitized_signal,8)); return digital_out; end ADC_8b_10v_bipolar; begin uADR_LATCH : PROCESS(adc_ale) BEGIN IF adc_ale'EVENT AND adc_ale='1' THEN address <= adc_adr; END IF; END PROCESS; analog_value <= analog_in0 WHEN address="000" ELSE analog_in1 WHEN address="001" ELSE analog_in2 WHEN address="010" ELSE analog_in3 WHEN address="011" ELSE analog_in4 WHEN address="100" ELSE analog_in5 WHEN address="101" ELSE analog_in6 WHEN address="110" ELSE analog_in7; instantly_digitized_signal <= std_logic_vector (ADC_8b_10v_bipolar (analog_value)); uADC_START : PROCESS(adc_start) BEGIN IF adc_start'EVENT AND adc_start='1' THEN sadc_eoc <= '0' after conversion_clock * 2, '1' after (conversion_time + conversion_clock); END IF; END PROCESS; uADC_OUT : PROCESS(adc_start) BEGIN IF adc_start'EVENT AND adc_start='0' THEN delayed_digitized_signal <= instantly_digitized_signal after conversion_time; END IF; END PROCESS; digital_out <= delayed_digitized_signal WHEN adc_oe='1' ELSE (OTHERS=>'Z'); adc_eoc <= sadc_eoc; end original;