现将脉冲变成电平,同步之后再恢复,
1.下面是脉冲展电平的做法
2.下面是电平恢复脉冲
DEBUX通过一个同步到目标时钟域的信号作为目标时钟域多比特数据更新的使能信号
其实和demux很相像,先选择一个qualif的singal做同步,同步到ck2之后,用该信号做其他数据的选通信号。
apb的信号中只有psel和pready会做sync,其他都不直接sync
假设apb2apb的clk_1域为slave 端,需要同步到clk_2域master端
psel_s/penalbe_s/pwrite_s/paddr_s/pwdata_s 需要同步到clk_2
pready_m/prdata_m/pslverr_m需要同步到clk_1
这种情况比较简单,但是资源占的较多
slave--->master过程如下:
1.将psel_s&(~penable_s)这样一个pulse signal 经过脉冲同步到clk_2,为pulse_d
2.用pulse_d拉高psel_m,用psel_m & penable_m & pready_m 拉低psel_m
3.用pulse_d_ff1拉高penable_m,用psel_m & penable_m & pready_m 拉低penable_m
4.pwrite_m/paddr_m/pwdata_m直接赋值
以上地方直接赋值也可以用psel_m做个mux
assign pwrite_m = psel_m & pwrite_s;
assign paddr_m = psel_m & paddr_s;
assign pwdata_m = psel_m & pwdata_s;
master--->slave过程如下:
1.将psel_m & penable_m & pready_m形成的pulse 信号同步到clk_1做pready_s
2.用psel_m & penable_m & pready_m对prdata_m在clk_2域锁存,锁存的信号直接作为clk_1的prdata_s
3.用psel_m & penable_m & pready_m对pslverr_m在clk_2域锁存,锁存的信号直接作为clk_1的pslverr_s(和prdata_s一样)
上面的处理适合clk_s(apbclk)比较慢,而clk_d比较快的情况。
否则如果clk_s快,clk_d(clk_m)慢 从clk_s到clk_d的pulse_d来拉高psel_m,pulse_d_ff1来拉高penable_m,此时pwrite_s/paddr_s/pwdata_s是稳定的可以在clk_d直接采样了,是完全没有问题。但是从慢的clk_m同步到快的clk_s的pready_s为1时,此时被锁存的prdata_d和pslverr_m可能还没有被锁存(clk_m/pclk_d太慢)
这种情况下 肯定要存在一对信号 从clk_s到clk_m,在从clk_m到clk_s,双向都确认完毕之后在进行下一次传输。思路如下:
在clk_s用psel产生req_s,同步到clk_m, 为req_s2m,用于产生psel_m
用clk_m的pready产生ack_m,将ack_m同步到clk_s用于产生ack_s,用ack_s清req_s
在clk_m等待req_s2m拉低,这个时候clk_s和clk_m才算完成双向握手,一次apb传输完成。这里和脉冲同步时一个道理。
具体代码可以参考另一篇私人博客
apb2apb的asyncBridgehttps://blog.csdn.net/cy413026/article/details/128960805?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22128960805%22%2C%22source%22%3A%22cy413026%22%7D
当然这篇参考文档给的apbAsyncBridge的写法和coreSight中的写法实际是一致的。
coreSight说明可参考:
jtag2axi和coresight学习_cy413026的博客-CSDN博客