Adc-fpga-dac interfacing vhdl

Status
Not open for further replies.

jimmykk

Full Member level 3
Joined
Oct 2, 2014
Messages
158
Helped
0
Reputation
0
Reaction score
1
Trophy points
1,298
Visit site
Activity points
2,865
Hi
i am inputting a sine wave to PARALLEL ADC-LTC2245 with max. amplitude 500mVpp at frequencies from 10 to 200 khz and the digital values are passed to Altera DE1 SOC board to remove the negative clock cycle of the input wave by using offset binary output format[LTC2245]. And then pass this to DAC5641(SPI) to see the rectified output.i.e to see only positive cycle analog wave. both adc and dac are 14 bit. I have written some code but , m not sure it works upto mark and also quite uncertain if DAC can manage to sample input frequencies greater than 50khz. I am using 5 mhz clock for both ADC and DAC. All the interfaces are using the GPIO bus.

HERE IS MY CODE:-


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
--use ieee.numeric_std.all;
 
 
entity ADC_PARALLEL is
port(
clock_50  : in std_logic;
LEDR      : out std_logic_vector(9 downto 0);
GPIO_1    : inout std_logic_vector(35 downto 0)
 
 
);
end ADC_PARALLEL;
 
architecture arch of ADC_PARALLEL is
type state_type is (IDLE,READ_DATA,WAIT_STATE,WRITE_DATA);
signal state  : state_type := IDLE;                  --initial state
 
 
signal clk_div : integer range 0 to 5 := 0;
signal clock_5 : std_logic := '0';
signal adc_data : std_logic_vector(13 downto 0);
signal positiv_cycle : unsigned(12 downto 0);             -- positive cycle data from adc 
signal count   : integer range 0 to 16 := 0;
 
 
 
begin
GPIO_1(6) <= '0';                 -- SHDN TO GROUND, SHOULD BE GROUND FOR NORMAL OPERATION OF ADC
GPIO_1(1)  <= clock_5;            -- 5MHZ OUT
GPIO_1(30) <= clock_5;            -- 5MHZ OUT
               
 
adc_data <= GPIO_1(25 downto 12); -- INPUT FROM GPIO BUS, 14 BITS COMING
LEDR <= adc_data(13 downto 4);
process(clock_50)      -- CLOCK DIVISION PROCESS
begin
if(rising_edge(clock_50)) then
if (clk_div = 4) then
clock_5 <= clock_5 xor '1';
clk_div <= 0;
else  
clk_div <= clk_div + 1;
end if;
end if;
end process;
 
 
process(clock_5)              --MAIN PROCESS
 
begin
if (rising_edge(clock_5)) then
--if(clk_div  = 4 and clock_5 = '0') then      -- DATA CHANGED ON RISING EDGE OF CLOCK
case state is
 
 
when IDLE =>
GPIO_1(0) <= '1';           -- DAC SYNC HIGH, DAC NOT IN WRITE MODE
GPIO_1(2) <= '0';           -- DAC SERIAL DATA OUT 
GPIO_1(7) <= '1';           -- OE high, adc disabled
positiv_cycle <= (others => '0');
if (count = 16) then
count <= 0;
state <= READ_DATA;
else 
count <= count + 1;
state <= IDLE;
end if;
 
when READ_DATA =>                     --  FOR one clock cycle
GPIO_1(0) <= '1';                     --  dac sync high, no write
GPIO_1(7) <= '0';                     -- OE down to 0,adc enabled, NORMAL OPERATION
GPIO_1(31) <= '0';                    -- OF BIT of ADC disabled, coz input is max. 500mVpp
 
