功能分解:
将大的功能,再进一步的细化,做一个MCU的子系统,里面有两个MCU,那有几个block?这个东西之间是怎么进行数据的交换的?时钟是怎么管理的?可以再把它细化,那细化的目的就是模块化,为接下来的这个设计做准备,那这个划分就不能胡划分,把一些功能上不太相关的放在一块儿去,一定是紧耦合的。这些模块呢,它的功能连接关系跨到一块去,不能把两个模块弄得很远,因为里面的线特别多,光连线的工作量都受不了。
那就像刚才讲的MCU的子系统,架构师跟画出来了,那去把这个细分一下,那code用的什么样的code?bus是什么样子?local的memory,size是多少?ROM size是多少?给你的地址空间里面有没有中断,中断怎么连接进来,clock,reset,这些就是由上往下,由大到小,中间的细化,划分到我们设计人员能够直接上手,形成所谓的design spec。
因为我们的来源是architecturer那边,如果是形成设计规范以后,各个公司尽管名字不太一致,那么形成设计规范以后呢,实际上是需要跟原来的架构师一起去review的。让他们来看一下,你要怎么样做,以及与这个模块相关的其他的人一起review一下,看这个模块,要输出哪些信号给到你这边,是同步的,还是异步的,CDC在哪边做?那设计规范就很重要了。designer拿着去做design,verification拿着它开始做VO,都是基于这个的。
有同学说,一开始可能是performance没有想好,也没有想清楚,ROM跟我的RAM,signs,以及时钟频率一开始可能有点低估了,现在需要提高一下。如果有这种变更,你需要有非常明确的理由和说明,以及可以追踪的记录。不能说跟张三商量,跟李四商量,感觉好像不行那就改。,或者你不说,自己内部悄悄地改了,顶层的spec不知道,那一定会出问题的,一般的公司里都会有一些机制,相应的流程,去保证改动能够给到大家。
就刚才讲的,如果是clock变了,你发现时钟频率不对,需要提高,但是我一路clock,可能又不行,需要两路clock,那这两个clock之间,是异步的,是同步的,就说我的这个时钟的分频管理不想local,就想做到center,作为一个模块去管理clock的一个单元,那你要提需求,说一个clock在我里边有点麻烦,不想local做分频,看能不能再给我提供一路,类似的道理。
那有了这个design spec,就可以开始我们的coding了。
功能设计:
coding我们还是推荐模块化的设计。你说过我就是那个top down,一个MCU,就在一个module里面从头写到底,这是不推荐。就算你很牛,也不要这样子。还是把它写成小的模块,这样设计看着清晰,层次清晰,验证的时候从每一个小模块开始,也容易去进行验证。这就是我们推荐的模块化设计。
module是verilog里面的最基本的单元。比如,张三去开发这个模块,李四,去开发那个模块,最后由小明同top回来,作为一个integration集成起来,对外的接口,这样很清晰,对于系统的集成是这样子,就是说不要小看集成的工作量,对一个非常复杂的ASIC,如果里边的模块非常之多,功能非常复杂,集成的工作量也是非常大的,并且难度也非常的高,一方面是体力活,另一方面需要非常的认真,细致,有经验,这个人一定要经常性的与各个model owner保持沟通。所以说一定就是做TOP LEVEL INTEGRATION的这个人一定要与各个module owner充分的交流,把这些integration的东西也写到一个文档里面去,这个信号是从哪里来的?到哪里去?前面是谁?后面是谁?是不是这样子?有没有理解上的偏差?这就是负责这个top level同学的工作。
刚才提到了模块化设计,那一旦到了这个程度,实际上大家可以开始工作了,那coding现在用的比较多的国内大学,比较流行的是verilog,VHDL用的相对来说少一些,那VHDL更加的严谨,verilog可能会更加的自由。
举个例子,VHDL编译的时候,文件的先后顺序要有非常严格的规定,但verilog就不是这样子,只要在里面有,就没有问题。
那在coding的时候,无非就是两个大的方向,要么是靠平台的,要么是sequential。还有一些IP,比如说,像一些SRAM,一开始的时候,前期的时候呢,也不知道是要到哪个foundry,就写一些module。那最后就要注意了,这个一定要做replace ment,要换成你对应的那个foundry的,提供的memory compiler产生出来的SRAM。并且相应的端口要跟人家匹配上,可能一开始写了一个clock,一个过来read,没有CSB,人家版本一定是有CSB,memory里边是没有reset的。像这些工作一定要后面的再去替换一下。
时序逻辑:
那对时序逻辑来讲,这是我们工作的一个重点,当然也是一个难点,难是因为面对的时序逻辑,各种各样的,非常的复杂。同步的还是异步的?有没有CTC的问题?data pass是不是太长了?要不要加pipeline?一个复杂的ASIC里边,只有一个clock吗?显然不是的,那怎么来管理?还有前面我们讲到的reset管理,那如果说这个ASIC是一个嵌入式的应用,那可能对功耗比较敏,那这时候就需要我们想一些别的策略跟方式了。是不是要花费一些power的domain,把一些系统待机的时候关掉,可以加clock getting,这个clock getting不是说综合的时候,DC自动给我插入的,而是在前端人为的,有意识的引入一些functional clock getting。
我知道在某种应用场景底下,某些模块是不工作的。比如说这里边,有另外一个模块,clock过来给到这儿来,那我知道在待机的时候。A是需要工作的,B and ,C是不需要工作的,那可不可以在这个地方人为插入clock getting。在这个地方也插入一个random。
如果说内部有硬件信号,可以自动加它的EN上面去,这个clock getting,或者说是可以加到寄存器里面,然后软件,这个寄存器,或者clock getting,那这个时候功耗就可以降下来。如果系统起来的时候,软件再把clock getting disable掉,它就正常的工作,甚至说在前端,我这个PLL,进入类似于说某一种提供好的模式的时候,可不可以把这个PLL的频率降下来。起来的时候,再把频率给升上来,这些都是在设计的时候要考虑的。另外,这个地方还讲了CDC,CDC也是我们在数字设计当中经常出错的一些东西,关于CDC的处理,不同的clock的domain之间,实际上是有讲究的。比如说从domain到另一个domain,那有信号要传输的时候,如果说这个信号,这些准静态的信号,通过简单的domain,把一个一位的信号从一个domain转到另一个domain去,它是准静态的。我就一个两极flip flop串起来的,或者说是要高速的里边,我三级,四级的比较少见。那还有一些,从domain到这另一个domain,时间脉冲信号,那这个时候呢就不能通过简单的二级触发器进行同步了,可能需要一些特殊的单元来达到这个功能的目的,他也不是没有条件限制,产生的时候,2个之间隔得太近了,因为我们PTP在反感本身来讲,它的应用原理,一般是把pass要进行展宽,同步过去以后再做成pass,所以说如果是两个pass离得太近的时候。那就混叠了,如果很关键,就会丢失信息了,这是单位的信号的CDC。
那如果说,是一个bus的信号,那这个store又不一样了,一些很宽的bus信号的一些data,如果是简单的通过这个synchronizer去传输的时候,可能会有问题了,因为它不能保障在同一个cycle同时发生变化,通不过以后,出来的数据可能就有问题了。那如果说这个数据很宽,还是通过简单的synchronizer打过去,到这边来以后,发一个人request过去,说这个信号已经打过来了。那这边它过了一段时间以后,说好的,好的这个东西我收到了。那好,这边DS通过这种类似于握手的机制,value这么一种机制,这个也是可以的,那还有一些就是所谓的异步的FIFO可以解决这些问题,这个话题呢,比较宽,希望同学们在自己的学习中,实践中逐渐的去扩展。
状态机的设计:
另外数字的sequential logical当中,我们用的非常多的就是FSM有限状态机。那有限状态机根据这个同学们只要学过数电的都有这个基础,那就是两大类,那输出,如果说是只和这个状态有关系,说的是输出只和状态关系,那就是Moore类型的。那如果你这个输出既和当前的状态有关系,又和这个输入信号有关系,那就是Mealy类型的,简单的表示出来就这个样子,
那状态机核心就是说我这个地方有一个类似于存储的状态的,current_state他可以简化成这个a register或者flip flop。另外就是,根据你的输入以及现在的状态来产生你这个下一个状态,下一个状态一定是在这儿,你现在的状态是在这儿。就是你寄存着的,现在的状态,现在的状态跟输入决定下一个状态。这是一个类似抽象的模型。那从这个上面来看,我们一般来看就说这个地方对应着一个sequential,这个地方呢,一般就是我们combination,那么输出这个地方不一定,这个地方尽管我这个地方画的是combination,那很多情况下,实际上是推荐这个地方flip flop输出。OK,状态机的设计,那这个也是很重要,就是说你这个初始状态,进入一个初始状态,另外就是你写的时候,你要有当你这个条件不满足呀,或者发出突变的时候啊,你的逻辑,它对吧,保证你这个逻辑不会陷入一个错误的地方。路对吧,那个只恢复。写的时候呢,比如你的那个case要有地方,IF ELSE执行这个默认的状态。
那从状态机的这个编码上来讲,那比如说,我们有这种最常用的这个二进制,比如说,我有四个状态,0001,1011,那这个时候呢,他可能就需要两个flip flop。那还有的。还有的比如说,我要用格雷码00,01,11,10,这也是可以的,这个格雷码呢,尤其是在我们这个异步FIFO当中,我会经常用到格雷码。
另外呢,还有很多同学喜欢用格雷码,就是每一个里边大家看一下,只有一个一,那和上面比起来,比如说还是四个状态,那你这个地方需要的flip flop跟这边需要两个相比,那你就加倍了,需要四个,但是它有它的好处。它的坏处要看到很清楚,就是用的状态机,用的触发器数量比较多,但是它可以减少你这个时间状态机和组合逻辑的数目。实际上,反而你返回去的那个地方,这个逻辑反而简单,因为它的速度可能会高一些。那另外还有一个什么好处呢?就是有时候,我们有时候要做ECO,或者什么什么的时候,FIX的收获这个,完好的有时候就比较好用。另外呢你这个东西啊,如果是要加到monitor signal里边,你进行观测的时候也比较好。你一看,哪一个为哪一个当主机,你就知道你现在是在哪个state。前面提到的格雷码大家看一下那个规律,这个东西同学们,我们都有所耳闻,就是如果你是临近变化的时候相连的这个数值之间变化的时候,每次只有一位发生变化。比方说00到01,低位变了,然后进行了最高位变,变化了以后,再最低位遍,每次只有一变化。这个刚才我也提到了,我们在这个异步FIFO当中使用这个东西,它作为我们这个异步FIFO的指针记数。在从read的clock domain到write 的clock domain,以及write clock domain传到read clock domain。格雷码以后就可以用简单的同步器,它进行同步,因为每次只有一位发生变化。尽管它是很多位的数据,那我用这种简单的同步器同步这种数据是没有问题的。它最多是有一个cycle的delay,不会出错。
状态机:注意事项
另外这个状态机,就是说你写完这个状态机啊,最好是把它夹到你的这个staut STREET里面。这样的,你顶层的软件,有能力知道你目前状态机的运行,比如说,有时候我这个软件跑飞了,或者这个有挂死了。我能够通过某种手段,把我这个状态读出来,知道这个状态,不对啊,应该是在这个状态A呀,它现在怎么在状态B啊,我在进一步的去分析,一步一步地找到这个root cause在什么地方,另外我们还有一个推荐,就是把这个状态机,如果有可能,加到这个monitor LIST当中去,通过派的人都说可以直接观测的这样的,万一出现问题的时候,对于你这个定位分析,你的问题的这个点也是非常有帮助的。状态机是这样的啊,实际上做起来同学问题都很多。都学过,它的写法,比方说,有这个两段式的,有一段式的,就是说,所谓两段式的就说我一个是sequential的,我只描述我状态的转换。if reset,next_state等于0,else connect_state,简单就这样,然后呢,我另外一个这个always @(clock),就去写什么,上面那是肯定是sequential的,里面地用用这个了long logical assignment,那紧接着我有一个always,我是组合逻辑的,来描述我这个状态的翻转。
那这个地方,大家注意写的时候,一定是always @(posedge clk or negedge clk),写完这个地方呢,如果想不清的时候写个always @(*),把所有的信号包含进去,跟这个数字相关的,来描述一个状态的翻转转。那我们在接下来的这个课程实践当中呢,是需要同学们的写这个状态机的,所以说这个,同学们接下来可以再去把课本翻一翻。
SRAM的替换:
另外就是SRAM的替换。这个呢,我提到的就说SRAM,比如说像TSMC的呀,你可能都会用到,那你需要把你原来的RTL当中写的这个你的behavior的module。一般我们说写一些二位的数组,比如说你这是63,举个例子来讲,他down为零,你这个位宽呢,是[31:0]。当然memory初始化呢,你不能一句话写完。它必须是一个一个的进行这个初始化。那我们真正真正的将来要,我最后我就就是想要用这个flip flop来实现可以没问题的,功能上没问题,他可能速度还挺快的,问题在哪儿啊,面积大,但63个还好,那如果这个地方,大家想象一下,如果是1024呢,1023呢,如果是很大的时候,那这你看本身光这个宽度就差不多是1K了,如果按照BIT来这就是四个,那就是4K。那你这个还是不小的。如果说用这个寄存器来做这个东西,到时候面积可能受不了,面积挺大的,两步就要换成这个SRAM了。那这个东西,一定要根据它的Foudry这个东西也要对应起来,那我们一般写这个东西的时候很简单,我们只是说上面的端口,我就说有一个进来的,你就进来,又出去的对吧?这边有CLOCK,有read clock,那你要换成module的的时候,要注意了,就是说你这个东西要做相应的修改,人家那个module真真正正的那个compiler产生出来的那个东西,就是说你希望我这个东西啊,有速度很快就是一个计算机堆。类似于他还是90发了CLOCK发了对吧?像这种类型的那你要把那个port相应的修改,那一种方式,就是刚才我提到的,你说呀,我也拿不到那东西,你就if define一个东西,用我的或者else,其他的你可以先空着。因为这个东西还有一个就是,你比如说你换到这个FPGA上去的时候,人家FPGA上有自己的这个真真正正,跟你这个东西又不太一样。这是关于ARAM。
经典电路的学习:
另外就是在这个学习当中呢,希望同学们要注意这个经典电路的学习,收藏。那这些东西一定是在理解的基础上,你不能说是我把它的code,我把它抄下来。我存到U盘了,我随身携带,这样不太好,你把它理解,你说谁去记那个code,很难。但是,你起码你把它的原理都清清楚楚的记着,这样有助于你到时候去分析一下更加复杂的电路。那比如说前面大家讲过的这些深刻的代码,以及我提到的,特别告诉你,就刚才我听过一会切夫对吧?就像这些。还有这个,APB的bridge,这些东西就是说,同学们见了以后,花点时间就可以去研究研究。如果有可能有波形更好了。对照着波形,把这些电路吃透,这些对于我们初学者来讲是非常重要的。不能说我们初学者一开始的时候,我就知道有这么多东西,知其然不知其所以然,这样是不推荐。
可测性设计(DFT):
那前面讲的呢,都是我们的这个designer做的,还有一个很重要的是前面我也提到的就是所谓我们的design for test。你费了半天劲,你把这个东西设计出来了,你也去生产了,回来以后有问题,你分析半天就说我设计上没问题啊!是的,可能确实不是你设计引起来了,可能是用于制造听引起来的。那我们要有这个DFT,这跟我们design应该是并行的,并且在我们项目的早期,根据我们产品的这个要求,我们就要开始制定我们的design for test。我是只有边界 scan就OK了,也要关注。那我port的流,我的EDT出来以后,我就多少个port,我的开始靠个怎么往里打。我怎么shift出来,这些早期的时候,都要进行考虑。我上面有很多memory。那我一个MBIST对的地址,要是测试的对吧,可能都是受这个太不看出来的感触进去控制它,那我所有的memory,我是并行一起开始的,还是说我要划分成不同的块,为什么要这样做呢,因为我们知道memory作bist的时候,他一般是跑到这个function clock。memory如果是跑到这个同时并行起来跑的话,这个电流是非常之大的,那对于大型的ASIC大型的SOC,一般的策略来讲,分开,一块儿一块儿的来做,不要说是一起坐。这个时候,可能有时候电流太大,就给烧了。还有一些,我上面有很多analog的IP,比如说我上面有很多这个ADC,有很多这个锁相环PLL,我一定要去看一下这些东西,它本身有没有提供这种CF TEST的手段,我怎么来充分利用它,我身上designer自己通过寄存器的方式,它控制它,把它相应的信号routing到pad上去,还是说怎么着,还就说我DFT的同事统一考虑,我设计某一种TEST mod,比方说ADC的TEST MOD,PLL的TEST mod,我会把Pll内部的可到signal,routing到我的一些特殊的pad上去,为什么要这样做呢?
因为PLL来讲一般,我们也不PLL就是想让他。但是,如果我们直接把它的信号routing到我们pad上去啊。可能我那pad承受不起。因为我们的pad受限于它的这个复杂性以及它一般是工作,在两个这个电源,与那他的工作频率,不能太高,那你比方说,你有一个PLL,它是八百兆,那你这个东西,我也把原始输出的这个PLL的clock,直接从pad输出,这可能是不现实,可能我们的pad也就只能输出几百兆甚至一百多兆,那我就要想办法呀,那输出到这儿来之前我们看一下PLL本身是不是内部已经提供了一些divider分频电路,还是说,我需要人为的引入一些分频电路,这些都是需要考虑的。还有一些比较复杂的fan,测试的时候我外边不可能去产生出它所需要的那种系列的波形来,它自己能产生,那我是不是要一些loop back啊,它自己产生出来以后,loop back,用这没问题,那就证明它这个pass 是OK的,诸如此类,这个都是需要来设计阶段进行考量的。那DFT给我们的来讲呢,一般的,现在目前一般的大型的公司呢,专门会有一个这个做DFT的这么一个team,那这个地方呢,我给同学们做一些宣传。同学们,如果将来有机会从事DFT的工作,一定要牢牢地把握。DFT,也是一个非常重要的方向。这个也是你随着你这个经验的积累啊,这个也是很好的。重点给同学们推荐一下啊,也是非常好的,希望同学们多多的看一下,当然DFT这个东西是这样子啊,有时候你也看了半天,学了半天,你也仅仅是知道了个皮毛。是因为那是纸上谈兵,你必须是到实践当中去,但是有一些基本的知识你是可以提前掌握的,因为现在各个公司的这些设计方案呢,也是做得越来越友好,减轻对这个DFT这个深入这个基本功的这种依赖性,他们做的,尽量的让DFT更容易,跟你来那个做好,但是呢,还是需要我们认真把握的把这些东西呢,把握住。DFT因为他自己的一些仿真的策略,仿真的手段。OK,这是DFT,总而言之DFT很重要,就可以同学们的提个醒,如果将来你有机会从事DFT,你要记住,有一片Andy老师给我讲过啊,我一定要坚持下去,DFT是非常有前景的也是非常重要的。
功能仿真:
那我们把设计做完,一个很重要的工作是什么,实际上不说做完了,实际上我们的设计的过程中,就是我们的仿真。我们的simulation,我们那边说K我们的一名了一审对吧,不同的公司有不同的叫法,那功能验证,这是我们代码,就是说我们作为designer,因为我们今天讲的主要是针对DE来讲的,就是design来讲的。这是你有relist,因为你每一个节点,你比如说我做完了这个一个设计,一个MCU的子系统,你可以迭代没有问题的。没有人说是我一把就成功了,你可能要逐步的添加你的功能。但是你有按节点,根据公司的这个进度节点。在RELEASE之前肯定要做一些必要的检查,比如说像这个功能的验证,编译过,这是必须的,你说compilation,我里面有error,这是不可饶恕的。有时候你这个里边还有编译错误你就发布了,这是不可接受的。那编译正确了,你还要保证你的工具去能够跑起来。最好也让他跑一下,Chock一些波形。这个不依赖于鉴证人员,是我们设计人员本身要做的事情。弄一个简单的testbench,过一些简单的激励,跑一跑。你不要说是因为我们知道你编译过了,并不意味着你的东西run的时候,没有问题,你的elaboration的时候,没有问题,这是两个不同的概念,同学们要牢牢的记住这个,一定要跑起来,看一下我输入信号OK的时候输出起码不要事情实现X态太,这是不好的。另外我们现在这些那个工具都很强,他会给你一些linting的东西,有时候如果你不清楚,到这个综合时候就会有问题。
举个例子来讲,我们一直提到这个clock getting,就刚才我还是拿这个例子来讲,我这有一个A模块。那我这个地方,我要加一个clock getting sale,这是一个function。那你跑的时候,他这个地方,他一定会给你如果你这个给你写的是的非常经典的的话,一定会给你报error的。它说,你这个不好,你这个地面里边了,有个赖吃。那我们要去判断这个是合理,因为我这个在一开始写的时候,我没有拿到对应的Foudry里边的那个库单元中的这个CG的这个,我一定是我自己拿verilog去写的。那这个地方,他也会给你报一个error,不是warning,它报error只是提醒你,你要去看一下,我本来就是个CG这个是必须的,那你就放心了。
除此之外,如果说别的地方,还报了一个,那你就要注意了,你是不是写的时候,你的always block没有写完整,你的CASE语句没有写完整,你的if else没有写完整。因为我们一般的design当中,现在我们都是基于这个flip flop,或者叫verd rist,我们不推荐,出现这种latch,像这种东西都是很重要的,另外就像CDC,clock domain的CHECK以及reset domain的check,这些都是非常重要的就说哎呀,我就不care!我这个我能保证,我认为reset的时候呢,我能够保证,我先reset,我在reset的时候我把clock停掉。我绿reset完了以后,我再把这个clock再打开,能做到这个,我就不care这个东西,那你可以把它给我一会儿拿掉。就像这些东西,就是说我们作为这个DE,作为设计人员一定要多考虑一步,多想一步。因为你的写完的这个code,最终是要去做综合的,要综合从网表。如果等到后期DC的人回过头来,再找你的时候,那个时候就比较尴尬,如果说,等着人家TOP level integration的人弄完的时候,一编译出错的时候,来找你的话,那属于比较尴尬。这是我们作为一个DE的人员,我们有义务,我们也应该保证它的编译没有问题,它的运行没有问题,它的基本的功能没问题。达到了这些标准以后,我们再去种类似我们的code。
当然,各个公司目前来讲,他都有自己的发布标准,我这个提的呢,可能是比较简单的,人家有的呢,可能会更严格对更严格。你这个做到了以后,你就是累死。那如果他没有这个,希望同学们的记住我今天讲的这些,做完了以后,我就看一看,因为有时候是这样子。你即使是做完了,你肯定这个仿真没有问题,那如果波形好,就没有问题吗?那不一定。因为最终你这个东西,是要给到DC做综合的,有映射到人家lib里面的那些非要上去,能映射过去吗?这是我们要讲的这个所谓的这个code的发布之前的功能验证。
未完-待续......
上一篇:
叩持电子(IC修真院)ASIC数字IC设计讲解(1)
下一篇:
IC修真院_关于芯片制造与芯片封测的那些事儿