UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
9,135 Views
Registered: ‎11-26-2009

adc dca Spartan3e

Jump to solution

Hallo,

I try to play a little bit with ad and da converters on my Spartan 3e board. I found some projects which use picoblaze to ensure communication between adc dac and fpga. Now I would like to implement it without using picoblaze (just for practice). I wrote a programm but it does not work in propper way. Below I pasted my code and screen from oscilloscope with input signal (sin wave to channel A adc) and output (from channel A dac). I gues that problem is in differences of bit representations in adc (14-bit twos complement signed) and dac (unsigned digital value).I would be very grateful for a help.


 

-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;

use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.all;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity control is
    Port ( rst : in  STD_LOGIC;
           clk : in  STD_LOGIC;
--           switch0 : in  STD_LOGIC;
           rot_a : in  STD_LOGIC;
           rot_b : in  STD_LOGIC;
           sdo : in  STD_LOGIC;
           sdi : out  STD_LOGIC;
           sck : out  STD_LOGIC;
           amp_cs : out  STD_LOGIC;
           amp_shdn : out  STD_LOGIC;
              ad_conv : out std_logic;
              da_cs : out std_logic;
              da_clr : out std_logic;
           strataflash_we : out  STD_LOGIC;
           strataflash_oe : out  STD_LOGIC;
           strataflash_ce : out  STD_LOGIC;
              platformflash_oe : out std_logic;
           simple_io : out  STD_LOGIC_VECTOR (3 downto 0);
           led : out  STD_LOGIC_VECTOR (7 downto 0));
end control;

architecture Behavioral of control is

    signal state_reg, state_next : std_logic_vector (1 downto 0) := "00";
    constant amp_state : std_logic_vector (1 downto 0) := "00";
    constant ad_state : std_logic_vector (1 downto 0) := "01";
    constant fir_state : std_logic_vector (1 downto 0) := "10";
    constant da_state : std_logic_vector (1 downto 0) := "11";
    signal sck_reg, sck_next, sdi_reg, sdi_next : std_logic := '0';

    --rotary filter
    signal rotary_in : std_logic_vector (1 downto 0) := "00";
    signal rotary_q1 : std_logic := '0';
    signal rotary_q2 : std_logic := '0';
    signal delay_rotary_q1 : std_logic := '0';
    signal rotary_event : std_logic := '0';
    signal rotary_left : std_logic := '0';
    signal led_pattern_reg, led_pattern_next : std_logic_vector (7 downto 0) := "00010001";
    --amp
    signal amp_state_reg, amp_state_next : std_logic_vector (2 downto 0) := "000";
    constant amp_idle : std_logic_vector  (2 downto 0) := "000";
    constant amp_wait1 : std_logic_vector (2 downto 0) := "001";
    constant amp_sck1 : std_logic_vector (2 downto 0) := "010";
    constant amp_wait2 : std_logic_vector (2 downto 0) := "011";
    constant amp_end : std_logic_vector (2 downto 0) := "100";
    signal amp_data_reg, amp_data_next : std_logic_vector (7 downto 0) := "00010001";
    signal amp_cs_reg, amp_cs_next : std_logic := '1';
    signal amp_bit_reg, amp_bit_next : natural range 0 to 8 := 8;
    --ad
    signal ad_state_reg, ad_state_next : std_logic_vector (3 downto 0) := "0000";
    constant ad_idle : std_logic_vector (3 downto 0) := "0000";
    constant ad_conv0 : std_logic_vector (3 downto 0) := "0001";
    constant ad_sck1 : std_logic_vector (3 downto 0) := "0010";
    constant ad_sck0 : std_logic_vector (3 downto 0) := "0011";
    constant ad_cnt_update : std_logic_vector (3 downto 0) := "0100";
    constant ad_loop : std_logic_vector (3 downto 0) := "0101";
    constant ad_data_adjust1 : std_logic_vector (3 downto 0) := "0110";
    constant ad_data_adjust2 : std_logic_vector (3 downto 0) := "0111";
    constant ad_end : std_logic_vector (3 downto 0) := "1000";
    signal ad_conv_reg, ad_conv_next : std_logic := '0';
    signal ad_bit_reg, ad_bit_next : natural range 0 to 34 := 34;
    signal ad_data_reg, ad_data_next : std_logic_vector (33 downto 0) := (others => '0');
    signal ad_channel1_reg, ad_channel1_next : std_logic_vector (13 downto 0) := (others => '0');
    --da
    signal da_state_reg, da_state_next : std_logic_vector (2 downto 0) := (others => '0');
    constant da_idle : std_logic_vector (2 downto 0) := "000";
    constant da_send : std_logic_vector (2 downto 0) := "001";
    constant da_sck1 : std_logic_vector (2 downto 0) := "010";
    constant da_loop : std_logic_vector (2 downto 0) := "011";
    constant da_end : std_logic_vector (2 downto 0) := "100";
    constant vref : unsigned (13 downto 0) := "00001000000000";
    signal da_cs_reg, da_cs_next : std_logic := '1';
    signal da_bit_reg, da_bit_next : natural range 0 to 32 := 32;
    signal da_data_reg, da_data_next : std_logic_vector (31 downto 0) := (others => '0');
    --fir
    signal fir_state_reg, fir_state_next : std_logic_vector (1 downto 0) := "00";
    constant fir0 : std_logic_vector (1 downto 0) := "00";
    constant fir1 : std_logic_vector (1 downto 0) := "01";
