【问题标题】:SPI Between Two FPGAs两个 FPGA 之间的 SPI
【发布时间】:2015-05-13 00:50:36
【问题描述】:

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

  • 当我将代码下载到套件时,它们无法稳定运行。该系统在多次尝试中运行了几次(当然都是偶然的)。

  • 为了正确观察它们,我在板载 LED 上给出了数字数据值,当我将 DAC 代码下载到另一个套件时,我发现有时 ADC 无法工作。 (带有 DAC 的套件不可能向另一个套件提供任何数据,但似乎它们正在相互影响 - 有可能吗?)

  • 当我实现设计时,我也在 DAC 套件上收到此警告:

    Place:1019 - 发现一个时钟 IOB/时钟组件对没有>放置在最佳时钟 IOB/时钟站点对上。时钟组件 spi_clock_BUFGP/BUFG 放置在站点 BUFGMUX_X1Y10。

另外,我使用 50 MHz 时钟。

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

所以,我认为这些问题的原因是我制作的 SPI 实现,但我无法弄清楚它有什么问题。下面给出了主从 SPI 代码部分。

大师:

        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;

信号描述如下:

  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 ;

还有 .ucf 文件:

ADC 套件

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 套件:

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 ;

这有什么问题?还是我应该完全改变算法?我的时间不多了,所以任何帮助将不胜感激。 谢谢。

【问题讨论】:

  • 你的跑步频率是多少?
  • 您需要提供更多信息,请提供您的信号的约束,这将有助于更好地理解问题。同时从您的敏感度列表中删除 spi_datain,这没有必要并且是错误的。有帮助的一件事是查看代码的 RTL 示意图,看看它是否按照您想要的方式实现了设计,我相信您会在这里找到一些惊喜。
  • 如您所说,添加了信息并修复了敏感度列表。但是,如果您怀疑信号的范围,尽管我认为我处理它们正确,我还是添加了信息。
  • 你不把信号定义为时钟?为什么不在时钟信号上加一个 BufG?

标签: vhdl fpga spi spartan


【解决方案1】:

查看 Xilinx 的回答记录

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

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

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

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

【讨论】:

  • 当我尝试将 spi_clock 定义为时钟时出现错误。其原因可能是信号不是周期性的(不确定)。而且我不明白为什么使用下降沿是一个坏主意。谢谢。
  • 只是convention在下降沿使用上升沿,没有错。
  • 我说不使用下降沿的原因是许多设计师混合了下降沿和上升沿时钟,这使得他们的设计时序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-25
相关资源
最近更新 更多