Vhdl SPI接口在模拟中工作,但在实际硬件上不工作
我试图在传输窗口期间在SPI总线上发送多个字节。最初,当输入脉冲较高时,我从闪存ADC采集数据,然后计算其平均值,并在SPI总线上按顺序传输每个平均值。我让SPI vhdl模块工作,当我尝试发送单个字节时,它能够发送数据,但当我尝试发送超过1个字节时,它就不工作了。MOSI线路上有逻辑0,SS线路一直处于高位。这是我尝试发送多个字节的部分Vhdl SPI接口在模拟中工作,但在实际硬件上不工作,vhdl,fpga,xilinx,Vhdl,Fpga,Xilinx,我试图在传输窗口期间在SPI总线上发送多个字节。最初,当输入脉冲较高时,我从闪存ADC采集数据,然后计算其平均值,并在SPI总线上按顺序传输每个平均值。我让SPI vhdl模块工作,当我尝试发送单个字节时,它能够发送数据,但当我尝试发送超过1个字节时,它就不工作了。MOSI线路上有逻辑0,SS线路一直处于高位。这是我尝试发送多个字节的部分 process(SPITrig, Clock, TX_Done, data_count, average2A_s, average2B_s) begin
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;
注:SPI传输序列在平均输出可用时开始,并使用内部信号“SPITRig”触发 查看合成和计时(STA)警告,因为这些警告将指示合成工具是否无法实现与RTL VHDL代码匹配的设计 除非有充分理由使用多个时钟信号,否则上升沿(…)或下降沿(…)的边缘条件只能用于单个公共时钟信号;通常只使用上升沿(…) 在您的设计中,您有三种不同的信号
SPITrig
,SPI_Clock_base
和TX_Start
,它们的工作原理与时钟类似,这可能会导致时序冲突
例如,在大流程的第一个if
中,TX\u Start
和data\u count
都在下降沿(SPITrig)
上更新,在最后一个if
中,使用上升沿(TX\u Start)
根据当前data\u count
值再次更新数据计数。这在模拟中可能很好,但在硬件中存在信号传播延迟,这取决于路由和其他因素,这些因素可能会对不同的信号产生警惕,因此类似的设计结构可能会在实现中产生问题
如果您的设计有一个完整的静态时序分析(STA)设置,而您在第一次FPGA项目中可能没有这样的设置,那么STA工具将报告时序是否可以满足,并且像上面这样的结构很可能无法满足时序
因此,请重写您的设计以仅使用单个时钟边缘,例如上升边缘(SPI\u clock\u base)
。为这种设计进行正确的STA定时设置也容易得多,并且过程的灵敏度列表应仅包含时钟和任何异步复位信号(如果使用),如:
process (SPI_Clock_base) is
begin
if rising_edge(SPI_Clock_base) then
...
end if;
end process;
最后,初始过程的灵敏度列表应该减少到只包含过程中读取的信号,因为过程只需要对这些信号敏感。如果包含更多的信号,设计不会失败,它会让读者怀疑到底是什么错了;灵敏度列表或代码。请查看合成和计时(STA)警告,因为这些警告将指示合成工具是否无法实现与RTL VHDL代码匹配的设计
除非有充分理由使用多个时钟信号,否则上升沿(…)
或下降沿(…)的边缘条件只能用于单个公共时钟信号;通常只使用上升沿(…)
在您的设计中,您有三种不同的信号SPITrig
,SPI_Clock_base
和TX_Start
,它们的工作原理与时钟类似,这可能会导致时序冲突
例如,在大流程的第一个if
中,TX\u Start
和data\u count
都在下降沿(SPITrig)
上更新,在最后一个if
中,使用上升沿(TX\u Start)
根据当前data\u count
值再次更新数据计数。这在模拟中可能很好,但在硬件中存在信号传播延迟,这取决于路由和其他因素,这些因素可能会对不同的信号产生警惕,因此类似的设计结构可能会在实现中产生问题
如果您的设计有一个完整的静态时序分析(STA)设置,而您在第一次FPGA项目中可能没有这样的设置,那么STA工具将报告时序是否可以满足,并且像上面这样的结构很可能无法满足时序
因此,请重写您的设计以仅使用单个时钟边缘,例如上升边缘(SPI\u clock\u base)
。为这种设计进行正确的STA定时设置也容易得多,并且过程的灵敏度列表应仅包含时钟和任何异步复位信号(如果使用),如:
process (SPI_Clock_base) is
begin
if rising_edge(SPI_Clock_base) then
...
end if;
end process;
最后,初始过程的灵敏度列表应该减少到只包含过程中读取的信号,因为过程只需要对这些信号敏感。如果包含更多的信号,设计不会失败,它会让读者怀疑到底是什么错了;灵敏度列表或代码。正如Morten Zimer建议的那样,我做了必要的更改,使所有内容与时钟同步。下面是代码,它正在工作。稍后可能会发布示波器的屏幕截图
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;
过程(SPITrig、数据计数、平均2a、平均2b)
开始
病例数据_计数为
当1=>
TX_数据
TX_Data TX_Data正如Morten Zimer建议的那样,我做了必要的更改,使所有内容与时钟同步。下面是代码,它正在工作。稍后可能会发布示波器的屏幕截图
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;
过程(SPITrig、数据计数、平均2a、平均2b)
开始
病例数据_计数为
当1=>
TX_数据
谢谢你对我的问题给出了答案。我会做必要的改变然后回到这里。我做了必要的改变