begin
   
    process(clk, rst)
        begin
            if rst = '1' then
                state_reg <= amp_state;
            elsif clk'event and clk = '1' then
                state_reg <= state_next;
            end if;
    end process;
                                       
rotary_filter: process(clk)
    begin   
        if clk'event and clk = '1' then
                rotary_in <= ROT_B & ROT_A;
                case rotary_in is
                    when "00" => rotary_q1 <= '0';
                                     rotary_q2 <= rotary_q2;
                    when "01" => rotary_q1 <= rotary_q1;
                                     rotary_q2 <= '0';
                    when "10" => rotary_q1 <= rotary_q1;
                                     rotary_q2 <= '1';
                    when "11" => rotary_q1 <= '1';
                                     rotary_q2 <= rotary_q2;
                    when others => rotary_q1 <= rotary_q1;
                                        rotary_q2 <= rotary_q2;
                end case;
        end if;
    end process rotary_filter;

direction: process(clk)
    begin
        if clk'event and clk = '1' then
            delay_rotary_q1 <= rotary_q1;
            if rotary_q1 = '1' and delay_rotary_q1 = '0' then
                rotary_event <= '1';
                rotary_left <= rotary_q2;
            else
                rotary_event <= '0';
                rotary_left <= rotary_left;
            end if;
        end if;
    end process direction;
   
    process(rst, clk)
        begin
            if rst = '1' then
                led_pattern_reg <= "00010001";
            elsif clk'event and clk = '1' then
                led_pattern_reg <= led_pattern_next;
            end if;
    end process;
    led_pattern_next <= (led_pattern_reg(7 downto 4) + 1) & (led_pattern_reg(3 downto 0) + 1) when (led_pattern_reg < "01110111" and rotary_event = '1' and rotary_left = '1') else
                              (led_pattern_reg(7 downto 4) - 1) & (led_pattern_reg(3 downto 0) - 1) when (led_pattern_reg > "00010001" and rotary_event = '1' and rotary_left = '0') else
                              led_pattern_reg;
    led <= led_pattern_reg;
    --main case
    process(clk, rst)
        begin
            if rst = '1' then
                sck_reg <= '0';
                sdi_reg <= '0';
            elsif clk'event and clk = '1' then
                sck_reg <= sck_next;
                sdi_reg <= sdi_next;               
            end if;
    end process;
    --amp ff
    process(clk, rst)
        begin
            if rst = '1' then
                amp_state_reg <= amp_idle;
                amp_data_reg <= (others => '0');
                amp_cs_reg <= '1';
                amp_bit_reg <= 8;
            elsif clk'event and clk = '1' then
                amp_state_reg <= amp_state_next;
                amp_data_reg <= amp_data_next;
                amp_cs_reg <= amp_cs_next;               
                amp_bit_reg <= amp_bit_next;
            end if;
    end process;
    --ad ff
    process(clk, rst)
        begin
            if rst = '1' then
                ad_state_reg <= ad_idle;
                ad_conv_reg <= '0';
                ad_bit_reg <= 34;
                ad_data_reg <= (others => '0');
                ad_channel1_reg <= (others => '0');
            elsif clk'event and clk = '1' then
                ad_state_reg <= ad_state_next;
                ad_conv_reg <= ad_conv_next;
                ad_bit_reg <= ad_bit_next;
                ad_data_reg <= ad_data_next;
                ad_channel1_reg <= ad_channel1_next;
            end if;
    end process;
    --da ff
    process(clk, rst)
        begin
            if rst = '1' then
                da_state_reg <= da_idle;
                da_cs_reg <= '1';
                da_bit_reg <= 32;
                da_data_reg <= (others => '0');
                fir_state_reg <= fir0;
            elsif clk ' event and clk = '1' then
                da_state_reg <= da_state_next;
                da_cs_reg <= da_cs_next;
                da_bit_reg <= da_bit_next;
                da_data_reg <= da_data_next;
                fir_state_reg <= fir_state_next;
            end if;
    end process;
    process(rotary_event, state_reg, led_pattern_reg, amp_state_reg, amp_bit_reg, ad_state_reg, ad_bit_reg, sdo, ad_data_reg, da_state_reg, da_bit_reg, da_data_reg, fir_state_reg)
        begin
        --amp
            state_next <= state_reg;
            amp_data_next <= amp_data_reg;
            amp_state_next <= amp_state_reg;
            amp_cs_next <= amp_cs_reg;
            sdi_next <= sdi_reg;
            sck_next <= sck_reg;
            amp_bit_next <= amp_bit_reg;
   
        --ad
            ad_state_next <= ad_state_reg;
            ad_channel1_next <= ad_channel1_reg;
            ad_bit_next <= ad_bit_reg;
            ad_conv_next <= ad_conv_reg;
        --da
            da_state_next <= da_state_reg;
            da_cs_next <= da_cs_reg;
            da_bit_next <= da_bit_reg;
            da_data_next <= da_data_reg;
        --fir
            fir_state_next <= fir_state_reg;
            case state_reg is
               
                when amp_state =>
                    case amp_state_reg is
                           
                        when amp_idle =>
                            amp_bit_next <= 8;
                            amp_data_next <= led_pattern_reg;
                            amp_cs_next <= '0';
                            sck_next <= '0';
                            amp_state_next <= amp_wait1;
                        when amp_wait1 =>
                            sdi_next <= amp_data_reg(amp_bit_reg - 1);
                            amp_state_next <= amp_sck1;
                        when amp_sck1 =>
                            sck_next <= '1';
                            amp_bit_next <= amp_bit_reg - 1;
                            amp_state_next <= amp_wait2;
                        when amp_wait2 =>
                            if amp_bit_reg > 0 then
                                amp_state_next <= amp_wait1;
                            else
                                amp_state_next <= amp_end;
                            end if;
                            sck_next <= '0';
                        when amp_end =>
                            sck_next <= '0';
                            sdi_next <= '0';
                            amp_cs_next <= '1';
                            amp_state_next <= amp_idle;
                            state_next <= ad_state;
                        when others => amp_state_next <= amp_idle;
                    end case;
                when ad_state =>
                    case ad_state_reg is
                        when ad_idle =>
                            ad_data_next <= (others => '0');
                            ad_conv_next <= '1';
                            ad_bit_next <= 34;
                            sck_next <= '0';
                            ad_state_next <= ad_conv0;
                        when ad_conv0 =>
                            ad_conv_next <= '0';
                            ad_state_next <= ad_sck1;
                        when ad_sck1 =>
                            sck_next <= '1';
                            ad_state_next <= ad_sck0;
                        when ad_sck0 =>
                            sck_next <= '0';
                            ad_data_next(ad_bit_reg - 1) <= sdo;
                            ad_state_next <= ad_cnt_update; 
                        when ad_cnt_update =>
                            ad_bit_next <= ad_bit_reg - 1;
                            ad_state_next <= ad_loop;
                        when ad_loop =>
                            if ad_bit_reg > 0 then
                                ad_state_next <= ad_sck1;
                            else
                                ad_state_next <= ad_data_adjust1;
                                --ad_data_next(33 downto 26) <= ad_data_reg(33 downto 26);
                            end if;
                        when ad_data_adjust1 =>
                            ad_data_next <= ad_data_reg(33) & ad_data_reg(33) & ad_data_reg(33 downto 2);
                            ad_state_next <= ad_data_adjust2;
                        when ad_data_adjust2 =>
                            ad_data_next <= ad_data_reg + x"0400";
                            ad_state_next <= ad_end;
                        when ad_end =>
                            ad_channel1_next <= ad_data_reg(33 downto 20);
                        -- ad_channel2_next <= ad_data_reg(15 downto 2);
                            ad_state_next <= ad_idle;
                            state_next <= fir_state;
                            sck_next <= '0';
                        when others => ad_state_next <= ad_idle;
                    end case;
                when fir_state =>
                    case fir_state_reg is
                        when fir0 =>
                            fir_state_next <= fir1;
                        when fir1 =>
                            state_next <= da_state;
                            fir_state_next <= fir0;
                        when others => fir_state_next <= fir0;
                    end case;
               
                when da_state =>
                    case da_state_reg is
                        when da_idle =>
                            da_cs_next <= '0';
                            sck_next <= '0';
                            da_bit_next <= 32;
                            da_data_next <= "0000000000110000" & ad_channel1_reg(13 downto 2) & "0000";
                            da_state_next <= da_send;
                        when da_send =>
                            sdi_next <= da_data_reg(da_bit_reg - 1);
                            da_state_next <= da_sck1;
                        when da_sck1 =>
                            sck_next <= '1';
                            da_bit_next <= da_bit_reg - 1;
                            da_state_next <= da_loop;
                        when da_loop =>
                            if da_bit_reg > 0 then
                                da_state_next <= da_send;
                            else
                                da_state_next <= da_end;
                            end if;
                            sck_next <= '0';
                        when da_end =>
                            da_cs_next <= '1';
                            sck_next <= '0';
                            da_state_next <= da_idle;
                            state_next <= amp_state;
                        when others => da_state_next <= da_idle;
                    end case;
                when others => state_next <= amp_state;
            end case;
    end process;
    simple_io(0) <= sck_reg;
    simple_io(1) <= sdo;
    simple_io(2) <= sdi_reg;
    simple_io(3) <= da_cs_reg;
    sdi <= sdi_reg;
    sck <= sck_reg;
    amp_shdn <= rst;
    amp_cs <= amp_cs_reg;
    ad_conv <= ad_conv_reg;
    da_cs <= da_cs_reg;
    da_clr <= not rst;
    strataflash_oe <= '1';
   strataflash_ce <= '1';
   strataflash_we <= '1';
    platformflash_oe <= '0';
