http://bbs.ednchina.com/BLOG_ARTICLE_164986.HTM
最近我女儿经常在用龙芯2号做的Linux PC上玩游戏。我告诉她这就是我们在九寨沟画的 方框“烧”出来的,她感到很诧异。在2002年8月10日龙芯1号首片调试成功之后,龙芯2号的设计工作又慢了下来,全组的主要力量放在了龙芯1号的系统开发上面。虽然由于龙芯1号的系统开发和性能分析耽误了一些时间,但我自己在龙芯1号上玩了近一个月后有很大的收获。尤其是对性能和主频的关系有了更深入的认识。比如,对于有一些访存密集的应用,主板频率83MHz而CPU频率250MHz时的性能还不如主板频率100MHz而CPU频率200MHz的性能。现在想起来,一个处理器的性能就象一个城市的交通系统的吞吐率,可能由于某几处的堵塞而影响整个城市的吞吐率,只要把这几处疏通了,虽然花的力气不大,但吞吐率会极大地提高。2002年9月28日龙芯1号发布会后,龙芯2号的设计工作全面展开。10月2日,我带着张福新和李祖松到母校中国科大利用十一长假进行龙芯2号的C模拟器封闭开发,顺便向母校报告一下我们的工作。在科大借了半间原来的库房呆了一个多星期,基本完成了C模拟器的代码编写。在对结构进行细化的过程中发现了好多原来没有考虑到的问题。对于这些问题我们有时候争辩得很激烈。例如在转移猜错取消时需要判断正在执行的指令中哪些是该转移指令前面的,哪些是该转移指令后面的,张福新和李祖松的观点是参照MIPS R10000使用的方法,而我觉得那个方法太麻烦,希望有更简洁的方法。我们一直争论了两天,在争论的过程中互相启发,终于找到了一种简洁而高效的方法。
2002年10月8日回北京时龙芯2号的C模拟器已经基本成型。我们继续在我的办公室进行半封闭式的开发,主要是继续完善C模拟器并开始调试。那段时间我们每周只有二、四、六晚上休息,其它时间都在调试。调试过程中也调动组里的其它人写了不少测试向量。11月中旬在C模拟器中成功启动LINUX操作系统,开始对C模拟器进行性能优化以加快模拟速度并用C模拟器对龙芯2号的结构进行性能分析。
在此期间以及以后的几个月内,我们在C模拟器上运行了完整的SPEC CPU2000的几乎所有程序以及八十年代比较流行的性能测试程序dhrystone和whetdstone等,对龙芯2号的性能进行初步的分析。在运行上述程序过程中还发现了不少设计上的bug和考虑不周的地方。印象比较深刻的是由于访存操作的乱序执行导致两个或多个访存操作之间互相替换CACHE 块并引起死锁。另外一件印象比较深刻的是MIPS指令系统规定转移指令的延迟槽指令不能是转移指令,否则处理器的行为不确定,但我们在C模拟器中发现在我们的设计中如果转移指令的延迟槽指令也是转移指令时也会导致处理器死锁。虽然这是由错误的程序引起的,但也是结构设计考虑不周的地方,对于错误的程序我们可以给出错误的结果,但不能把机器搞死。
由于张福新和李祖松的加入,龙芯2号的C模拟器比龙芯1号完善很多,包括checkpoint在内的很多功能都加到模拟器中,此外,C模拟器的运算速度也大大提高了。张福新还顺手开发了不少小工具。
2002年11月底,我觉得C模拟器已经基本稳定,就召开了龙芯1号总结以及龙芯2号部署的会议,全面部署龙芯2号的RTL设计工作。
2002年12月初我们组建了RTL设计的队伍,由于我们人手有限,RTL编写的人员都是从各组抽调的,我自己也负责寄存器重命名和几个队列模块。龙芯2号的RTL设计大致可以分为三个阶段。
第一阶段为设计阶段。从12月初开始大家花了约半个月的时间了解龙芯2号的结构,同时我开始进行顶层模块的设计,主要是每个模块的互连关系、接口总线及触发器的定义。12月28日完成顶层模块的设计并启动各模块RTL的编写。由于有Cycle-by-Cycle的C模拟器作为参照,2003年1月14日就完成所有模块RTL的编写并编译通过,1月21日成功运行第一条指令。在此基础上,经过三天三夜的努力,到1月25日成功运行龙芯1号中使用的包括所有MIPS指令的一段功能测试程序。由于2002年春节没有放假,因此1月25日后全组放假。
第二阶段为联调阶段。春节后开始在RTL仿真环境上运行LINUX操作系统。经过连续一个多星期的努力,2月18日成功运行LINUX操作系统。在龙芯1号的联调过程中,在运行LINUX后,整个流水线的设计就基本上没有发现什么问题,只发现了部分与浮点有关的问题。但在龙芯2号中,运行LINUX后试图运行whetdstone时碰到了巨大的困难,甚至一度出现停滞不前的情况。因为错误出现在调用动态库的过程中,而且没有动态库的源代码无法调试。不得已我组织RTL编写人员于3月7日和8日进行了两天的封闭式自查。通过自查发现了大大小小20多个错误,使运行whetdstone的联调取得突破性的进展。后来我们又进行了两次封闭自查,只发现一、二处小错误。
第三个阶段为调整和优化阶段,这个阶段是龙芯2号逻辑设计的关键阶段。与联调阶段相 比,优化阶段发现的bug较少,但根据对RTL进行综合以及用C模拟器进行性能分析的结果对整个设计的延迟、面积、性能进行了持续的优化。通过初步的优化,龙芯2号的延迟降低了一倍多,面积降低了30%以上,相同频率的性能提高了30%以上。在这个阶段的每一周都充满了激动人心的改进,深刻体会到精益求精的道理。孔子说“食不厌精”,处理器设计更是如此。用1%的工夫可以完成一个正确的设计,但需要用99%的工夫来优化它。
在龙芯2的RTL优化过程中,我们总结了三条经验。第一条是精益求精的经验。做一个正确的设计和做一个精品的设计是有很大区别的。为了做到精益求精,思想上要永不满足,执着改进。碰到复杂的问题,不能满足于用复杂的方法来解决,要努力把问题简单化再用简单的方法来解决。第二条经验是在执着于细节的理解和把握的同时退后一步进行的全局的观察和思考是十分必要的。在龙芯2号的优化中有很多都是在项目的推进过程中退后一步进行文档整理、看文章、或封闭自查时得到的启示。对设计的微观了解和宏观把握是不可偏废的。如果对设计的细节不做一定的了解,则在整理文档或看文章过程都比较虚,不会有灵感出现;反之,如果过于执着于细节,则可能只见树木,不见森林,忽略了一些大的改进。第三条经验是以事实为依据的经验。对设计进行持续的性能分析、物理综合、以及仿真验证为龙芯2号的改进和改正提供了大量了事实依据。在根据事实进行设计和改进时,一定要在大量的事实和数据的基础上(小量的、不具有代表性的不行)对事实进行深入的分析,弄清楚隐藏在这些事实后面的、本质的东西,这样做的设计和改进才是最优的。
与RTL设计和验证同时进行的是FPGA验证环境的建设。在这个方面我犯了个错误。由于觉得有了龙芯1号的FPGA验证的经验,龙芯2号的FPGA验证应该没有问题,因此只让范宝峡一个人负责FPGA验证工作。没想到由于龙芯2号的规模较大,设计也更加复杂,导致FPGA验证困难重重。主要困难是由于在一片FPGA中放不下,需要多片FPGA,而且多片FPGA之间互连信号太多需要在每片FPGA接口处进行倍频传输。此外由多发射引起的多端口寄存器堆也难以在FPGA中实现。到4月下旬我才意识到FPGA验证方面投入的力量很不够并加强了这方面的力量。直到6月下旬龙芯2号的第一个芯片tapeout之前的半个月,才完成FPGA验证工作并通过FPGA验证及时地发现了设计中的一个错误。
在进行处理器结构和逻辑设计的过程中,其它方面的工作也在同时展开,包括王剑和郑保建带领的龙芯1号系统的继续开发以及龙芯2号软件环境的开发,郑为民带领的龙芯2号主板的开发,许彤、赵继业、钟石强、张珩负责的物理设计和验证方法的总结和研究等等。
就在龙芯2号的RTL设计过程中,SARS在北京肆虐,并给我们极大的考验。那时候所里的政策是所里不统一放假,但各个部门可以根据自己的具体情况放假。我和唐志敏商量后决定我们采取一定的预防措施并适当减轻工作强度。我们要求凡是乘坐公共交通系统上下班的都不来上班,晚上9点前必须下班,每天的中饭和晚饭由室里统一安排在办公室吃。至于外界的来访,所里早就不允许进入北楼了。此外,所里和室里都给我们发放了有关的预防药物,我们自己也买了一些。在这段日子里,虽然我们的进度被迫放慢了一些,但依旧不断地向前推进。我在为全国人民面对灾难时众志成城战胜非典的精神所鼓舞的同时,也为全组在这么困难的情况下坚守岗位所感动。
2003年3月份我们开始部署龙芯2号中用到的一个9个端口的寄存器堆的全定制设计。为了保险,我们部署了两套方案来设计寄存器堆。首选方案是请一个大公司帮我们做这个寄存器堆,同时作为与中科院微电子中心的合作请微电子中心设计同样的寄存器堆作为备选方案。由于首次流片主要是对设计的正确性和结构性能进行验证,因此首次流片除了寄存器堆外还是用ASIC的设计方法,并准备用中科院EDA中心的Synopsys工具进行布局布线以减少购买EDA工具的费用,因此在5月份之前物理设计组的人员也对Synopsys的工具进行了进一步熟悉。2003年5月份开始龙芯2号的物理设计正式展开。从5月初到6月中下旬,我们对使用的方法和流程进行了反复的试验、比较和确定,尤其是关于是否使用层次化设计方法、使用何种Wireload Model、以及Floorplan的方案等进行了反复的试验和尝试,并最后确定方法和流程。到6月底时确定了布局布线的方案并基本完成了布局布线,与流片厂家TSMC联系好准备在7月10日前tapeout。本来一切都在“掌控之中”,但随后发生的两件事情却大大出乎我们的意料。