if(count = 0) then
count <= count + 1;
state <= READ_DATA;
elsif(count = 1) then
if adc_data(13) = '1' then                    -- check MSB, IF '1' then positive cycle of wave OFFSET BINARY OUTPUT FORMAT
positiv_cycle <= unsigned(adc_data(12 downto 0));
--LEDR(9 downto 1) <= std_logic_vector(positiv_cycle(12 downto 4));
count <= 0;
state <= WAIT_STATE;
else                                                -- ELSE FOR NEGATIVE CYCLE, ALL BITS = 0
positiv_cycle <= "0000000000000";
--LEDR(9 downto 1) <= std_logic_vector(positiv_cycle(12 downto 4));
count <= 0;
state <= WAIT_STATE;
end if;
end if;
 
when WAIT_STATE =>
GPIO_1(0) <= '1';               -- sync high
GPIO_1(7) <= '1';               -- OE BACK HIGH OF ADC LTC2245
count <= 0;
state <= WRITE_DATA;
 
 
when WRITE_DATA =>
GPIO_1(0) <= '0';
GPIO_1(7) <= '1';
if(count = 0 or count = 1) then     -- NORMAL WRITE OOPERATION OF DAC-SPI, FIRST TWO BITS SHOULD BE 0
GPIO_1(2) <= '0';
count <= count+1;
state <= WRITE_DATA;
elsif(count = 2) then               -- HAS TO BE 0 BECAUSE ONLY 13 BITS ARE TO BE TRANSFERRED
GPIO_1(2) <= '0';
count <= count + 1;
state <= WRITE_DATA;
elsif(count > 2 and count < 16) then                   -- 13 BITS TRANSFEREED SERIALLY
GPIO_1(2) <= std_logic(positiv_cycle(15 - count));
count <= count + 1;
state <= WRITE_DATA;
 
elsif (count = 16) then
GPIO_1(0) <= '1';
GPIO_1(2) <= '0';
count <= 0;
state <= READ_DATA;
end if;
 
 
 
end case;
end if;
--end if;
end process;
 
end architecture;

 
Last edited by a moderator:

Now you need to write a testbench which will involve:
- Creating or finding models for the LTC2245 and DAC5641
- Input your signal into the LTC2245
- Check that what comes out of the DAC5641 matches what you want it to be

No doubt there will be errors of some sort in your code that will require debugging but the testbench is always there for you to run and re-run until you've got it correct.

Kevin Jennings
 

Thanks for your response...i am working on the test bench part but meanwhile can you suggest me if my code needs any changes that have not come into my mind or errors which are fatal for proper working of the system
thanks
 

Thanks for your response...i am working on the test bench part but meanwhile can you suggest me if my code needs any changes that have not come into my mind or errors which are fatal for proper working of the system
thanks

Genius! You incredible ... human, you! Thanks for a good chuckle.

Allow me to paraphrase: "Yes K-J, you are absolutely right. Getting the testbench in order should really be my priority at this stage, because that will make the debugging that much easier now AND in the future. When I have that testbench in place it will be that much easier to spot problems that otherwise can take way too much time. So I am all over that testbench thingy. ... Oh hey, while you're here, think you can take a look at my code before I put it through that testbench?"

Too funny. XD Not to worry, we all do that sort of thing to some degree. The good news is, you only have to do a few testbenches to realize that you are a silly person for not doing that sooner, and why on earth did you persist in debugging the hard way for so long.

But since you ask: the errors that are fatal for proper working of the system is the testbench shaped hole in your code base. ;-)
 

The DAC interface looks correct at first sight. In case that GPIO_1(31) is connected to ADC OF output, it must not be driven but should be tristated. And there's no actual use of toogling the ADC output enable.

It's usually mentioned that a divided clock is bad design practice and a clock enable or PLL generated clock should be used instead. You should keep this in mind when advancing to complex designs that make also use of the clock_50 input clock in other parts. If the complete design is clocked by the divided clock (except for the divider itself) it may be accepted though.

I basically agree with the test bench suggestion. With some experience in hardware interfaces, you may skip the tesbench phase and try the code in hardware directly, using Signaltap as debugging tool.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…