cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
ken2ken
Newbie
Newbie
2,919 Views
Registered: ‎12-12-2009

Regarding the SPI between ADC and DE2 board

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;
0 Kudos
1 Reply
bassman59
Historian
Historian
2,901 Views
Registered: ‎02-25-2008

First: do NOT used shared variables. No, really. Don't use them. Seriously.

 

Second: do NOT use std_logic_arith/unsigned. No, really. Don't use them. Use numeric_std instead.

 

 Third: the process with the vector data_register as a clock? Think about why that doesn't work.

----------------------------Yes, I do this for a living.
0 Kudos