完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嗨,
我正在尝试在两个Virtex 5 FPGA评估板之间实现自己的自定义SPI连接,但我在采样SPI时钟时遇到了一些问题。 我的SPI时钟是12.5 MHz,它由sys_clk(125 MHz)采样,所以我想这不是问题。 首先,我试图通过将SPI clk延迟一个sysclk来对SPI时钟进行采样,并将其路由到另一个进程,在那里我比较当前和延迟的SPI clk。 如果当前SPIclk = 1 延迟的SPIclk = 0 该过程生成一个输出信号(sclk_event = 1),表示正SPIclk边沿。 然而,这导致了SPIclk的相当不稳定的采样,因为它仅被采样了大约80%的时间 接下来,我尝试在两位**哔哔**寄存器中对SPIclk进行采样,然后等待寄存器值为“01”以生成输出(sclk_event) 突然之间,SPIclk的采样都是稳定的。 有谁知道为什么第一种采样SPIclk的方法不起作用? 当我引起你的注意时,是否有人知道我的12.5 MHz SPIclk是否需要在某种时钟驱动的I / O引脚上进行路由? 这是我的VHDL示例: 首先是两个进程,一个延迟进程和一个SPIclk事件生成进程: 实体Delay_one_clock是端口(clk:在STD_LOGIC中; rst:在STD_LOGIC中; d_in:在STD_LOGIC中; d_out:输出STD_LOGIC);结束Delay_one_clock;体系结构Delay_one_clock的行为i***eginpass_on:进程(clk,rst)如果(rst ='1'则开始 )然后d_out elsif(clk'event和clk ='1')然后d_out结束if; 结束过程pass_on;结束行为; ================================================== ===== 实体Generate_Sclk_event是端口(clk:在STD_LOGIC中; rst:在STD_LOGIC中; sclk:在STD_LOGIC中; delayed_sclk:在STD_LOGIC中; sclk_event:输出STD_LOGIC);结束Generate_Sclk_event;架构Generate_Sclk_event的行为i***egin Genrate_clk_event:process(clk,rst)如果开始 (rst ='1')然后sclk_event elsif rising_edge(clk)然后 - 如果sclk rising_edge if(sclk ='1'和delayed_sclk ='0')然后sclk_event else sclk_event结束if; 万一; 结束过程;结束行为; ================================================== ======= 那么使用shif寄存器的过程: 实体Generate_Sclk_event是Port(clk:在STD_LOGIC中; rst:在STD_LOGIC中; sclk:在STD_LOGIC中; sclk_event:out STD_LOGIC); end Generate_Sclk_event;架构Generate_Sclk_event的行为是信号Sclk_samples:STD_LOGIC_VECTOR(1 downto 0);开始Genrate_clk_event:process(clk ,rst)开始if(rst ='1')然后sclk_event Sclk_samples elsif rising_edge(clk)然后Sclk_samples(1)Sclk_samples(0) - 如果sclk rising_edge if(Sclk_samples =“01”)则sclk_event else sclk_event结束if; 万一; 结束过程;结束行为; 任何帮助我appriciated Muggi 以上来自于谷歌翻译 以下为原文 Hi, I am trying to implement my own custom SPI connection between two Virtex 5 FPGA evaluationboards, but I have some problems sampling the SPI clock. My SPI clock is 12.5 MHz and it is sampled by the sys_clk (125 MHz), so I guess this is not a problem. At first I tried to sample the SPI clock by delaying the SPI clk by one sysclk and route it in to another process where I compare the current and the delayed SPI clk. If the current SPIclk = 1 and the delayed SPIclk = 0 the process generated a output signal (sclk_event = 1) symbolizing a positive SPIclk edge. However this resulted in a rather unstable sampling of the SPIclk,as it was only sampled about 80% of the times it was supposed to Next i tried to sample the SPIclk in a two bit **bleep** register and then wait for the registervalue to be "01" to generate the output (sclk_event) All of the sudden the sampling of the SPIclk is all stabil. Does anyone know why the first way of sampling the SPIclk does not work? while I got your attention, does anyone know if my 12,5 MHz SPIclk needs to be routed on some sort of clock deticated I/O pin? here is my VHDL examples: First the two processes, one delay process and one SPIclk event generate process: entity Delay_one_clock is Port ( clk : in STD_LOGIC; rst : in STD_LOGIC; d_in : in STD_LOGIC; d_out : out STD_LOGIC); end Delay_one_clock; architecture Behavioral of Delay_one_clock is begin pass_on : process( clk, rst ) is begin if (rst='1') then d_out <= '0'; elsif (clk'event and clk = '1') then d_out <= d_in; end if; end process pass_on; end Behavioral; ======================================================= entity Generate_Sclk_event is Port ( clk : in STD_LOGIC; rst : in STD_LOGIC; sclk : in STD_LOGIC; delayed_sclk : in STD_LOGIC; sclk_event : out STD_LOGIC); end Generate_Sclk_event; architecture Behavioral of Generate_Sclk_event is begin Genrate_clk_event : process( clk, rst ) is begin if (rst='1') then sclk_event <= '0'; elsif rising_edge(clk) then -- if sclk rising_edge if (sclk = '1' and delayed_sclk = '0') then sclk_event <= '1'; else sclk_event <= '0'; end if; end if; end process; end Behavioral; ========================================================= Then the process with the shif register: entity Generate_Sclk_event is Port ( clk : in STD_LOGIC; rst : in STD_LOGIC; sclk : in STD_LOGIC; sclk_event : out STD_LOGIC); end Generate_Sclk_event; architecture Behavioral of Generate_Sclk_event is signal Sclk_samples : STD_LOGIC_VECTOR(1 downto 0); begin Genrate_clk_event : process( clk, rst ) is begin if (rst='1') then sclk_event <= '0'; Sclk_samples <= "00"; elsif rising_edge(clk) then Sclk_samples(1) <= sclk_samples(0); Sclk_samples(0) <= sclk; -- if sclk rising_edge if(Sclk_samples = "01") then sclk_event <= '1'; else sclk_event <= '0'; end if; end if; end process; end Behavioral; Any help i appriciated Muggi |
|
相关推荐
7个回答
|
|
可能不会。
如果您的SPI接口与我见过的其他接口相似,则数据在一条边上发生变化,另一条边采样。 因此,数据在采样边缘周围是稳定的。 特别是它长时间保持稳定 - 5 125 MHz时钟(40 ns) - 足够长以防止违反输入触发器的建立/保持时间。 因为您(可能)仅对SPI时钟边沿采样数据和从机选择,所以它们仅在数据稳定时进行采样。 这很好。 时钟是个例外 - 你不断对其进行采样,因此它需要通过同步器。 顺便提一下,同步总线的多个位是导致偶然的位错误的好方法。 同步器是概率设备。 如果你有两个采样两个一起改变的位,那么一个同步器的输出可能比另一个同步1位。 解决此问题的简单方法只是同步一位 - 特别是时钟或数据使能,然后使用该同步控制信号对其余位进行采样。 在原帖中查看解决方案 以上来自于谷歌翻译 以下为原文 Probably not. If your SPI interface is like others I've seen, data changes on one edge and is sampled with the other. As such, the data is stable around the sampling edge. In particular, it's been stable for a whole long time - 5 125 MHz clocks (40 ns) - well long enough to prevent violation of the setup/hold times of the input flip-flop. Because you (probably) only sample the data and the slave select at a SPI clock edge, they're only sampled when the data is stable. This is good. The clock is the exception though - you're sampling it constantly, so it needs to go through a synchronizer. Incidentally, synchronizing multiple bits of a bus is a good way to cause occasional bit errors. Synchronizers are probabilistic device. If you have two of them sampling two bits that are changing together, there's a chance the output of one synchronizer may be 1 bit ahead of the other. The easy way to fix this is only to synchronize one bit - specifically a clock or a data enable, and then use that synchronized control signal to sample the rest of the bits. View solution in original post |
|
|
|
事实上,您的SPI时钟频率远低于系统时钟频率,因此无法直接在系统时钟域中对其进行采样。
如果SPI时钟由与系统时钟有任何不同的振荡器生成(即使它们的频率相同),SPI时钟与系统时钟振荡器异步。 因此,它偶尔会违反FPGA上输入触发器的建立或保持时间要求,导致触发器在某个(尽管很短)的时间内变为亚稳态。 这个事实是很多FPGA问题的根源。 幸运的是,解决方案非常简单。 同步器是一个两位移位寄存器,可将亚稳输出的几率降低到统计上不显着的数字。 如果您将SPI时钟通过同步器然后边沿检测它,则边缘检测电路基本上不会“看”亚稳输出。 以上来自于谷歌翻译 以下为原文 The fact that your SPI clock frequency is much less than your system clock frequency in no way makes it "safe" to sample it directly in the system clock domain. If the SPI clock is being generated by an oscillator that is in any way different from your system clock (even if they are the same frequency), the SPI clock is asynchronous to your system clock oscillator. As such, it will occasionally violate the setup or hold time requirements of the input flip-flop on the FPGA, causing that flip-flop to go metastable for a certain (albeit short) amount of time. This fact is the source of quite a few FPGA problems. The solution is fortunately quite simple. A synchronizer is a two bit shift register that reduces the chances of a metastable output to a statistically insignificant figure. If you put the SPI clock through a synchronizer and then edge detect it, there's essentially no chance your edge detection circuit will be "looking at" a metastable output. |
|
|
|
谢谢你的帮助,
当我假设我的第二个解决方案中的移位寄存器将作为同步器工作时,我是对的吗? 以上来自于谷歌翻译 以下为原文 Thanks for your help, Am I right when I assume that the shift register in my second solution will work as a synchronizer? |
|
|
|
从技术上讲,在第二种解决方案中,您不是通过同步器放置SPI时钟。
输入和信号使用位置之间只有一个寄存器。 你可以经常使用“慢速”时钟和“快速”FPGA来摆脱这种情况,但这不是一个好的设计实践,可以改变构建。 我建议你让Sclk_samples成为一个3位向量,然后只比较最重要的两位。 以上来自于谷歌翻译 以下为原文 Technically, you're not putting the SPI clock through a synchronizer in the second solution. There's only one register between the input and where you use the signal. You can often-times get away with that with a "slow" clock and a "fast" FPGA, but it's not good design practice and can vary build to build. I would suggest you make Sclk_samples a 3 bit vector and then compare only the most significant two bits. |
|
|
|
非常感谢,
我见过使用3位向量代替2位的例子......现在我知道为什么了! 当我开始考虑它时,我想我必须在我的数据信号和芯片选择信号上使用同步器,对吧? 以上来自于谷歌翻译 以下为原文 Thanks a lot, I have seen examples using a 3 bit vector in stead of a 2 bit... Now I know why! When I come to think about i it, I guess I have to use a synchronizer on my data signals and my chip select signal, right? |
|
|
|
可能不会。
如果您的SPI接口与我见过的其他接口相似,则数据在一条边上发生变化,另一条边采样。 因此,数据在采样边缘周围是稳定的。 特别是它长时间保持稳定 - 5 125 MHz时钟(40 ns) - 足够长以防止违反输入触发器的建立/保持时间。 因为您(可能)仅对SPI时钟边沿采样数据和从机选择,所以它们仅在数据稳定时进行采样。 这很好。 时钟是个例外 - 你不断对其进行采样,因此它需要通过同步器。 顺便提一下,同步总线的多个位是导致偶然的位错误的好方法。 同步器是概率设备。 如果你有两个采样两个一起改变的位,那么一个同步器的输出可能比另一个同步1位。 解决此问题的简单方法只是同步一位 - 特别是时钟或数据使能,然后使用该同步控制信号对其余位进行采样。 以上来自于谷歌翻译 以下为原文 Probably not. If your SPI interface is like others I've seen, data changes on one edge and is sampled with the other. As such, the data is stable around the sampling edge. In particular, it's been stable for a whole long time - 5 125 MHz clocks (40 ns) - well long enough to prevent violation of the setup/hold times of the input flip-flop. Because you (probably) only sample the data and the slave select at a SPI clock edge, they're only sampled when the data is stable. This is good. The clock is the exception though - you're sampling it constantly, so it needs to go through a synchronizer. Incidentally, synchronizing multiple bits of a bus is a good way to cause occasional bit errors. Synchronizers are probabilistic device. If you have two of them sampling two bits that are changing together, there's a chance the output of one synchronizer may be 1 bit ahead of the other. The easy way to fix this is only to synchronize one bit - specifically a clock or a data enable, and then use that synchronized control signal to sample the rest of the bits. |
|
|
|
@bialkenthanks的重要解释。
2个问题,如果我可以: 1)通过2-FF同步器传递输入数据线是好还是好,以保持数据时序更好地与同时通过2-FF同步器的时钟对齐? 当您尝试同步并行总线时,我已经阅读了可能出现的问题,但在这种情况下,数据输入只是一个信号。 2)我知道有一个简写符号,使用std_logic_vector以紧凑的方式编写同步器。 你能举个例子吗? 3)从哪里获得5个时钟周期(40ns),这是一个3级同步器,然后是2级边缘检测器? **如果答案是有帮助的话,那就是kudo。 如果您的问题得到解答,请接受解决方案 以上来自于谷歌翻译 以下为原文 @bialken thanks for the great explanation. 2 questions if I may : 1) would it be good / ok to pass the incoming data line also through a 2-FF synchroniser, in order to keep the data timing better aligned with the clock that went also through a 2-FF synchroniser? I've read about possible issues when you try to synchronize parallel busses, but in this case data in is only a single signal. 2) I know there is a short-hand notation using a std_logic_vector to write a synchronizer in a compact way. Could you show an example maybe? 3) where do you get the 5 clock cycles from (40ns), is this of a 3-stage synchronizer followed by 2-stage edge detector? ** kudo if the answer was helpfull. Accept as solution if your question is answered ** |
|
|
|
只有小组成员才能发言,加入小组>>
2270 浏览 7 评论
2682 浏览 4 评论
Spartan 3-AN时钟和VHDL让ISE合成时出现错误该怎么办?
2167 浏览 9 评论
3235 浏览 0 评论
如何在RTL或xilinx spartan fpga的约束文件中插入1.56ns延迟缓冲区?
2308 浏览 15 评论
有输入,但是LVDS_25的FPGA内部接收不到数据,为什么?
556浏览 1评论
1633浏览 1评论
126浏览 1评论
在使用xc5vsx95T时JTAG扫片不成功,测量TDO无信号输出
2278浏览 0评论
595浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-14 00:21 , Processed in 1.279893 second(s), Total 88, Slave 72 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191