Continue to Site

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.

Please Help me, interconnecting ADC(ADS7861)and FPGA DE2

Status
Not open for further replies.

LF_LF

Member level 1
Joined
Nov 15, 2009
Messages
32
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,676
Please Help me.

Hi, i am a beginner in designing using VHDL. I need to construct interconnection between ADC(ADS7861 from Texas) and FPGA DE2 board. I have been told to use a SPI --- a serial to parallel SPi interface between ADC and FPGA. I have constructed the VHDL code for master(FPGA) and slave (ADC).

I understand that SPI only consists of 4 wires but my ADC having more than that. Therefore, i used Data_out( for MISO in slave), modeselect_A0 or convst (for MOSI in slave).
The total cycle needed for conversion is 32cycles but i only obtain the data till 16 cycles as the A0(I use mode 2 which is( M0=0,M1=1,A0=1)==>CHA1). After 16 cycle the A0 =0 so it convert for CHA0,so i stop then.
I put the CS always to low so that it is always ready to sent data.

For the code, i found out some errors in master and slave(i think is the same error for both) and i failed to fix it after many trial.

I hope that someone please help me in this case. Thank you in advanced

Master
LIBRARY ieee;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
LIBRARY work;

ENTITY ADC_SLAVE IS
PORT( serial_data_clock : IN STD_LOGIC;
serial_convst : IN STD_LOGIC;
serial_modeselect_A0 : IN STD_LOGIC;
serial_slaveselect : IN STD_LOGIC;
Data_in : IN STD_LOGIC_vector(15 downto 0)
);
END ENTITY;


ARCHITECTURE main OF ADC_SLAVE IS
shared variable data_register : BIT_VECTOR(15 downto 0);
shared variable data_counter : integer range 0 to 15 := 0;


BEGIN
recv_data: PROCESS(serial_data_clock,serial_slaveselect)
BEGIN
if serial_slaveselect ='1' then
data_counter := 0;

