Regarding the SPI between ADC and DE2

N

New2VHDL

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.


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;
 
K

KJ

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.

Regardless of what anyone tells you (i.e. "I have been told to use a
SPI") the reality is that you a particular ADC so you need to become
familiar with the datasheet for that part. If you're not, it's at
http://focus.ti.com/lit/ds/symlink/ads7861.pdf

I have constructed the VHDL code for master
(FPGA) and slave (ADC).

Looking at the signal names on your entity for the ADC slave and the
pin names from the data sheet I'm not quite sure what you're
modelling. Entity ADC_SLAVE has no outputs, ADC_SLAVE_SPI
does...which is supposed to be the ADC?

Also, looking at the data sheet for the part there is an output called
'BUSY' which looks like it is used to indicate when a conversion is
still in progress (and therefore not an appropriate time to read back)
which does not seem to show up in your model.

The way I would approach it is to first model the ADC and validate
that it behaves according to the specification by creating a testbench
to validate that model. Specifically the model to create and validate
is the following entity

entity ADS7861 is port(
CHB1_PLUS: in real;
CHB1_MINUS: in real;
CHB0_PLUS: in real;
CHB0_MINUS: in real;
CHA1_PLUS: in real;
CHA1_MINUS: in real;
CHA0_PLUS: in real;
CHA0_MINUS: in real;
REF_IN: in real;
REF_OUT: in real;
BUSY: out std_logic;
CLOCK: in std_logic;
CS_N: in std_logic;
RD: in std_logic;
CONVST: in std_logic;
A0: in std_logic;
M0: in std_logic;
M1: in std_logic);
end ADS7861;

I understand that SPI only consists of 4 wires but my ADC having more than that.

Yep...it's not really a SPI device now is it then? While it does
appear that at some point you'll clock the device and it will generate
a serial data stream output much like a SPI device would do, there are
several other control signals that you need to provide that are unique
to your particular ADC. Hence you *really* should create a model for
that device and validate that it is correct first.

Take the view for the moment that the creation of a somewhat accurate
model for the ADS7861 is your ONLY concern. The real device only
responds to inputs received from it's pins, your model should behave
in the same manner.

To validate your model of the ADS7861 you will need to create
testbench code to generate stimulus to the ADS7861 and check that it
is responding appropriately. When you get to this point, you can
widen your view a bit, realizing that you're now creating a controller
for the ADS7861 so it would be handy to use the controller design
itself as part of the testbench for the ADS7861. I would have that
controller as a standalone entity as you intend to use it in your
final design. Looking at your code, it's not clear how your
controller outputs the data that it receives or what causes it to try
to start getting data in the first place...indeed I'm unclear as to
whether you actually have the controller code there or not, you lost
me.

In any case, at the end of the day, your model should be able to input
a real value into the analog inputs of your ADS7861 model and retrieve
the correct 12 bit interpretation of that real.

You might consider that it's 'too difficult' to model the part, but
it's not. In fact, the more complicated the part, the more important
it is to have an actual simulation model that captures what the real
device is doing...the alternative is to spend a LOT of time debugging
on hardware which is much slower than writing and validating your own
model. If you can obtain a model for the part you're using that
somebody has already written and tested, all the better. The point is
to model the real world in simulation so you can later debug and find
problems in simulation and not have to do so in the real world.

Lastly, do not use the 'ieee.std_logic_arith' or
'ieee.std_logic_unsigned' packages, they are not standards, they are
not even from the IEEE; use 'ieee.numeric_std' instead. It's probably
means nothing on your code, but it's a good practice to get into for
those situations where the differences between the two will be
evident.

Good luck
Kevin Jennings
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top