【问题标题】:SPI interface works in simulation but not on actual hardwareSPI接口在模拟中工作,但在实际硬件上不工作
【发布时间】:2015-02-23 11:45:41
【问题描述】:

我试图在传输窗口期间在 SPI 总线上发送多个字节。最初,当输入脉冲为高电平时,我从闪存 ADC 获取数据,然后计算其平均值并在 SPI 总线上按顺序传输每个平均值。我让 SPI vhdl 模块工作,当我尝试发送单个字节时它能够发送数据,但是当我尝试发送超过 1 个字节时它就不起作用了。 MOSI线上有逻辑0,SS线一直为高。这是我尝试发送多个字节的部分。

process(SPITrig, Clock, TX_Done, data_count, average2A_s, average2B_s)
begin
    case data_count is
        when 1 => 
            TX_Data <= average2A_s;
        when 2 => 
            TX_Data <= average2B_s;
        when others => TX_Data <= "0101010101010101";
    end case;
end process;

process(SPIBusy, SPITrig, SPI_Clock_base, data_count, TX_Start) 
begin
     if falling_edge(SPITrig) then
        SPIBusy <= '1';
        TX_Start <= '0';
        data_count <= 0;
        delay_counter <= 0;
     end if;
     if rising_edge(SPI_Clock_base) and SPIBusy = '1' then
        if data_count < 3 then
            if delay_counter = 128 then
                TX_Start <= not TX_Start;
                delay_counter <= 0;
            elsif delay_counter < 128 then
                delay_counter <= delay_counter + 1;
            end if;

         elsif data_count >= 3 then
            TX_Start <= '0';
            delay_counter <= 0;
            SPIBusy <= '0';
        end if;
    end if; 
    if rising_edge(TX_Start) then
        data_count <= data_count + 1;
    end if;
end process;

它在模拟中运行良好,但在硬件上没有输出。需要您帮助找出问题所在。 PS:这是我的第一个FPGA项目,所以我的代码可能效率不高。 我还附上了 ISIM 屏幕截图。

可点击

tx = TX Done pin
trig = TX Start ping
c1 = data count

注意:当平均输出可用并使用内部信号“SPITRig”触发时,SPI 传输序列开始。

【问题讨论】:

    标签: vhdl fpga xilinx


    【解决方案1】:

    查看综合和时序 (STA) 警告,因为这些将指示综合工具是否无法实现设计以匹配 RTL VHDL 代码。

    rising_edge(...)falling_edge(...) 的边沿条件只能用于单个公共时钟信号,除非有充分的理由使用多个时钟信号;并且通常只使用rising_edge(...)

    在您的设计中,您有三个不同的信号 SPITrigSPI_Clock_baseTX_Start,它们的工作方式类似于时钟,这可能会导致时序违规。

    例如,在大进程的第一个if中,TX_Startdata_count都在falling_edge(SPITrig)上更新,在最后一个ifrising_edge(TX_Start)用于更新@ 987654333@ 再次基于当前的data_count 值。这在模拟中可能工作得很好,但在硬件中你会有信号传播延迟,这取决于路由和其他可能对不同信号持谨慎态度的因素,因此这样的设计结构可能会在实现中出现问题。

    如果您的设计有完整的静态时序分析 (STA) 设置,而您在第一次 FPGA 项目中可能没有,那么 STA 工具将报告时序是否可以满足,像上面这样的构造很可能不满足时机。

    因此,改写您的设计以仅使用单个时钟边沿,例如rising_edge(SPI_Clock_base)。为这样的设计进行正确的 STA 时序设置也容易得多,并且进程的敏感度列表应该只包含时钟和任何异步复位信号(如果使用),例如:

    process (SPI_Clock_base) is 
    begin
      if rising_edge(SPI_Clock_base) then
        ...
      end if;
    end process;
    

    最后,初始进程的敏感列表应该减少到只包含进程中读取的信号,因为进程只需要对这些信号敏感。如果包含更多的信号,设计不会失败,它会让读者想知道哪里出了问题;敏感度列表或代码。

    【讨论】:

    • 感谢您回答我的问题。我将进行必要的更改并返回这里。
    • 我进行了必要的更改,现在它正在工作。非常感谢。这是新答案中的更新代码;
    【解决方案2】:

    按照 Morten Zilmer 的建议,我进行了必要的更改以将所有内容与时钟同步。以下是代码,它正在工作。稍后可能会发布示波器的屏幕​​截图。

    process(SPITrig, data_count, average2A_s, average2B_s)
            begin
                case data_count is
                    when 1 => 
                        TX_Data <= average2A_s;
                    when 2 => 
                        TX_Data <= average2B_s;
                    when others => TX_Data <= x"0000";
                end case;
            end process;
    
            SPICycler : process(delay_counter, data_count, SPITrig, SPI_Clock_base, SPIBusy)
            begin
                if rising_edge(SPI_Clock_base) and SPIBusy = '1' then
                    if delay_counter < 511 then
                        delay_counter <= delay_counter + 1;
                        TX_Start <= '0';
                    else
                        delay_counter <= 0;
                        TX_Start <= '1';
                        data_count <= data_count + 1;
                    end if;
    
                end if;
                if rising_edge(SPI_Clock_base) then
                    if SPITrig = '1' then
                        SPIBusy <= '1';
                        data_count <= 0;
                    end if;
                    if data_count = 3 then
                        SPIBusy <= '0';
                    end if;
                end if;
            end process;
    

    【讨论】:

    • 太棒了。为了增加对代码的清理,然后将时钟进程中的ifs 与rising_edge(SPI_Clock_base) 条件合并为一个,并在内部创建一个额外的if SPIBusy = '1' then,因为这是常见的编码风格。此外,将该进程的敏感度列表减少到process (SPI_Clock_base),因为它只对时钟敏感。 SPITrig 也可以从第一个进程中删除,因为它在进程中未使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多