end Behavioral;

 

Tags (5)
ad_da.JPG
0 Kudos
1 Solution

Accepted Solutions
Scholar drjohnsmith
Scholar
11,390 Views
Registered: ‎07-09-2009

Re: adc dca Spartan3e

Jump to solution

Hi

 

looks to me as if your code in actuality is working,

  have you tried simulating.

 

One comment first

  it's 'nice' to attach the code as a zip file, much easier to read the post, and to look at the code.

 

Anyway.

  AS you suggest, it looks as if you have the ADC / DAC working with different codes.

     You have the ADC outputting 2's compliment, and the DAC accepting straight binary.

 

To convert from one to the other you need:

 

 

http://en.wikipedia.org/wiki/Two%27s_complement

 

 

0 Kudos
7 Replies
Scholar drjohnsmith
Scholar
11,391 Views
Registered: ‎07-09-2009

Re: adc dca Spartan3e

Jump to solution

Hi

 

looks to me as if your code in actuality is working,

  have you tried simulating.

 

One comment first

  it's 'nice' to attach the code as a zip file, much easier to read the post, and to look at the code.

 

Anyway.

  AS you suggest, it looks as if you have the ADC / DAC working with different codes.

     You have the ADC outputting 2's compliment, and the DAC accepting straight binary.

 

