library IEEE; use IEEE.std_logic_1164.all; use ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; -- $Id$: -- PASA ADCs old design: ADS5221 -- new design: AD9235 -- and mux 0x5800 0x5FFF -- -- Offset -- 0 ..511 r 32 bit '0' & ASEL & OVR & sample(2*i+1) & '0' & ASEL & OVR & sample(2*i) -- sample is 12 bit -- ASEL see below -- OVR is overrange -- -- 1024 w/r configuration reg -- Bit 1..0 - ASEL -- 3 PASA channel 1 -- 2 PASA channel 17 -- 1 PASA channel 18 -- 0 DDS channel 1 -- Bit 2 - enable duty cycle adjust (see ADS5221 datasheet) -- Bit 3 - standard power down in idle mode of the state machine -- Bit 4 - when 0 disconnect the analog mux, useful to measure the offset -- Bit 5 - invert the clock output -- Bit 6 - enable pretrigger start -- w Bit 7 - when 1 - start entity pasaadc is generic(TesterNum : Positive := 4); -- 1,2,3 are old design, 4,5.. are new design PORT ( CLK : in std_logic; -- Clock, 30 or 40 MHz RESET_n : in std_logic; -- reset start : in std_logic; -- to the internal bus CE : in std_logic; WE : in std_logic; ADDR : in std_logic_vector(10 downto 0); WDATA : in std_logic_vector(23 downto 0); RDATA : out std_logic_vector(31 downto 0); -- to the ADC PAADC_D : in std_logic_vector(11 downto 0); PAADC_OVR : in std_logic; PAADC_CLK : out std_logic; PAADC_Msel : out std_logic; -- Duty cycle adjust PAADC_STDP : out std_logic; -- Standard power down enable PAADC_MuxnRS : out std_logic; -- disable the mux, the outputs are offen PAADC_MuxA : out std_logic_vector(1 downto 0) ); end pasaadc; architecture a of pasaadc is component pasaadc_ram PORT ( data : IN STD_LOGIC_VECTOR (15 DOWNTO 0); wren : IN STD_LOGIC := '1'; wraddress : IN STD_LOGIC_VECTOR ( 9 DOWNTO 0); rdaddress : IN STD_LOGIC_VECTOR ( 8 DOWNTO 0); wrclock : IN STD_LOGIC ; rdclock : IN STD_LOGIC ; q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) ); end component; type sm_type is (idle, run); signal sm : sm_type; signal samples : std_logic_vector( 9 downto 0); signal samples_last : std_logic_vector( 9 downto 0); signal rdata_ram : std_logic_vector(31 downto 0); signal wdata_ram : std_logic_vector(15 downto 0); signal adc_data : std_logic_vector(12 downto 0); signal cfr : std_logic_vector( 6 downto 0); signal wren_cfr : std_logic; signal start_s : std_logic; signal io_start : std_logic; signal sampl_end : std_logic; signal sample_en : std_logic; signal PAADC_D_i : std_logic_vector(PAADC_D'range); begin PAADC_STDP <= cfr(3) when sm=idle else '0'; -- Standard power down in idle mode PAADC_MuxA <= cfr(1 downto 0); -- mux select -- NEW PCB design newd: if TesterNum > 3 generate PAADC_Msel <= '0'; swap: for i in PAADC_D'range generate PAADC_D_i(i) <= PAADC_D(PAADC_D'high - i); -- swap the pins end generate; PAADC_MuxnRS <= not cfr(4); -- disable the mux end generate; -- OLD PCB design oldd: if TesterNum < 4 generate PAADC_Msel <= cfr(2); -- enable Duty cycle adjust PAADC_MuxnRS <= cfr(4); -- disable the mux PAADC_D_i <= PAADC_D; end generate; samples_last <= (others => '1'); PAADC_CLK <= clk xor cfr(5); -- invert the ADC clock wdata_ram <= '0' & cfr(1 downto 0) & adc_data; wren_cfr <= CE and WE and ADDR(ADDR'high); process(clk, reset_n) begin if reset_n = '0' then cfr <= (cfr'high => '1', others =>'0'); io_start <= '0'; elsif clk'event and clk= '1' then io_start <= '0'; if wren_cfr = '1' then cfr <= WDATA(cfr'range); io_start <= WDATA(cfr'high+1); end if; end if; end process; adcram: pasaadc_ram PORT map ( data => wdata_ram, wren => sample_en, wraddress => samples, rdaddress => ADDR( 8 DOWNTO 0), wrclock => clk, -- may be later will be different rdclock => clk, q => rdata_ram ); sampl_end <= '1' when samples = samples_last else '0'; process(clk, reset_n) begin if reset_n = '0' then sm <= idle; elsif clk'event and clk='1' then -- state machine case sm is when idle => if start_s = '1' then sm <= run; end if; when run => if sampl_end = '1' then sm <= idle; end if; when others => sm <= idle; end case; end if; end process; sample_en <= '1' when sm=run else '0'; process(clk) begin if clk'event and clk='1' then start_s <= (start and cfr(6)) or io_start; adc_data <= PAADC_OVR & PAADC_D_i; -- write address if sm = idle then samples <= (others => '0'); else samples <= samples + 1; end if; end if; end process; -- read mux omx: process(addr, cfr, rdata_ram) begin RDATA <= (others => '0'); if ADDR(ADDR'high)='0' then -- RAM RDATA(rdata_ram'range) <= rdata_ram; else RDATA(cfr'range) <= cfr; end if; end process; end;