gpt4 book ai didi

interface - FPGA 上的输入信号边沿检测

转载 作者:行者123 更新时间:2023-12-02 23:36:36 25 4
gpt4 key购买 nike

我正在尝试使用 4 线 SPI(cs、sclk、miso、mosi)连接 Virtex 4 (ML401) FPGATIVA C 系列板。 tiva 作为主机,FPGA 作为从机。我能够从主机接收 SPI 数据并在 FPGA 上的 LED 上显示数据(方法 2)。然而,我需要找到片选信号的上升和下降转换(我的应用程序需要用于同步目的)。我已经尝试了许多使用 FIFO 的方法(在模拟中效果很好),但在 FPGA 上不起作用,如下所示:

注:spi_cs是从TIVA板输入到FPGA的异步SPI片选信号,而其他信号(spi_cs_s、spi_cs_ss、spi_cs_h2l、spi_cs_l2h等)在 FPGA 内部创建。

方法1)

                prc_sync_cs: process(clk)
begin
if (clk'event and clk = '1') then
spi_cs_s <= spi_cs;
end if;
end process prc_sync_cs;

spi_cs_l2h <= not (spi_cs_s) and spi_cs;
spi_cs_h2l <= not (spi_cs) and spi_cs_s;

方法2)

                process (spi_cs)
begin
if (spi_cs = '0' or spi_cs = '1') then
-- update ledss with new MOSI on rising edge of CS
spi_cs_ss <= spi_cs_s;
spi_cs_s <= spi_cs;
--leds <= spi_wdata; --leds display the received data on the FPGA (saved into spi_wdata in another process)
-- THIS WORKS ON THE FGPA BUT the edge detection doesn't. Why?
end if;
end process;

spi_cs_h2l <= '1' when (spi_cs_s = '0' and spi_cs_ss = '1') else '0';
spi_cs_l2h <= '1' when (spi_cs_s = '1' and spi_cs_ss = '0') else '0';
leds <= "000000" & spi_cs_h2l & spi_cs_l2h; -- ALL leds are off always (i,e both transitions are '0' always).

方法3)

                prc_sync_cs: process(clk)
begin
if (clk'event and clk = '1') then
spi_cs_ss <= spi_cs_s;
spi_cs_s <= spi_cs;
end if;
end process prc_sync_cs;

prc_edge_cs: process(clk)
begin
if (clk'event and clk = '1') then
spi_cs_ss_del <= spi_cs_ss;
end if;
end process prc_edge_cs;

spi_cs_h2l <= '1' when (spi_cs_ss_del = '1' and spi_cs_ss = '0') else '0';
spi_cs_l2h <= '1' when (spi_cs_ss_del = '0' and spi_cs_ss = '1') else '0';

所有方法在仿真中都能完美运行,但在下载到 FPGA 上时却无法运行。我编写了一个过程来更密切地监视转换(监视亚稳态值,如果有的话):

            led_test: process(spi_cs_h2l, spi_cs_l2h)
begin
if spi_cs_h2l = '1' or spi_cs_l2h = '1' then
leds <= "111100" & spi_cs_h2l & spi_cs_l2h;
elsif spi_cs_h2l = 'X' or spi_cs_h2l = 'U' or spi_cs_h2l = 'Z' or
spi_cs_l2h = 'X' or spi_cs_l2h = 'U' or spi_cs_l2h = 'Z' then
leds <= "00001111";
else
leds <= "10101010";
end if;
end process led_test;

LED 始终为 “10101010”,即 spi_cs_h2lspi_cs_l2helse 的情况强>='0'。我缺少什么?任何指示都会非常有帮助,因为我已经被这个问题困扰很多天了。

更新

采用时钟域交叉的方法3(Jeff建议的),将所有LED和信号初始化为零,点亮LED的过程如下:

            led_test: process(spi_cs_h2l)
begin
if rising_edge(clk) then
if spi_cs_h2l = '1' then
leds <= "11110011";
end if;
end if;
end process led_test;

芯片选择引脚至少有一次从高到低的转换预计会点亮 LED。 SPI 芯片选择引脚始终接收“1”,当 FPGA 启动/重置时,LED 会亮起。这怎么可能?这种假高到低的转变是如何发生的?

最佳答案

方法1

这不会对 spi_cs 信号执行任何类型的时钟域交叉,因此不是一个可靠的电路。

方法2

if (spi_cs = '0' or spi_cs = '1') then 在综合设计中始终为真,我不希望您能够使用此检测边缘

方法3

这确实为 spi_cs 提供了时钟域交叉,并且总的来说看起来相当不错。您在 LED 上看到 “10101010” 的原因是,它们仅在 SPI 开始或结束时的一个 clk 周期内显示与此不同的内容交易。这可能比您用肉眼在 LED 上看到的速度要快得多。

此外,行 elsif spi_cs_h2l = 'X' or spi_cs_h2l = 'U' or spi_cs_h2l = 'Z' or spi_cs_l2h = 'X' or spi_cs_l2h = 'U' or spi_cs_l2h = 'Z' then 不会转化为 FPGA 中的任何真实硬件,因为真实硬件没有办法检查 'U''Z' 等。

方法3更新

听起来spi_cs实际上是低电平有效。您需要确保 spi_cs_sspi_cs_ss 等信号的初始值全部正确。在这种情况下,我认为您应该将它们全部初始化为 '1',因为这似乎是 spi_cs 的正常状态。因此,您的信号声明将类似于 signal spi_cs_s : std_logic := '1'。您应该能够在模拟中看到其正常运行。

关于interface - FPGA 上的输入信号边沿检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31407981/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com