else(serial_data_clock'event = '1' and serial_data_clock ='1') then
if serial_convst = '1' and serial_modeselect_A0 = '1' then
if data_counter < 15 then
data_register(0) := to_stdlogicvector(Data_in);
data_register := data_register sll 1;
data_counter := data_counter +1;
else data_register(0) := to_bit(Data_in);
data_register := to_bit(data_register);
end if;
end if;
end if;
END PROCESS;

PROCESS(data_register)
BEGIN
if serial_convst = '0' then
data_counter := 0;
data_register <=(other=>'0');
elsif rising_edge (data_register) and data_counter < 15 then
data_counter <= data_counter + 1;
if (counter>"000000000000010") then
data_register(15 downto 1) <= data_register(14 downto 0);
data_register(0) <= Data_in;
end if;
end if;
END PROCESS;

END main;

Slave
LIBRARY ieee;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
LIBRARY work;

ENTITY ADC_SLAVE_SPI IS
PORT( serial_data_clock : IN STD_LOGIC;
serial_convst : IN STD_LOGIC;
serial_modeselect_A0 : IN STD_LOGIC;
serial_slaveselect : IN STD_LOGIC;
Data_out : OUT STD_LOGIC_vector(15 downto 0)
);
END ENTITY;

ARCHITECTURE main OF ADC_SLAVE_SPI IS
shared variable data_register: STD_LOGIC_VECTOR(15 downto 0);
shared variable data_counter : integer range 0 to 15 := 0;

BEGIN

PROCESS(serial_slaveselect)
BEGIN
if serial_convst = '0' then
Dataout<="0000000000000000";
elsif serial_modeselect_A0='1' and rising_edge(serial_slaveselect) then
Data_out<=data_register;
end if;
END PROCESS;


PROCESS(serial_slaveselect,serial_data_clock)
BEGIN
if serial_slaveselect='0' then
if rising_edge(serial_data_clock) then
data_register<=data_register(15 downto 0);
end if;
end if;
END PROCESS;
END main;
 

Re: Please Help me.

I have constructed the VHDL code for master(FPGA) and slave (ADC).
What are you trying to achieve? If you want to control the ADC, you have to design a SPI master interface. A VHDL code for the slave would be needed only to simulate the slave's behaviour.
For the code, i found out some errors in master and slave(i think is the same error for both) and i failed to fix it after many trial.
You are talking in riddles...
 

Re: Please Help me.

Yupp, i want to control the ADC so that it can send data from serial to parallel to FPGA board(as i am using the USB blaster download cable for DE2 board).

I am not quite sure about the interface and connectivity of the port with respect to the pin of ADC as i am new to it May you give me a hand? Thanks.
 

Please Help me.

The basic operation is to select some output pins of your DE-2 boards for ADC connections, most likely from one of the
GPIO connectors. These pins must appear in the external port of your design's top entity. You need to make pin assignments
for these pins too. Possibly you can copy port definitions together with the pin assignments from an existing example design.

You have to design the SPI master interface and connect it to the ADC pins. At the master interface, all signals except serial
data in have to be outputs to the ADC. As you already found out, the device has special hardware features, e.g. pins for
mode setting and channel selection that have to be controlled in addition to the SPI interface. I didn't use the particular chip,
but I thing the datasheet is clear in general.

It's a good practice to connect static signals as mode selection also to FPGA outputs, particularly if you don't know what's
the best setting for your application and set them to a fixed level in the VHDL code.

It's not as easy as a basic SPI device. You may need to read the data sheet more than once, until you understand everything.
 

Thank for your reply FvM;
I understand that my SPI is not an easy 1 as it consists of other pins. I have trued many time for the debugging part but it just didn't work, especially the clk part that interact with modeselect part. Do you mind to lend me a hand in debugging this. Thanks in advanced and please help me as i don't know where can i seek for my help(This is an individual project) . Thanks again.
 

When I see a FPGA design, that doesn't define any output pins, I can't imagine a SPI interface. This hasn't to do with specific properties of the interfaced ADC chip.

A FPGA design without outputs will be synthesized to zero logic cells by the design compiler, and it surely can't control anything outside.
 

    LF_LF

    Points: 2
    Helpful Answer Positive Rating
Thank for your reply btbass.
I checked that website before but it is written in verolog code. Unfortunately, i need to write in VHDL. Somemore, i cant understand the verilog code.:cry:

For FvM,
Thank for your remind. That's is some mistake when i copy n paste into this website.

It suppose to be :
PORT( serial_data_clock : IN STD_LOGIC;
serial_convst : OUT STD_LOGIC;
serial_modeselect_A0 : OUT STD_LOGIC;
serial_slaveselect : OUT STD_LOGIC;
Data_in : IN STD_LOGIC_vector(15 downto 0)
);

Do you mind to take a look into the part
:

else(serial_data_clock'event = '1' and serial_data_clock ='1') then
if serial_convst = '1' and serial_modeselect_A0 = '1' then
if data_counter < 15 then
data_register(0) := to_stdlogicvector(Data_in);
data_register := data_register sll 1;
data_counter := data_counter +1;
else data_register(0) := to_bit(Data_in);
data_register := to_bit(data_register);

I have been informed that the link of serial_data_clock has a few errors. According to the mesg of error, it always ask me to put in between these:= or <= or ; or then. After i changed, it asked me to put the other:cry:
 

Your code has syntax errors. Why don't you use the Q.uartus language templates to learn about valid VHDL syntax?
E.g. this is incorrect
else(serial_data_clock'event = '1' and serial_data_clock ='1') then
valid VHDL syntax would be elseif ... then
I also don't understand the purpose of various type conversions in your code. std_logic and std_logic_vector are directly
compatible, one bit of std_logic_vector can be assigned to and from a std_logic signal without conversions.

Shared variables have no actual purpose in synthesizable code, why don't you simply use signals?

serial_convst has finally become an output in your design, but where it's originated from? It must be generated by
your design after a number of clocks, or there should be an external trigger starting the conversion.

Havin serial-data_clock as an input to your design, implies, that it's an existing system clock. But it must also keep the
ADS7861 clock specification of max. 8 MHz. So where do you get this clock from?

Even if you would generate the SPI clock by an external clock divider or PLL, it must be fed to both the ADC and the SPI
master. It would be rather meaningful to operate the SPI master from a common design clock and generate the SPI clock
in your design internally. As another point, if serial_data_clock is not the common system clock, you have to synchronize
signals crossing the border between both clock domains. It's no problem at present, but it soon becomes, when you
operate the ADC controller as part of a larger design.

As a final comment, it's really a pitty, that Terasic doesn't provide instructive design examples for DE-2, covering both VHDL
and Verilog. There is however a huge amount of VHDL text books with usable code. From time to time I also stumble upon
VHDL lab exercises from various engineering schools and universities at the internet.
 

    LF_LF

    Points: 2
    Helpful Answer Positive Rating
I have changed a new code for that. However, i unable to obtain output waveform(it gave me logic 0 all the time) even there is no syntax errors.

This is held inside FPGA to control the output of ADC by sending convst and modeselect_A0.


The code as below:
LIBRARY ieee;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
LIBRARY work;

ENTITY ADS IS
PORT ( CLK, Data_in, Input_convst, modeselect_A0 : IN STD_LOGIC;
SCK, ADC_convst : OUT STD_LOGIC;
ADC_PAL_DATA : OUT STD_LOGIC_VECTOR(11 downto 0)
);
END ADS;

ARCHITECTURE main OF ADS IS
signal parallel : STD_LOGIC;
signal data_register : STD_LOGIC_VECTOR(11 downto 0);
signal counter1,counter2,counter3,counter4 : STD_LOGIC_VECTOR(5 downto 0);
shared variable temp1,temp2,temp3,temp4,syn : STD_LOGIC;

BEGIN

PROCESS(CLK) -- start conversion
BEGIN
if Input_convst='1' and temp1='0' then
temp1:='1';
temp2:='0';
ADC_convst<='1';
elsif (rising_edge(CLK))then
if temp1='1' then
if counter1<000010 then
counter1<=counter1 + 1;
elsif counter1 < 001111 then
if (rising_edge(CLK)) and modeselect_A0='1'then
if counter2<"000010" then
counter2<=counter2 + 1;
end if;
ADC_convst<='0';
temp2:='1';
end if;

end if;
end if;
if temp3='1' then
temp1:='0';
temp2:='0';
counter1<="000000";
end if;
end if;
END PROCESS;


PROCESS(CLK) -- CLK FOR ADS
BEGIN

if temp2 ='1' and rising_edge(CLK) then
if counter3<"101000" then
if counter3="000000" then syn:='1';
end if;
counter3<=counter3 + 1;
syn:=syn xor '1';
temp3:='0';
else
temp3:='1';
counter3<="000000";
end if;
end if;
SCK<=syn;
END PROCESS;

parallel<= syn;

PROCESS(parallel) --- Serial to parallel conversion
BEGIN
if modeselect_A0='1' then
counter4<="000000";
data_register<=(others=>'0');
elsif rising_edge(parallel) and counter4<"001111" then
counter4<=counter4 + 1;
if (counter4>"000010") then
data_register(11 downto 1)<= data_register(10 downto 0);
data_register(0)<= Data_in;
end if;
end if;
END PROCESS;

ADC_PAL_DATA<=data_register;

END main;

May someone please help me take a look on this. Thanks
 

Your going in the right direction regarding the overall structure of your design, particularly in assigning in- and
output ports in a meaningful way.

But there a serious problems with the internal structure. Apart from all other details, the basic outline of a synchronous
design should look like:
Code:
process (clk,reset)
begin
  if reset = '1' then
  -- reset action
  elsif rising_edge(clk) then
  -- action on each clock edge
    if condition1 then
      -- conditional action
    end if;
  end if;
end process;
I must remember again the Q.uartus language templates, that contain various VHDL design examples.

You have nested clock sensitive expressions in your process code. This isn't a syntax error, but meaningless code. It's also
questionable, if the conversion start should be build as an asynchronous action, similar to the reset in my above template. It
can be necessary in special cases, but also brings up a danger of timing violations and unexpected behaviour. If ever possible,
the conversion start request should be processed in the clock sensitive code.

As another point, I don't understand the purpose of the various counters in your design. You should be happy with one bit counter
that represents the current state of your receiver. Of course, it can be only set in one process. You may want to have a global state
signal for e.g. state = idle, run, whatsover. But it's not absolutely required.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top