我正在尝试使用 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 代码部分。
掌握:
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 ;
这有什么问题?或者我应该完全改变算法吗?我的时间不多了,所以任何帮助将不胜感激。谢谢。