热度 13
2015-3-9 16:35
1655 次阅读|
1 个评论
首先,自己并不是从技术领域去探讨FPGA和Verilog HDL语言,自己接触这方面知识时间较短,也没有丰富的经验,而网络上关于这方面的学习资源还是比较丰富的,自己也受益匪浅。这篇文章只是想对自己过去的一段工作经历做下总结,和对之后的发展方向做下思考。 去年在一个项目中,被安排做FPGA的逻辑代码开发,由于以前从未接触过Verilog HDL语言,心里还是比较心虚的。但考虑到三方面因素,还是承担了下来: 1、从原理图修改、审核PCB开始,可以抽空学习Verilog HDL语法,这大概有两周时间。之后还会有20天时间可以全部用于代码编写上,时间看来还是充裕的; 2、FPGA要实现功能并不复杂,只是一些简单的控制逻辑和通信接口; 3、自己并不是凭空撰写,而是有之前产品代码做修改参考。 后来在实际的项目开发中,原理图的审核修改、投板流程需要的众多输出准备、和软件讨论接口方案及前期调试资源准备,这些事情所耗费的时间大大超出了预期,迫于项目进度的压力,自己主动承担了一些之前计划外的事情。尤其在原理图审核修改方面,出于高速信号性能的考虑,基本成为了PCB主导,遇到走线不顺时,原理图调换线序成为了首选方案,尤其FPGA管脚分配,基本全部做了更改,引入了大量不受控的工时耗费。等到完成了这些工作后,项目进度已有延迟,但项目层面通过与PCB供应商及和产线的沟通,加急优先安排生产,回板时间却未发生改变。于是才发现可用于编写代码的时间仅有一周。 刚开始看以前的代码时,由于项目压力导致的焦虑情绪,使得犹如阅读天书一般,半天下来反而昏昏欲睡,更是无从下手修改。中午就想反馈这种风险,但获悉只需要先把一些时钟、复位、GPIO等基本功能做好即可,后续调试过程中,再一步步加入其它功能。于是心情缓解了很多,也静下心来阅读代码,于是在下午,配合在百度上查询一些语法用法,也去宏观思考其实一个模块就是定义了诸多输入、输出接口用于与其它模块互连,模块内部是对功能的描述,有组合逻辑电路和时序逻辑电路之分,这样下来,竟然顺利地看懂了一个模块,然后又意识到always过程块、assign语句实际上代表的是并行执行的电路;通过模块实例化,一个模块又可以由若干个子模块构成,这样对整个项目的架构也明晰了。而且在阅读过程中,也明白了以前觉得很神秘的FPGA为软件提供的寄存器是如何实现的,这些在当时极大地提升了自己的信心。于是在第二天自己便开始修改代码。回板前便将基本功能实现了。 回板后,硬件电源、时钟及复位调试完成后,便分别开始软件调试和逻辑调试,但一开始便遇到了问题,逻辑代码烧入后,功能无法正常运行,很快便遇到了软件方向的投诉,说影响了进度。于是在大家的共同帮助下,查出了问题所在。之后牵涉的其它方向人员更多了,需要用到的新功能需求接踵而至,而一些小问题也需要处理,投诉也犹如雪片般纷沓而至,部门考虑到自己的困难,协调了另一个同事来处理一些急需解决的问题,而自己则全力以赴先把所有功能加入,这样持续了近四天,总算是完成了大部分的功能,加上这段时间来自家庭的因素,已是心力交瘁。接下来为了保障项目进度和质量,部门将最后一个通信模块的代码编写任务交给了另外一个同事,并对代码进行检查整改。自己则开始进行硬件信号完整性测试,从而结束了这次短暂的FPGA逻辑开发工作。 最近抽空认真学习了一遍Verilog HDL语言,再回想之前的那些问题,才发现其实很多都是对语法应用理解不深入所造成的。主要遇到的问题有以下三个: 1、逻辑烧入后,功能无法正常运行。测试一些GPIO的输出,初始化应该输出高电平的,却是低电平等。 首先怀疑是电源、时钟和复位的问题。 测试电源,电压正常; 时钟是利用外部晶振输入,内部PLL倍频得到,PLL的配置包括了时钟输入clk_in、时钟输出clk_out和指示时钟是否稳定的pll_lock信号构成;pll_lock信号引至复位系统中,用作复位信号产生的一部分; 复位信号是由外部复位信号、FPGA上电后内部自己产生的复位信号和pll_lock信号相与实现的。 由于时钟是通过配置PLL得到的,因此怀疑是复位信号的问题。将复位信号组成部分中的外部复位信号和pll_lock信号去掉,仅保留了内部复位信号进行调试,发现FPGA初始化后输出正确。 现在想想,这应该是外部复位信号所导致的,因为在逻辑中大量使用了异步复位触发器,即 “always @ (posedge clk or negedge rst) if(rst == 1'b0) 初始化操作 else 其它时序操作 ” 之前的复位由外部复位信号、内部复位信号和pll_lock信号相与组成,而外部复位信号由带POR功能的电源监控芯片提供,因此在上电过程中,其一直处于低电平复位状态,那么逻辑也就不会检测到下降沿并进行初始化操作。 之后软件调试中又投诉一些寄存器值进行配置后,相应的功能无法生效。自己也做了下调试,对一个按键进行检测,并通过检测结果对一个LED灯进行亮灭控制,发现LED的亮灭只和初始化设置有关,而和按键的动作无关,于是问题应当是整个逻辑只执行了初始化过程,便不再运行。 由于初始化过程正确,因此怀疑是时钟问题,将PLL倍频后的时钟分配到某个GPIO输出,利用示波器进行测试,发现有时钟波形输出。在同事建议下,对涉及初始化的语句进行一条一条屏蔽,当将复位信号产生的语句屏蔽掉后,检测按键并控制LED灯亮灭的功能正常,因此问题还是出在复位电路上了。通过共同分析,加入pll_lock信号与内部复位信号相与构成逻辑的复位信号,时序逻辑功能正常。 现在想想,应该是去掉pll_lock后,当内部复位结束后,而时钟还未产生,但异步复位触发器需要在复位结束时,时钟信号和复位释放信号满足一定时序关系,否则就会进入亚稳态。引入pll_lock信号后,在时钟稳定产生后,复位才会被释放,满足了时序关系,电路功能正常。 2、诸多Verilog HDL语法理解模糊。比如:自己虽然意识到always过程块、assign语句等是并行执行的,但是对于阻塞和非阻塞赋值还是毫无概念,尤其是“=”和“=”两种赋值方式,肤浅的认为前者用于组合逻辑赋值,后者用于时序逻辑赋值。这种概念上的模糊导致了一些小问题的出现,例如赋值不生效等。 又比如自己按照以前C语言编程思想,将一个变量在不同的always块中去赋值,结果综合时便报错,不允许将一个变量在always块中赋值。这样的写法也导致了很多的修改返工。其实现在想想,既然always过程块是并行运行的,一个变量在不同always过程块中去赋值,是会引发竞争冒险的。当时应该是受了C语言语句顺序执行的惯性思维影响了。 还有always块中被赋值的变量是reg型,这是Verilog HDL语言所规定的,但这应该只是Verilog HDL语言早期用于时序逻辑电路时的规定,现在也可用于组合逻辑电路,所以这些变量虽然被定义为reg类型,但并非代表寄存器。 3、由于对基本语法都还未理解掌握,所以一些编程思想、经验等更是欠缺。比如外部输入信号滤波等,这些在绘制原理图时都会考虑的因素,在编写逻辑时就忽视了。可以说自己只是急于将逻辑功能调通,而逻辑的质量则丝毫没有顾及。 以上便是第一次接触FPGA逻辑开发的经历,虽然短暂,但记忆深刻。痛定思痛,自己得到以下几点感悟: 1、以前自己不太明白一个好的团队在于人岗匹配,合适的人做合适的事。这次经历让自己意识到这一点,人岗匹配可以最大程度发挥团队中每个成员的优势,保证整件事情的顺利开展和高质量完成。有时即使出于培养个人能力出发,也应该对预交付事情的难度、进度等进行风险评估,循序渐进、由浅及深地去培养。而对于个人,则应该调整好心态,不要总觉得别人做的事情是很有技术含量的,而自己不过是从事的琐事杂事,其实每一件安排给自己的事情都是团队认真思考后,最适合自己、最能发挥自己优势的事情,作为一个职业人,应当在自己的本职工作上追求完美,这才是对自己和对公司负责任的态度。 2、个人还是应该有个知识体系,要有所聚焦,不能蜻蜓点水般去学习。其实,知识体系这个概念是四年前自己的经理告诉我的,但当时自己完全不知道这是个什么概念。人的精力是有限的,而知识的领域尤其是硬件知识的领域是非常宽泛的,面面俱到的后果就是零星杂散,无一样精通。自己以前的想法就是这样,梦想着既能够绘制原理图,又能画PCB,还能编代码,数电、模电、电机、射频、EMIEMC等领域无不涉足,当然有时这也与自己的经历有关,但几年下来,几乎一无所成,所有的知识点都是杂乱无章的。这实际上是一种急功近利的浮躁心态,其实任何一个领域要想精通都是需要时间的积累,而想跨领域融会贯通,更是时间、知识、经验的综合积累,除非是天才,否则不可能有所速成。承认了这点,自己才可以真正平静下来,不被纷乱的信息所干扰。具体到目前,我觉得自己更好的做法应当是形成自己的知识体系,即自己的优势所在,在这个基础上去发散学习。在知识体系没有完固的情况下,要学会舍弃,将精力聚焦,先深后宽。自己经过这段时间的反思,觉得自己应当首先聚焦于从事时间较多的数字电路领域,将数字电路、信号完整性、EMIEMC作为自己的理论基础,原理图绘制、PCB绘制和Verilog HDL语言作为自己的技能发展方向,而其它之前涉及的模电、电机、射频、驱动编写等就不再作为关注重点,以后根据具体发展再慢慢拓展。 3、在聚焦了精力后,自己要比以前更加勤奋。以往由于精力分散,在地铁上多是抱着手机不做思考地浏览一些新闻,并认为这是在充实自己。而现在这些碎片时间,自己则用于阅读一些和自己知识体系相关的内容,现在我觉得时间一方面是通过克制自己的懒惰获得的,一方面也是收缩自己精力获得的。另外,公司毕竟是以产品以盈利为目标,自己更多的是保证按时按质地完成任务,所以经验总结、知识学习更多的应该利用业余时间来完成,以不断提高自己的能力。自己以前浪费了太多的时间,之后不能再这样了。 4、学会更好的沟通。自己在这次任务中,其实在意识到风险后,就应该及时提出,沟通清楚后续的任务、时间节点等,并协调资源帮助自己。寻求帮助不可耻,事情做不完做不好才是可耻的。而不是想当然的自己认为后续该如何安排。充分地去沟通,是这次留给我的一个教训。 5、不得不承认,自己的心态还是有一定问题,不能完全放开,似乎总要彰显出自己的能力,害怕自己的专业被质疑。这样在做事时,无疑是自己给自己带了一副枷锁,其实有时放开自己,一直抱着谦虚谨慎的学习态度,不懂即坦荡承认,虚心请教,虚心接受别人的意见,多分享多沟通多交流,才是一种健康的成长方式。 以上便是这次短暂的逻辑开发经历给我的反思,限于经历,应当有很多局限的地方,但认识是逐步去深入提高的,在努力的方向上多思考多总结,这才是自己该做的。