两个FPGA之间的SPI

时间:2015-05-13 00:50:36

标签: vhdl fpga spi spartan

我正在尝试用SPI通信两个FPGA(SPARTAN 3E入门套件)。我的主要目的是使用板载ADC和DAC(一个套件的ADC和另一个套件的DAC)实现语音传输系统,但是现在,我使用电位计为ADC输入提供模拟值,并测量DAC输出。我测试了系统的ADC和DAC部分,它们似乎正常工作。但是当我在套件之间添加SPI部件时,我发现了这些问题:

  • 当我将代码下载到工具包时,它们无法正常工作。在很多次尝试中,系统工作了几次(当然都是偶然的)。

  • 我在板载LED上提供数字数据值,以便正确观察它们,我发现当我将DAC代码下载到另一个套件时,ADC有时无效。 (带有DAC的套件不可能向其他套件提供任何数据,但看起来它们相互影响 - 是否可能?)

  • 我在实施设计时也会在DAC套件上收到此警告:

      

    放置:1019-已发现时钟IOB /时钟分量对未被放置在最佳时钟IOB /时钟位置对。时钟组件   spi_clock_BUFGP / BUFG位于BUFGMUX_X1Y10站点。

另外,我使用 50 MHz 时钟。

更新:将时钟分频以2MHz频率工作并没有任何区别

所以,我认为这些问题的原因是我所做的SPI实现,但我无法弄清楚它有什么问题。主机和从机SPI代码部分如下。

站长:

0

从站:

        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;

信号描述为:

  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;

和.ucf文件:

ADC套件

  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 ;

DAC套件:

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 ;

这有什么问题?或者我应该完全改变算法?我没时间了,所以任何帮助都将受到赞赏。 感谢。

1 个答案:

答案 0 :(得分:0)

查看Xilinx的答案记录

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

确保已将SPI时钟信号放在正确的引脚上,并将其定义为约束文件中的时钟。

请尽量不要在设计中使用时钟的下降沿!

我建议您使用50MHz时钟将所有数据同步到您的块中,然后使用SPIC_CLK作为控制状态机的信号,这样您设计中的所有信号都会与同一时钟同步,您就可以摆脱它SPI通信上的任何噪声。