每一个做数字逻辑的都绕不开跨时钟域处理,谈一谈SpinalHDL里用于跨时钟域处理的一些手段方法。
打拍处理
BufferCC(input: T, init: T = null, bufferDepth: Int = 2)
bufferDepth可用于指定打拍级数。input信号的时钟域为源时钟域,BUfferCC调用的地方的时钟域为目的时钟域。
GrayCounter(width: Int, enable: Bool)
提供一个小demo,GtayCounter+BufferCC:
这里GrayCounter在时钟域clkA中实现,通过BufferCC将其跨时钟域至clkB,bufferDepth为3.Tips:BufferCC的第二个参数init数据类型是T,而T<:Data,即意味着init数据类型为“硬件”数据类型,因而上面init赋值需为U(0,8 bits)而不能直接写0 》》脉冲信号处理 脉冲信号的跨时钟域处理,SpinalHDL提供了PulseCCByToggle方法:
Bool,clockIn: ClockDomain,clockOut: ClockDomain): Bool :
握手处理
对于吞吐要求不是特别高的场合,跨时钟域信号采用握手形式 进行处理也是一种不错的选择。SpinalHDL有两个抽象类型个人一直很喜欢:Stream,Flow。这两种形式基本囊括了所有的信号交互行为,其也可以说是SpinalHDL lib库的基石。针对跨时钟域的握手处理,SpinalHDL有一个StreamCCByToggle可以使用:
StreamCCByToggle(input: Stream[T], inputClock: ClockDomain, outputClock: ClockDomain): Stream[T]
其输入参数包含源时钟域信号,源时钟域,目的时钟域,其返回一个目的时钟域的Stream信号:
这里srcIn隶属于时钟域clkA,destOut隶属于时钟域clkB。
val myFifo = StreamFifoCC(
dataType = Bits(8 bits),
depth = 128,
pushClock = clockA,
popClock = clockB
)
<< streamA
myFifo.io.pop >> streamB
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !