I am trying to communicate two FPGAs (SPARTAN 3E Starter Kits) with SPI. My main purpose is to implement a voice transmission system using onboard ADC and DAC (ADC of one kit and DAC of the other kit), but for now, I am giving analog values to ADC input with potentiometer, and measuring the DAC output. I tested the ADC and DAC parts of the system, which seem to work properly. But when I added the SPI part between the kits, I observed these problems:
When I download the code to the kits, they do not work stable. The system worked few times out of many tries (of course all by chance).
I give the digital data values on the onboard LEDs in order to observe them properly, and I saw that sometimes ADC did not work when I downloaded the DAC code to the other kit. (It is not possible that the kit with DAC giving any data to the other kit, but it seems like they are affecting each other -is it possible?)
I also receive this warning on the DAC kit when I implement the design:
Place:1019 - A clock IOB / clock component pair have been found that are not >placed at an optimal clock IOB /clock site pair. The clock component spi_clock_BUFGP/BUFG is placed at site BUFGMUX_X1Y10.
Also, I use 50 MHz clock.
Update: Dividing clock to work on 2MHz frequency didn't make any difference
So, I think the reason of these problems is the SPI implementation that I made, but I can't figure out what is wrong with it. The master and the slave SPI code parts are given below.
Master:
if(spi_cs = '0') then
case spistt is
when 0 => spi_dataout <= DData(cntrspi) ;
when 1 => spi_clock <= '1';
when 2 => spi_clock <= '0';
if(cntrspi=15) then
adcstt <= 0;
spi_cs <= '1';
end if;
cntrspi <= cntrspi +1;
when 3 => null;
end case;
spistt <= spistt+1;
end if;
Slave:
process(spi_clock) is begin
if(falling_edge (spi_clock)) then
if(spi_cs = '0') then
if(spicounter = 0) then
fromADCtemp <= fromADC;
spicounter<=14;
else
fromADC(spicounter-1) <= spi_datain;
spicounter<=spicounter-1;
end if;
end if;
end if;
end process;
Where the signals are described as:
signal spistt : integer range 0 to 3;
signal cntrspi : integer range 2 to 15;
signal DData: STD_LOGIC_VECTOR (35 downto 0);
signal fromADC, fromADCtemp : std_logic_vector (13 downto 0);
signal spicounter : integer range 0 to 14 := 14 ;
And .ucf files:
ADC Kit
NET "SPI_SS_B" LOC = "U3" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
NET "SF_CE0" LOC = "D16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "FPGA_INIT_B" LOC = "T3" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4 ;
NET "Rst" LOC = "K17" | IOSTANDARD = LVTTL | PULLDOWN ;
NET "clk" LOC = "C9" | IOSTANDARD = LVCMOS33 ;
NET "SPI_SCK" LOC = "U16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "AD_CONV" LOC = "P11" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
NET "SPI_MISO" LOC = "N10" | IOSTANDARD = LVCMOS33 ;
NET "DOUT<7>" LOC = "F9" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "DOUT<6>" LOC = "E9" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "DOUT<5>" LOC = "D11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "DOUT<4>" LOC = "C11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "DOUT<3>" LOC = "F11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "DOUT<2>" LOC = "E11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "DOUT<1>" LOC = "E12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "DOUT<0>" LOC = "F12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "AMP_CS" LOC = "N7" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
NET "SPI_MOSI" LOC = "T4" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
NET "AMP_SHDN" LOC = "P7" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
NET "spi_clock" LOC = "B4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "spi_dataout" LOC = "A4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "spi_cs" LOC = "D5" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
DAC Kit:
NET "SPI_SS_B" LOC = "U3" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
NET "SF_CE0" LOC = "D16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "FPGA_INIT_B" LOC = "T3" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4 ;
NET "Rst" LOC = "K17" | IOSTANDARD = LVTTL | PULLDOWN ;
NET "clk" LOC = "C9" | IOSTANDARD = LVCMOS33 ;
NET "SPI_SCK" LOC = "U16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "AD_CONV" LOC = "P11" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
NET "DAC_CS" LOC = "N8" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "DAC_CLR" LOC = "P8" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "AMP_CS" LOC = "N7" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
NET "SPI_MOSI" LOC = "T4" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
NET "spi_clock" LOC = "B4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "spi_datain" LOC = "A4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "spi_cs" LOC = "D5" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
NET "spi_clock" CLOCK_DEDICATED_ROUTE=FALSE;
NET "LEDS<7>" LOC = "F9" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LEDS<6>" LOC = "E9" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LEDS<5>" LOC = "D11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LEDS<4>" LOC = "C11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LEDS<3>" LOC = "F11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LEDS<2>" LOC = "E11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LEDS<1>" LOC = "E12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LEDS<0>" LOC = "F12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
What is wrong with this? Or should I change the algorithm completely? I am running out of time so any help will be appreciated. Thanks.