2
votes

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.

1
What frequency are you running at?Jonathan Drolet
You need to give more info, please provide the constraints for your signals it will help understand the problem better.Also remove the spi_datain from your sensitivity list, this is not necessary and wrong. One thing that helps is to look at the RTL schematic of your code and see if it implements the design the way you want it to be, I am sure you find some surprises here.FarhadA
Added the information and fixed the sensivity list as you said. But if you suspect about the ranges of the signals, although I think I handled them correctly, I added info anyway.ddyn
You do not define the signal as a clock? Why not put a BufG on the clock signal?FarhadA

1 Answers

0
votes

Check out the answer record from Xilinx

11.3 Spartan-3A Place - "Place:1018 error does not adequately describe the cause of the error."

Make sure you have placed the SPI clock signal on the correct pin and it is defined as a clock in your constraint file.

And PLEASE try not to use falling edge of a clock in your designs!

I would recomend using your 50MHz clock to synchronize all the data into your block then use the SPIC_CLK as a signal to control a state machine, This way all the signals in your design are synchronized with the same clock and you get rid of any noise on the SPI communication.