To convert from one to the other you need:

 

 

http://en.wikipedia.org/wiki/Two%27s_complement

 

 

0 Kudos
9,087 Views
Registered: ‎11-26-2009

Re: adc dca Spartan3e

Jump to solution

Hi,

Thank you for a reply, I have found an error. The problem was not with 2's complement to binary conversion but with scaling of data form ad converter.

Best regards

0 Kudos
Newbie raineraine
Newbie
9,005 Views
Registered: ‎12-08-2009

Re: adc dca Spartan3e

Jump to solution
hello .. am a graduating student and i'll be doing a project -- voice recognition using the dac adc feature of the spartan 3e .. i just have this problem of what microphone to use in order to interface with the spartan kit. i have in mind but i couldn't find any circuit for the mic that have pins for the data to input to the converter. pls help
Tags (1)
0 Kudos
Adventurer
Adventurer
7,177 Views
Registered: ‎03-15-2011

Re: adc dca Spartan3e

Jump to solution

Is it possible to declare what the signals stand for?

I'm trying to make my own code, and was trying to understand and use this code, but when I compare your names listed (e.g. sdo, sdi) with the user guide of the spartan board, I don't know which are equal (e.g. sdo = (perhaps) spi_miso).

Greetings

Tags (1)
0 Kudos
Newbie sexosle
Newbie
7,109 Views
Registered: ‎03-29-2011

