研一,进组,正在0基础开始学习FPGA,蛮多东西都不太熟悉,所以在这里记录下那些难懂的点,随复习进度更新。(部分资料来源于网络搜索,侵删)
置顶:compile和eleborate常见问题可查询网址。
vivado常见compile和elaborate错误_module instantiation should have an instance name-CSDN博客
问题:非阻塞赋值为什么总是要延迟一个时钟周期?
一直没想明白,非阻塞赋值为什么是要延迟一个时钟周期才赋值,尤其是刚好时钟上升沿和数据垂直对齐的时候?(如下图,key_in上升沿和clk上升沿对齐了,但是led_out下一个周期才上拉)
当表达时序逻辑时如果时钟和数据是对齐的,则默认当前时钟沿采集到的数据为在该时钟上升沿前一时刻的值;当表达组合逻辑时如果时钟和数据是对齐的,则默认当前时钟沿采集到的数据为在该时钟上升沿同一时刻的值。
为什么?
我的理解是,当时钟上升沿来临时,这个时候数据的输入其实是时钟上升沿来临时左边一丢丢时间的数据,而非时钟来临时同样时刻的数据。不管同步还是异步D触发器,时序逻辑电路都有延一拍的特点。(这好像就是数电的知识啊,完全还给老师了)
进而引出
对于上述代码,使用非阻塞赋值和阻塞赋值的情况就会完全不同了。阻塞赋值会满足()内条件直接赋值,而非阻塞赋值必须等着CLK上升沿,如果()条件和CLK上升沿对齐,就必须等下一周期了。
问题:边沿检测如何实现?
刚学的时候的疑问:为什么不能直接posedge要检测的信号?
答:因为posedge和negedge这些带时钟的always电路,都是由寄存器构成的,一般只有一个时钟信号。
上升沿检测:~a_delay和a相与。
下降沿检测:a_delay和~a相与。(图同理上升沿)
双边沿检测:a_delay和a相异或。
双边沿检测可能存在的问题:下降沿检测的矩形波很窄,原因是此时clk和信号产生了巧合,但也能算检测到了,如下图。
易错点:各种过程块中被赋值的一定得是reg型,比如initial里面。
知识点:同步复位,异步释放(复位信号恢复时打两拍)
意义:
- 复位信号到来的有效与否与 clk 无关,而且复位信号的撤除也与 clk 无关,但是复位信号的撤除是在 下一个 clk 来到后才起的作用。
- 异步复位同步释放的目的为了防止复位信号撤除时,可能产生的亚稳态。
module sync_test( input clk, input rst_async_n //原始的复位信号 ); reg rst_s1; reg rst_s2; reg y; always @ (posedge clk or negedge rst_async_n) begin if (!rst_async_n) begin rst_s1 <= 1'b0; //复位 rst_s2 <= 1'b0; end else begin rst_s1 <= 1'b1; //复位信号恢复,打两拍 rst_s2 <= rst_s1; end end assign rst_sync_n = rst_s2; //打两拍之后的复位信号 always @ (posedge clk or negedge rst_sync_n ) begin if (rst_sync_n == 1'b0) y <= 1'b0 ; else y <= 1; end endmodule
易错点
reg [7:0] dpram [31:0]这句代码里[7:0]是指寄存器位宽,而[31:0]是指有32个8位的元素,前后不要弄混了。
跨时钟域处理
问题:为什么多比特不能采用打两拍的方法进行跨时钟域同步?
原因1:假设从时域A垮到时域B,是域A从00变到11,在时域B还能采样到从00变到11吗?在时域B中,时钟的上升沿来的时间是肯定一致的,但是各个bit从时域A到达时域B的时间是不一样的,slack不一样,亚稳态恢复到稳态的时间也是不一样的。因此也就是说00中的两个0并不是同时变成1的,因此子时域B中可能采到中间态01或10。
原因2:还有一个原因是单比特发送亚稳态的概率变成多bit后概率会大很多。我们不这样做是可以降低亚稳态发生的概率的。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。原文链接:https://blog.csdn.net/qq_38374491/article/details/119079054
下面给出亚稳态可能的情况https://xilinx.eetrend.com/blog/2023/100573876.htmlhttps://xilinx.eetrend.com/blog/2023/100573876.html
(1)单bit位宽数据两级同步情况
情况一:下图是在T0时刻发生了亚稳态,T1时刻Q1的输出已经稳定在高电平,且满足Tsu和Th,因此T1时刻,Q2就成功的锁存了高电平。
情况二:下图是在T0时刻发生了亚稳态,T1时刻Q1的输出已经稳定在低电平,且满足Tsu和Th,因此T1时刻,Q1重新成功的锁存了Q0的高电平,Q2成功的锁存了Q1的低电平。T2时刻,Q2成功的锁存了Q1的高电平。
可知Q2最终都会锁存到Q0的高电平。要么在T1时刻,要么在T2时刻。换句话说,Q2要么锁存旧数据,要么锁存到新数据。
(2)bit位宽数据两级同步情况
加入针对2bit数据的跨时钟域处理,也是采用两级打拍同步,又会出现什么情况呢。我们举例说明:原始数据为Q00和Q01,分别进行两级同步电路处理,最终输出Q20和Q21。
若T0时刻,Q0从2‘b00,跳变为2’b11,且Q10在亚稳态后,稳定在低电平,而Q11在亚稳态后,稳定在高电平。
最终Q2会在T2时刻,采样到2‘b11的数据。而在T1和T2之间采样到2’b10的数据。
换句话说,Q2不再是要么锁存Q0的旧数据,要么锁存到Q0的新数据,而是有可能出现其它的数据。假如电路中,通过Q2==2'b10产生脉冲来控制其它的逻辑,这里就会出现功能上的错误。
同理,更多bit的数据跨时钟域采用两级同步处理,情况类似。
AXI Interconnect
他里面的Number of Slave Interfaces不是指从机有多少个,而是指从机接口,相对应也就是主机的数量。Number of Master Interfaces同理。