cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Anonymous
Not applicable
9,336 Views

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
drjohnsmith
Teacher
Teacher
11,591 Views
Registered: ‎07-09-2009

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

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>

View solution in original post

0 Kudos
7 Replies
drjohnsmith
Teacher
Teacher
11,592 Views
Registered: ‎07-09-2009

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

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>

View solution in original post

0 Kudos
Anonymous
Not applicable
9,288 Views

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
raineraine
Newbie
Newbie
9,206 Views
Registered: ‎12-08-2009
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
wouterdevriese
Adventurer
Adventurer
7,378 Views
Registered: ‎03-15-2011

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
sexosle
Newbie
Newbie
7,310 Views
Registered: ‎03-29-2011
 
xx.gif
0 Kudos
bassman59
Historian
Historian
7,291 Views
Registered: ‎02-25-2008

 


@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
drjohnsmith
Teacher
Teacher
7,288 Views
Registered: ‎07-09-2009

 

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

 

 

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos