Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help needed w.r.t D.A.C and FPGA on Nexsys2 Board!!!

Status
Not open for further replies.

sai1711

Newbie level 5
Joined
Jul 28, 2010
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,353
Hi All,
I got Bazinga'ed by the thing here.
After tinkering around for the past 8 days on my FPGA+ DAC to generate a Sinewave. I am still stuck.
Specs:
128 word deep ROM was used by me on VHDL
Board: Nexsys2

DAC: LTC1668, 16-bit Data In and differential signal IoutA and IoutB

code used:
Code:
  ---------------ROM module------------
  
  library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;		 
use ieee.std_logic_unsigned.all;

entity ROM is
port(	Clock   : in std_logic;
	Reset	: in std_logic;	
	Enable	: in std_logic;
	Read	: in std_logic;
	Address	: in std_logic_vector(6 downto 0);
	Data_out: out std_logic_vector(15 downto 0)
);
end ROM;

--------------------------------------------------------------

architecture Behav of ROM is

    type ROM_Array is array (0 to 127) 
	of std_logic_vector(15 downto 0);

    constant Content: ROM_Array := (
       
		 
0=>"0000000000000000",
1=>"0000001111011101",
2=>"0000011110111000",
3=>"0000101110001110",
4=>"0000111101011100",
5=>"0001001100100001",
6=>"0001011011011010",
7=>"0001101010000101",
8=>"0001111000011111",
9=>"0010000110100110",
10=>"0010010100011000",
11=>"0010100001110011",
12=>"0010101110110100",
13=>"0010111011011011",
14=>"0011000111100011",
15=>"0011010011001101",
16=>"0011011110010101",
17=>"0011101000111011",
18=>"0011110010111100",
19=>"0011111100010111",
20=>"0100000101001011",
21=>"0100001101010101",
22=>"0100010100110110",
23=>"0100011011101011",
24=>"0100100001110100",
25=>"0100100111001111",
26=>"0100101011111100",
27=>"0100101111111010",
28=>"0100110011001001",
29=>"0100110101100111",
30=>"0100110111010101",
31=>"0100111000010010",
32=>"0100111000011110",
34=>"0100110111111010",
35=>"0100110110100100",
36=>"0100110100011110",
37=>"0100110001101000",
38=>"0100101110000001",
39=>"0100101001101011",
40=>"0100100100100111",
41=>"0100011110110101",
42=>"0100011000010110",
43=>"0100010001001011",
44=>"0100001001010101",
45=>"0100000000110110",
46=>"0011110111101111",
47=>"0011101110000000",
48=>"0011100011101101",
49=>"0011011000110101",
50=>"0011001101011100",
51=>"0011000001100011",
52=>"0010110101001011",
53=>"0010101000010111",
54=>"0010011011001001",
55=>"0010001101100010",
56=>"0001111111100101",
57=>"0001110001010100",
58=>"0001100010110001",
59=>"0001010011111111",
60=>"0001000101000000",
61=>"0000110101110110",
62=>"0000100110100011",
63=>"0000010111001011",
64=>"0000000111101111",
65=>"1111111000010001",
66=>"1111101000110101",
67=>"1111011001011101",
68=>"1111001010001010",
69=>"1110111011000000",
70=>"1110101100000001",
71=>"1110011101001111",
72=>"1110001110101100",
73=>"1110000000011011",
74=>"1101110010011110",
75=>"1101100100110111",
76=>"1101010111101001",
77=>"1101001010110101",
78=>"1100111110011101",
79=>"1100110010100100",
80=>"1100100111001011",
81=>"1100011100010011",
82=>"1100010010000000",
83=>"1100001000010001",
84=>"1011111111001010",
85=>"1011110110101011",
86=>"1011101110110101",
87=>"1011100111101010",
88=>"1011100001001011",
89=>"1011011011011001",
90=>"1011010110010101",
91=>"1011010001111111",
92=>"1011001110011000",
93=>"1011001011100010",
94=>"1011001001011100",
95=>"1011001000000110",
96=>"1011000111100010",
97=>"1011000111101110",
98=>"1011001000101011",
99=>"1011001010011001",
100=>"1011001100110111",
101=>"1011010000000110",
102=>"1011010100000100",
103=>"1011011000110001",
104=>"1011011110001100",
105=>"1011100100010101",
106=>"1011101011001010",
107=>"1011110010101011",
108=>"1011111010110101",
109=>"1100000011101001",
110=>"1100001101000100",
111=>"1100010111000101",
112=>"1100100001101011",
113=>"1100101100110011",
114=>"1100111000011101",
115=>"1101000100100101",
116=>"1101010001001100",
117=>"1101011110001101",
118=>"1101101011101000",
119=>"1101111001011010",
120=>"1110000111100001",
121=>"1110010101111011",
122=>"1110100100100110",
123=>"1110110011011111",
124=>"1111000010100100",
125=>"1111010001110010",
126=>"1111100001001000",
--127=>"1111110000100011",
--128=>"0000000000000000"
--63=>"0000000000000000",


	OTHERS => "1111110000100011"
	);       

begin
    process(Clock, Reset, Read, Address)
    begin
        if( Reset = '1' ) then
	    Data_out <= "ZZZZZZZZZZZZZZZZ";
        elsif( Clock'event and Clock = '1' ) then
	    if Enable = '1' then
		if( Read = '1' ) then
		    Data_out <= Content(conv_integer(Address));
            	else
                    Data_out <= "ZZZZZZZZZZZZZZZZ";
            	end if;
	    end if;
        end if;
    end process;
end Behav;

-----------------------------------------------------------
--------------------------------------------------counter module to count 4-bit address------
 library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

----------------------------------------------------

entity counter is

 port(	clock:	in std_logic;
	rst:	in std_logic;
	count:	in std_logic;
	Q:	out std_logic_vector(6 downto 0)
);
end counter;

----------------------------------------------------

architecture behv of counter is		 	  
	
    signal Pre_Q: std_logic_vector(6 downto 0);

begin

    -- behavior describe the counter

    process(clock, count, rst)
    begin
	if rst = '1' then
 	    Pre_Q <= "0000000";
	elsif (rising_edge(clock) and rst='0') then
	    if count = '1' then
		Pre_Q <= Pre_Q + '1';
	    end if;
	end if;
    end process;	
	
    -- concurrent assignment statement
    Q <= Pre_Q;

end behv;
-------------------------------------------- clock---------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity clk1mHz is
    Port (
        clk : in  STD_LOGIC;
        reset  : in  STD_LOGIC;
        clk_out: out STD_LOGIC
    );
end clk1mHz;

architecture Behavioral of clk1mHz is
    signal temporal: STD_LOGIC;
    signal counter : integer range 0 to 26 := 0;
begin
    frequency_divider: process (reset, clk) begin
        if (reset = '1') then
            temporal <= '0';
            counter <= 0;
        elsif rising_edge(clk) then
            if (counter = 26) then
                temporal <= NOT(temporal);
                counter <= 0;
            else
                counter <= counter + 1;
            end if;
        end if;
    end process;
    
    clk_out <= temporal;
end Behavioral;



--------------------------------------------------------------------MAIN MODULE-------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

use IEEE.NUMERIC_STD.ALL;
entity sinecounter is

port (clk,reset,resetclk,rst,En,read,count: in std_logic;
clk_out: out std_logic;
sine: out std_logic_vector(15 downto 0));


end sinecounter;
architecture Behavioral of sinecounter is

component counter is

port(	clock:	in std_logic;
	rst:	in std_logic;
	count:	in std_logic;
	Q:	out std_logic_vector(6 downto 0)
);
end component;


component clk1mHz is
    Port (
        clk : in  STD_LOGIC;
        reset  : in  STD_LOGIC;
        clk_out: out STD_LOGIC
    );
end component;

component ROM is
port(	Clock   : in std_logic;
	Reset	: in std_logic;	
	Enable	: in std_logic;
	Read	: in std_logic;
	Address	: in std_logic_vector(6 downto 0);
	Data_out: out std_logic_vector(15 downto 0)
);
end component;
 
signal tempo: std_logic_vector(6 downto 0);
begin

x1: counter port map( clock=>clk, count=>count, rst=>rst,Q=>tempo);

x2: clk1mHz port map ( clk=> clk, reset=>resetclk, clk_out=> clk_out);

x3: ROM port map(Clock=>clk, Reset=> reset, Enable=> En, Read=>read, Address=> tempo, Data_out=> sine);
			 
end Behavioral;

UCF file :
Code:
Net "clk" Loc ="B8";
Net "sine(0)" Loc ="J13";
Net "sine(1)" Loc="M18"; 
Net "sine(2)" Loc="N18"; 
Net "sine(3)" Loc="P18";
 
Net "sine(4)" Loc="G15"; 
Net "sine(5)" Loc="J16"; 
Net "sine(6)" Loc="G13"; 
Net "sine(7)" Loc="H16"; 

Net "sine(8)" Loc="M13"; 
Net "sine(9)" Loc="R18"; 
Net "sine(10)" Loc="R15"; 
Net "sine(11)" Loc="T17";
 
Net "sine(12)" Loc="L15"; 
Net "sine(13)" Loc="K12"; 
Net "sine(14)" Loc="L17"; 
Net "sine(15)" Loc="M15";
 
Net "clk_out" Loc="H15";
Net "reset" Loc="G18";
Net "resetclk" Loc="H18";
Net "rst" Loc="K18";
Net "En" Loc="K17";
Net "read" Loc="L14";
Net "count" Loc="L13";


DAC Output
dig1.JPG
digi2.JPG
 

aruipksni

Full Member level 6
Joined
May 23, 2013
Messages
346
Helped
68
Reputation
136
Reaction score
66
Trophy points
1,308
Activity points
3,004
Hi All,
I got Bazinga'ed by the thing here.
After tinkering around for the past 8 days on my FPGA+ DAC to generate a Sinewave. I am still stuck.
Specs:
128 word deep ROM was used by me on VHDL
Board: Nexsys2

DAC: LTC1668, 16-bit Data In and differential signal IoutA and IoutB

code used:
Code:
  ---------------ROM module------------
  
  library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;		 
use ieee.std_logic_unsigned.all;

entity ROM is
port(	Clock   : in std_logic;
	Reset	: in std_logic;	
	Enable	: in std_logic;
	Read	: in std_logic;
	Address	: in std_logic_vector(6 downto 0);
	Data_out: out std_logic_vector(15 downto 0)
);
end ROM;

--------------------------------------------------------------

architecture Behav of ROM is

    type ROM_Array is array (0 to 127) 
	of std_logic_vector(15 downto 0);

    constant Content: ROM_Array := (
       
		 
0=>"0000000000000000",
1=>"0000001111011101",
2=>"0000011110111000",
3=>"0000101110001110",
4=>"0000111101011100",
5=>"0001001100100001",
6=>"0001011011011010",
7=>"0001101010000101",
8=>"0001111000011111",
9=>"0010000110100110",
10=>"0010010100011000",
11=>"0010100001110011",
12=>"0010101110110100",
13=>"0010111011011011",
14=>"0011000111100011",
15=>"0011010011001101",
16=>"0011011110010101",
17=>"0011101000111011",
18=>"0011110010111100",
19=>"0011111100010111",
20=>"0100000101001011",
21=>"0100001101010101",
22=>"0100010100110110",
23=>"0100011011101011",
24=>"0100100001110100",
25=>"0100100111001111",
26=>"0100101011111100",
27=>"0100101111111010",
28=>"0100110011001001",
29=>"0100110101100111",
30=>"0100110111010101",
31=>"0100111000010010",
32=>"0100111000011110",
34=>"0100110111111010",
35=>"0100110110100100",
36=>"0100110100011110",
37=>"0100110001101000",
38=>"0100101110000001",
39=>"0100101001101011",
40=>"0100100100100111",
41=>"0100011110110101",
42=>"0100011000010110",
43=>"0100010001001011",
44=>"0100001001010101",
45=>"0100000000110110",
46=>"0011110111101111",
47=>"0011101110000000",
48=>"0011100011101101",
49=>"0011011000110101",
50=>"0011001101011100",
51=>"0011000001100011",
52=>"0010110101001011",
53=>"0010101000010111",
54=>"0010011011001001",
55=>"0010001101100010",
56=>"0001111111100101",
57=>"0001110001010100",
58=>"0001100010110001",
59=>"0001010011111111",
60=>"0001000101000000",
61=>"0000110101110110",
62=>"0000100110100011",
63=>"0000010111001011",
64=>"0000000111101111",
65=>"1111111000010001",
66=>"1111101000110101",
67=>"1111011001011101",
68=>"1111001010001010",
69=>"1110111011000000",
70=>"1110101100000001",
71=>"1110011101001111",
72=>"1110001110101100",
73=>"1110000000011011",
74=>"1101110010011110",
75=>"1101100100110111",
76=>"1101010111101001",
77=>"1101001010110101",
78=>"1100111110011101",
79=>"1100110010100100",
80=>"1100100111001011",
81=>"1100011100010011",
82=>"1100010010000000",
83=>"1100001000010001",
84=>"1011111111001010",
85=>"1011110110101011",
86=>"1011101110110101",
87=>"1011100111101010",
88=>"1011100001001011",
89=>"1011011011011001",
90=>"1011010110010101",
91=>"1011010001111111",
92=>"1011001110011000",
93=>"1011001011100010",
94=>"1011001001011100",
95=>"1011001000000110",
96=>"1011000111100010",
97=>"1011000111101110",
98=>"1011001000101011",
99=>"1011001010011001",
100=>"1011001100110111",
101=>"1011010000000110",
102=>"1011010100000100",
103=>"1011011000110001",
104=>"1011011110001100",
105=>"1011100100010101",
106=>"1011101011001010",
107=>"1011110010101011",
108=>"1011111010110101",
109=>"1100000011101001",
110=>"1100001101000100",
111=>"1100010111000101",
112=>"1100100001101011",
113=>"1100101100110011",
114=>"1100111000011101",
115=>"1101000100100101",
116=>"1101010001001100",
117=>"1101011110001101",
118=>"1101101011101000",
119=>"1101111001011010",
120=>"1110000111100001",
121=>"1110010101111011",
122=>"1110100100100110",
123=>"1110110011011111",
124=>"1111000010100100",
125=>"1111010001110010",
126=>"1111100001001000",
--127=>"1111110000100011",
--128=>"0000000000000000"
--63=>"0000000000000000",


	OTHERS => "1111110000100011"
	);       

begin
    process(Clock, Reset, Read, Address)
    begin
        if( Reset = '1' ) then
	    Data_out <= "ZZZZZZZZZZZZZZZZ";
        elsif( Clock'event and Clock = '1' ) then
	    if Enable = '1' then
		if( Read = '1' ) then
		    Data_out <= Content(conv_integer(Address));
            	else
                    Data_out <= "ZZZZZZZZZZZZZZZZ";
            	end if;
	    end if;
        end if;
    end process;
end Behav;

-----------------------------------------------------------
--------------------------------------------------counter module to count 4-bit address------
 library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

----------------------------------------------------

entity counter is

 port(	clock:	in std_logic;
	rst:	in std_logic;
	count:	in std_logic;
	Q:	out std_logic_vector(6 downto 0)
);
end counter;

----------------------------------------------------

architecture behv of counter is		 	  
	
    signal Pre_Q: std_logic_vector(6 downto 0);

begin

    -- behavior describe the counter

    process(clock, count, rst)
    begin
	if rst = '1' then
 	    Pre_Q <= "0000000";
	elsif (rising_edge(clock) and rst='0') then
	    if count = '1' then
		Pre_Q <= Pre_Q + '1';
	    end if;
	end if;
    end process;	
	
    -- concurrent assignment statement
    Q <= Pre_Q;

end behv;
-------------------------------------------- clock---------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity clk1mHz is
    Port (
        clk : in  STD_LOGIC;
        reset  : in  STD_LOGIC;
        clk_out: out STD_LOGIC
    );
end clk1mHz;

architecture Behavioral of clk1mHz is
    signal temporal: STD_LOGIC;
    signal counter : integer range 0 to 26 := 0;
begin
    frequency_divider: process (reset, clk) begin
        if (reset = '1') then
            temporal <= '0';
            counter <= 0;
        elsif rising_edge(clk) then
            if (counter = 26) then
                temporal <= NOT(temporal);
                counter <= 0;
            else
                counter <= counter + 1;
            end if;
        end if;
    end process;
    
    clk_out <= temporal;
end Behavioral;



--------------------------------------------------------------------MAIN MODULE-------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

use IEEE.NUMERIC_STD.ALL;
entity sinecounter is

port (clk,reset,resetclk,rst,En,read,count: in std_logic;
clk_out: out std_logic;
sine: out std_logic_vector(15 downto 0));


end sinecounter;
architecture Behavioral of sinecounter is

component counter is

port(	clock:	in std_logic;
	rst:	in std_logic;
	count:	in std_logic;
	Q:	out std_logic_vector(6 downto 0)
);
end component;


component clk1mHz is
    Port (
        clk : in  STD_LOGIC;
        reset  : in  STD_LOGIC;
        clk_out: out STD_LOGIC
    );
end component;

component ROM is
port(	Clock   : in std_logic;
	Reset	: in std_logic;	
	Enable	: in std_logic;
	Read	: in std_logic;
	Address	: in std_logic_vector(6 downto 0);
	Data_out: out std_logic_vector(15 downto 0)
);
end component;
 
signal tempo: std_logic_vector(6 downto 0);
begin

x1: counter port map( clock=>clk, count=>count, rst=>rst,Q=>tempo);

x2: clk1mHz port map ( clk=> clk, reset=>resetclk, clk_out=> clk_out);

x3: ROM port map(Clock=>clk, Reset=> reset, Enable=> En, Read=>read, Address=> tempo, Data_out=> sine);
			 
end Behavioral;

UCF file :
Code:
Net "clk" Loc ="B8";
Net "sine(0)" Loc ="J13";
Net "sine(1)" Loc="M18"; 
Net "sine(2)" Loc="N18"; 
Net "sine(3)" Loc="P18";
 
Net "sine(4)" Loc="G15"; 
Net "sine(5)" Loc="J16"; 
Net "sine(6)" Loc="G13"; 
Net "sine(7)" Loc="H16"; 

Net "sine(8)" Loc="M13"; 
Net "sine(9)" Loc="R18"; 
Net "sine(10)" Loc="R15"; 
Net "sine(11)" Loc="T17";
 
Net "sine(12)" Loc="L15"; 
Net "sine(13)" Loc="K12"; 
Net "sine(14)" Loc="L17"; 
Net "sine(15)" Loc="M15";
 
Net "clk_out" Loc="H15";
Net "reset" Loc="G18";
Net "resetclk" Loc="H18";
Net "rst" Loc="K18";
Net "En" Loc="K17";
Net "read" Loc="L14";
Net "count" Loc="L13";


DAC Output
View attachment 97131
View attachment 97132

3 issues i like to raise :

1. sensitivity list : if you are implementing synchronous process then only clk or (async rst_n if you want)
should be written.

2. asertion to 'Z' : you better use iobuffer primitive, and why you actually do this ? (it's not like you have a bi-di bus to drive)

3. you better use the ROM primitive to be on the safe side.

and ofcouse edit this post to include VHDL syntax.

your plot look like some random noise to me, so check you hardware, and scope.
 

mrflibble

Advanced Member level 5
Joined
Apr 19, 2010
Messages
2,724
Helped
679
Reputation
1,360
Reaction score
651
Trophy points
1,393
Activity points
19,551
Well, it's definitely periodic, but not exactly sine wave. Closer to a triangle wave with superimposed noise...

Anyways, the ever popular question: have you put it through a testbench yet?
 

sai1711

Newbie level 5
Joined
Jul 28, 2010
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,353
Well, it's definitely periodic, but not exactly sine wave. Closer to a triangle wave with superimposed noise...

Anyways, the ever popular question: have you put it through a testbench yet?
Yes, its a popular question and everytime has its own local problems. :))
I have not taken it through a TB.
Aftre burning my DAC.
As an alternative I tried the LC-Low pass filter trick. With Delta-sigma thing. Didnt work either.
The Delta sigma module individually is working fine.
The ROM module with counter is individually working fine.
But only when the modules come together, they aint working at all. :(
I am almost at the verge of a certain vexation.
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
48,919
Helped
14,335
Reputation
28,933
Reaction score
13,080
Trophy points
1,393
Location
Bochum, Germany
Activity points
282,272
How can we know that the DAC is connected correctly? If you verified the data sent to the DAC, it's obviously a hardware problem.

Giving a binary counter output to the DAC would be a simple way to check for correct data line order and complete connection.
 

mrflibble

Advanced Member level 5
Joined
Apr 19, 2010
Messages
2,724
Helped
679
Reputation
1,360
Reaction score
651
Trophy points
1,393
Activity points
19,551
I would check my power supply and grounding. The wiring looks potentially a bit optimistic. What is the frequency of the clock signal you're sending to that LTC1668? Anyways, I'd make the ground connection between board + DAC a bit beefier and maybe add some bypass caps. Then lower the update frequency and see what we can see on the scope.

That, and double checking a couple of data pins on the DAC with the scope is probably a good idea as well. For that you'd want just a regular binary counter as output, just like FvM suggested. That's easier to watch than bit number 3 of a sine wave for example. ;)
 

sai1711

Newbie level 5
Joined
Jul 28, 2010
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,353
Genau, I shall do that today

- - - Updated - - -

The max rated clock frequency of the DAC LTC1668 is 1 MHz. I am feeding in 917 kHz, from the clock divider module. the reason for 128 words deep ROM is the same, i.e. to have a frequency of sampling satisfying nyquist sampling theorem, because with 128 Words and 917 KHz> 2* Freq of the sinewave being generated.

I suspect the wiring to be a culprit too. I shall look to add some caps and see. And I will get back with the outcome.
BTW the Sigma-Delta method posted here: http://designingwithfpgas.blogspot.kr/2011/10/one-of-downfalls-of-fpgas-are-digital.html
http://designingwithfpgas.blogspot.kr/2011_11_01_archive.html

didnt work either.
 

mrflibble

Advanced Member level 5
Joined
Apr 19, 2010
Messages
2,724
Helped
679
Reputation
1,360
Reaction score
651
Trophy points
1,393
Activity points
19,551
In that case feeding it a 1 kHz clock signal with a simple binary counter would be a nice test. That should then give you a nice slow sawtooth on the scope.

Not sure what the delta-sigma thing has to do with this? That sounds like it's a totally seperated issue from the LTC1668. LTC1668 ==> most likely crap wiring. delta-sigma not working ==> most likely crap coding. ;)

Delta sigma is easy enough to debug though. Just run through a testbench, spit out the 1-bit data stream to text file. Then do some low-pass filtering in your favorite math tool. Matlab, octave, whatever.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top