IC设计笔记

原文链接:https://blog.csdn.net/evolone/article/details/73484041

一、关于Design

1.设计功能模块。

首先详细掌握模块功能。 
    然后定义接口信号,设计模块结构,尽可能复用逻辑资源。 
    最后再写代码。

对于定义接口信号,多说几句。 
  (1)如果是一个人独自完成,那么其实定义信号接口没有那么紧迫,毕竟自己啥都知道,随时可以调整,完成代码后再完善接口定义也行。 
  (2)但是,如果是几个人合作,那么就必须在开始敲代码前,一定要定义好信号接口,包括信号名/位宽/功能描述。并且,如果有更改添加,一定第一时间沟通并达成一致。否则,如果没有这样清晰接口定义,那么往往因为项目推进带来新变化及沟通不充分,造成不同人员之间的理解存在偏差,就会造成仿佛迭代的过程,进而影响项目推进速度。所谓,事倍功半。切记切记!

注意:接口中的控制信号尽可能用1bit表示,也就是说,模块需要用到的控制信号,尽可能是单个的使能信号。优点是方便以后写代码,如果信号名定义合理,能够一眼看出信号功能,那么还更容易维护。否则,如果信号采用几位数据进行编码,那么在design内部还需要解码,并且不容易看出信号的含义,给维护带来困难。甚至长时间不看,自己写的代码都会忘记功能而看不懂。

例如: 
    假设一个计算模块,计算类型有加、减、乘、除。 
    如何定义信号更有利于编写代码及后续维护? 
    (1)编码信号(强烈不推荐) 
    定义一个2bits的信号: 
    signal  caozuoleixin    :  std_ulogic_vector(0 to 1);  
                 – 假设: 
                                00 对应 加 
                                01 对应 减 
                                10 对应 乘 
                                11 对应 除 
   优点:接口信号数量少。 
   缺点:看到这个信号,并不能直接知道其含义,造成编写代码困难,也不利于之后对代码的维护。过了一段时间,自己看代码,如果没有清晰的注释,自己都不知道是什么含义。另外,就算有注释,可是你敢保证注释一定正确?就算注释正确,你还要再去核对编码,确认信号功能,费时费力。 
    所以,编码信号,墙裂不推荐!!!

(2)单bit独立信号 
定义4个1bit的信号: 
signal  add      : std_ulogic; – 加 
signal  sub      : std_ulogic; – 减 
signal  mul      : std_ulogic; – 乘 
signal  div       : std_ulogic; – 除

优点:信号功能清晰,方便编写代码,日后维护也更容易。 
缺点:接口信号数量增加。不过这一点点缺点,与带来的优点相比,完全可以忍受。

另外,编写代码时,经常有类似的代码段,会图省事直接copy然后修改。这样做,是可以提高效率,但是必须格外小心,要修改的地方,一定要做完整的修改。如果漏掉一些未修改的信号,那么就会在仿真时出错。往往还是一些特别难以找到的错误,匪夷所思的错误。血和泪的教训!!!!

今后,一定在修改的时候千万小心,做到对所有的代码进行了必须要的修改。

2.设计较大的模块的一些经验教训

当设计一个小模块时,上面的方法已经足够应付。 
下面说说,当设计模块更大时,我所踩过的坑。 
最近设计的一个东东,因为功能较为复杂,于是乎分成了几个小模块:筛选/排序/IOU 
而且有相互依赖关系:筛选 -> 排序 -> IOU 
为了方便debug,并减少无聊的代码,于是决定将几个模块都写在一个文件中,分段描述即可。 
首先完成第一个功能,筛选。 
很好,一切顺利。 
于是,开始写排序。 
排序的实现稍微复杂,花了一些时间。 
最后debug时,发现之前筛选的信号与排序的信号,混杂在一起,信号多,容易引起混乱。 
类似的信号名太多,容易混淆,看波形,也难以迅速准确找到对应的信号。给调试增加了难度。 
最后,总算,完成了,决定,下次还是老老实实将不同模块封装起来,虽然会形成多个文件,增加无聊的接口,但是,至少在调试的时候,会减少麻烦,减少出错的概率。

另外,说说我当时犯的一个错。 
我也不知道是怎么的,在调试排序代码的时候,一次仿真后,做了一系列修改后,再跑仿真,发现编译报错。 
于是去看错误的地方。 
然后,就发现,在之前的筛选的代码中,不知何时增加了一部分代码,细看下,发现应该说复制粘贴时出现的错误粘贴。而且,代码并不是完整的功能,而是后面用到的代码的一部分,开头的信号名都只有半个!!! 
估计是VIM操作时的误操作。 
惊出一身冷汗。 
还好这部分代码刚写没几天,还有印象,小心翼翼将错误代码删除,一跑仿真,通过! 
哈哈,还好。 
不过,还是后怕。 
如果是间隔很久的代码,我自己都忘记了,那怎么办? 
于是,决定,以后,还是老老实实写小模块,分成几个文件。虽然看似费事费时,但是至少不会无意间更改已经完成的代码。 
一定要分拆封装!!!

二、工具使用 
IC工具很多,使用何种工具看公司购买了哪些工具以及个人喜好。我一般使用VCS、Incisive编译仿真代码,用Verdi追信号,GPRO产生测试激励。 
1 Verdi 
使用Verdi看代码追信号,很方便。

如果只是看代码,那么操作很简单。 
(1)在Linux命令行中敲入verdi,就会启动Verdi的图形界面GUI。 
(2)点击File->Import Design。选择要加载的文件,进行加载即可。注意,GUI只支持Verilog,不支持VHDL。

2 VCS 
一般用VCS编译仿真,仿真阶段直接用-gui命令看波形,非常方便。

3 Incisive 
因为工具原因,有些VHDL语法不支持,所以编译现成的库代码都有问题,需要修改。 
所以,用的不多。

不过,Incisive有一个强大的功能:force。force直接将内部的寄存器在规定的时刻赋值。这样可以粗暴仿真出功能的波形。 
不过,这样做有不科学的地方,最好还是按照从接口信号往内部灌注的方法为好。
--------------------- 
版权声明:本文为CSDN博主「evolone」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/evolone/article/details/73484041

展开阅读全文

没有更多推荐了,返回首页