Re: adc dca Spartan3e

Jump to solution
 
xx.gif
0 Kudos
Historian
Historian
7,090 Views
Registered: ‎02-25-2008

Re: adc dca Spartan3e

Jump to solution

 


@wouterdevriese wrote:

Is it possible to declare what the signals stand for?

I'm trying to make my own code, and was trying to understand and use this code, but when I compare your names listed (e.g. sdo, sdi) with the user guide of the spartan board, I don't know which are equal (e.g. sdo = (perhaps) spi_miso).

Greetings


 

I always give my FPGA signals names that are meaningful, and I always make the schematic netnames match the FPGA pin signal names. Most of my designs have more than one SPI interface, so I like to assign a prefix to each group, like:

 

adcSpiSCLK

adcSpiMISO

adcSpiCS_l  (_l for active low)

 

dacSpiSCLK

dacSpiMOSI

dacSpiCS_l

 

etc.

----------------------------Yes, I do this for a living.
0 Kudos
Scholar drjohnsmith
Scholar
7,087 Views
Registered: ‎07-09-2009

Re: adc dca Spartan3e

Jump to solution

 

don 't know if this helps or confuses

 

in SPI / motorola world,

   they have a master and a number of slaves.

 

master drives the chip select signals, and the serial bit clock

 

MISO, is Master in Slave out , serial data out of the Slave to the master

MOSI, is master Out , slave in,  serial data out of the master , into the slave

 

 

 

 

0 Kudos