慢速接口约束提要
记得我2年前在B站讲I2C和SPI的时候,有同学就说这个东西low,看不上。但实际上,如果你亲自上手写,特别是写一个slave,而且没有驱动时钟,纯靠SCL驱动,你就会知道它的难度。RTL代码量并不大,比较简单的两三百行就搞定了,但约束很麻烦,没点约束经验的,只会约束快速电路的,你约束不了慢速电路。
你看那些芯片datasheet中的I2C接口时序,都是以us作单位的,和我们习惯看的以ns和ps作单位的时序不同。以us作单位,是不是说电路很好约束呢?闭上眼随便约束,这电路也能用呢?当然没那么简单。因为这里面的坑在时钟质量上。我们平常的电路,时钟来自晶振、RCO、PLL,质量都很好,它的trans time很小,频率也稳定。但是I2C的时钟来自于外面,做实验的时候经常两根飞线接一起就开始用,时钟能好到哪去?时钟的trans极大,300ns算是好的情况。
周一我在专栏里粘了一张图,是一个简单的DFF,其lib库中的时序数据(看不清楚的去知乎上下载,我也放知乎一份),那上面明确写了,DFF的D端的setup和hold timing取决于D端信号的trans和时钟的trans。所以你会发现,这时钟trans一旦大了,setup和hold timing就跟着大,甚至大到几百ns,不是我们一般看大那种几ps。所以I2C在最快情况下也只能飙到4MHz左右,这不是没原因的,如果它的SCL能好一些,就不至于这样了。我们的lib表格一般也不会写这么大的trans,所以超出表格范围的数据,一般都要靠工具基于模型的推测,比如线性插值,卡曼预测。
注:有同学跟我讨论过generated时钟的trans是不是和master时钟有关,是相等的,还是分频的。从那张表也能看出来,有关系,但既不相等,也不是分频。generated时钟如果是分频出来的,那肯定也是从DFF输出的,是DFF输出,就要根据输入的trans和时钟trans进行查表,表上写多少就是多少,不是直接等于输入时钟的trans。级联分频,那最后的trans就是一级一级的输出时钟查表。道理简单,但查起来麻烦。
另一个麻烦的问题是数据和时钟混用。SCL主要用作时钟,但也有一小部分电路把它当作数据,SDA主要用作数据,但也有一小部分电路把它当作时钟。怎么约束这个关系?约束完以后,那些超长的setup和hold timing怎么满足?(大trans下setup数据还比较好,主要是hold要求太猛)。。。。有时候,master不提供你希望的波形,人家图方便,人家的波形是正确的,但你不容易用。比如SDA当时钟,采样SCL,容易误触发,容易亚稳态。master不配合你,你就得自己插delay,插多少delay合适?
快速电路,比拼的是工艺,你1ns,我10ps,更先进的1ps。慢速电路,工艺已经不重要了,1ps和1ns在1us眼里都是差不多长短,主要还是防止大的时钟和数据trans下时序不能满足,传出亚稳态的问题。
所以,即便是小小的慢速接口,也有这么多讲究,一失手芯片就死了。
其实,还有很多小芯片,虽然小,但并不简单。它卷,但不只是拼命压价格,还卷技术,只不过没法用好的技术,好的技术协议不支持,或者成本不允许,市场不认可,你就必须用low技术做到好效果,这个是真难,比用好技术做到好效果要难。
前几天跟一个软件的小伙儿聊嵌入式,他说做得很辛苦,但社会认可度不高。我说是这样,一些大类,比如手机CPU,GPU,你一说人家就认,做个什么高精度电容、晶振,很辛苦,想的问题多,做的测试多,写的代码多,但人家不认,这也没办法,社会就是这么个社会,你还能咋样呢。