在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
楼主: weijiaming

[原创] 大家好,我是《Verilog编程艺术》的作者,欢迎大家的反馈和提问

[复制链接]
 楼主| 发表于 2014-5-28 19:02:26 | 显示全部楼层
第5章
编码风格
著名的Verilog专家Cliff Cummings说:“我是一个简洁编码的狂热分子。一般来说,代码越短越
好。如果我们能够把一段代码整齐清晰地写在一页纸内,那么就很容易理解这段代码的意图。按照我的
观点,那些额外地要消耗掉一两代码行的begin-end和近来流行的那种//end-always 的标示风格都毫无必
要地增加了混乱,因为你在发现并识别出重要的细节之前,你的眼睛总是要扫描这些无用的代码。我把
这个现象称为Where's Waldo,这个名字来源于同样名字的儿童玩具书(见图5-1)。虽然Waldo穿着鲜
亮的红白条T恤,但是当他处于混乱的环境里,要想发现他就很困难。正如在混乱的环境里难以发现
Waldo一样,当RTL代码格式混乱、注释愚蠢时,那么简单的编码错误都有可能被掩盖掉。”
图5-1 Where’s Waldo(来源于网络)
强调Verilog编码风格,经常是一个不太受欢迎的话题,因为某些人不能接受别人说他的编码风
格不好,不能接受让他采用更好的编码风格,似乎触到了他的痛点和自尊一样。不管如何,强调
Ver ilo g编码风格是非常有必要的。
每个设计人员都喜欢按照自己的习惯去编写代码,与自己风格相近的代码,阅读和理解就容易一
些。相反与自己风格相差较大的代码,阅读和理解起来就困难一些。另外那些编码风格随意的代码,通
常晦涩、凌乱,在工作上既会给开发者本人带来很大的麻烦,也会给合作者和维护者带来很大的麻烦。
编码风格就是要求我们写的代码符合一定的格式,达到信、达、雅的要求。这样在满足功能和
性能目标的前提下,能够规范代码和优化电路,增强代码的整洁度、可读性、可修改性、可维护
性、可重用性、可移植性,这样能够更好地保证逻辑功能正确,更好地阅读理解,更好地交流合
作,更好地仿真验证,更好地整理文档。但是我们不要拘泥于这些要求,只要能达到规范、和谐、
紧凑、整洁、优美的目的,那么就可以灵活地运用。
对于一个开发部门,开发者(设计人员和验证人员)应该共同制定一套得到每个开发者都认同的编
码风格,然后共同遵守,编写出最整洁的代码,从而达到这样的效果,名字定义清晰,书写格式规范,
逻辑组织有序,层次结构清晰。这样的代码用一个字形容,就是“爽”。
32  Verilog编程艺术  ●
5.1  干干净净
如果我们的环境是干干净净的,那么我们的生活会很愉快,同样如果我们的代码是干干净净
的,那么我们的工作也会很愉快。但是为什么有些人会接受脏乱差的环境?为什么有些人会写出乱
七八糟的代码呢?
干干净净的代码就是要求代码整洁,结构合理,层次清晰,注释明了,没有烂代码,没有冗余
代码,合理地建立目录,合理地分配到不同文件中。有些人觉得格式不重要,只要能正确运行就
行,何必在这上面花费时间呢?其实整理格式花费的时间并不多,我们的大部分时间都花在了设计
和调试上。养成习惯之后,注重格式就会自然而然地完成,对自己对别人对项目都有益。
我们要随时删除那些无用的代码,保持设计干干净净,保持逻辑块清晰。我们写的代码不是张旭的
狂草,也不是王羲之的草书,不是写得乱七八糟别人都看不懂,就显得你很高深。
写代码和写文章一样,刚开始可能粗陋无序,结构杂乱,然后就要仔细斟酌推敲,达到你心目
中的样子。不要以为能够运行就足够了,还需要做很多整理。代码的设计不是一开始就是整洁的,
要经过不断地调整结构,才能达到好的结果。
我认识一个大学生,我问他们的宿舍干净不,他说不太干净,我问他是不是有的宿舍很干净,
他说是的,他说要那么干净干啥,反正大家都习惯了,他还说有的宿舍其实更脏。想一想,大学宿
舍其实就那么大的地方,每个同学平时多注意一些,平时稍微清理一下,就会很干净,可是他们却
不做,没有办法呀。其实干干净净的代码和干干净净的宿舍一样,关键在于你自己有没有想保持干
干净净的心,如果没有这个心,那么不管外人如何说,也没有多大的效果。
5.2  代码划分
我们要学会善于分类、归纳和总结,按照高内聚、低耦合的原则,把代码划分为模块、函数和
任务,形成合理的层次结构。
一般来说,我们应该让每一个模块、函数或任务只做一个功能,隐藏内部实现细节,提供一个
干净的接口,这就是高内聚的原则。对于函数和任务来说,很好满足,但是对于模块来说,有时一
个模块就要干很多事。因为如果进一步做模块划分,就会导致出现太多的模块、太多的实例和太多
的连线,这样反倒更容易出错,所以划分模块应该由设计人员灵活掌握,不要拘泥于这种“模块最
好在500行左右”的说法。例如,有时候大的模块几千行,小的模块就只有10来行。低内聚的代码
会造成很严重的后果,一旦对其修改,就会产生涟漪效应,其他相关的代码也要做相应的修改,这
是“牵一发而动全身”。
另一方面,低耦合的原则就是模块之间尽量用少量的连线连接,避免大量的信号线连来连去,
这样也可以减少错误的发生。
模块划分时,要将关键路径逻辑和非关键路径逻辑放在不同模块,这样在综合时就可以对含有
关键路径的模块做速度优化,而对含有非关键路径的模块做面积优化,而如果把它们都放到同一模
块里,就不能对它们使用不同的综合策略。
模块划分时,要将相关的组合逻辑放在同一模块,这样在综合时可以对其进行优化,因为综合
工具通常不越过模块的边界来优化逻辑。
我们要注意提取公共的代码或常用的代码,形成模块、函数和任务,便于项目组内使用和以后
的移植。如果有可能,要将它们参数化、通用化、IP 化,这样就可以很灵活地使用它们。例如,
CRC计算、时钟分频、同步电路、同步FIFO控制、异步FIFO控制和通用GPIO控制等。
●  第5章  编码风格 33
在模块内部,我们也要合理地切分逻辑,让相关的代码紧挨着,组合在一起形成一个个不同的逻辑
块,按照合理的顺序安排这些逻辑块。进一步我们可以用固定长度的横线分割这些逻辑块,并针对每个
逻辑块加注释。这样我们就可以按照每个逻辑块阅读和理解,就能够很好地阅读和理解整个模块。另外
当函数或任务的代码行非常多时,就要考虑把它分解了,把每一块相关的部分用子函数或子任务实现。
模块内不要存在重复的代码,因为重复的代码会造成代码混乱、维护困难和修改遗漏等问题。
当消除重复的代码之后,模块就变得清晰易读,更加有表达力。设计时,可以使用子模块、函数、
任务、循环语句和寄存器组来消除重复的代码。重复的代码总是有相同的共性,如果在代码中多次
使用一个重复的表达式,那么我们就要用一个函数来代替。同样在做行为级的代码设计时,我们可
以把经常使用的一组描述写到一个任务中。另外我们要积极使用for/generate 或实例数组来实现子模
块的多次实例化,这样可以有效地减少代码行数。
代码的结构不是一开始就是合理的,只有经过不断地调整,才能达到好的结果,但是很多人却
存在着“一蹴而就”的想法。
5.3  代码要求
汉语是优美、丰富的语言,具有以下特点。
1.语言方面,音节结构中元音占优势,每个音节都有声调,音节在汉语中占有重要地位,这些
特点使普通话富有抑扬、和谐、悦耳的音乐美。
2.词汇方面,双音节占优势,构词法灵活多样,词汇丰富,能够反映纷繁的社会现象和表达细
腻的思想感情。
3.语法方面,各级语言单位的组合具有一致性,语序和虚词是最重要的两种组合手段,量词丰
富,这些语法特点使现代汉语的表达容易,做到生动丰富、简明准确。
但是汉语也有很多容易造成混淆的地方,例如多音字,稍不小心,就会写出错别字。例如,有
一天我就在电视上看到,把“犯罪分子”写成了“犯罪份子”。
例如,在“看在我的fèn上”和“事情到了这个fèn儿上”这两句话中,到底是用“分”还是
“份”呢?“分”在汉语中有以下意思:“成分”、“本分”和“情分”,所以应当是“看在我的分
上”,当“情分”用。“份”在汉语中有以下意思:“份额”、“一份快餐”、“月份”、“份儿”,“事情到
了这个份儿上”,表示“程度”、“地步”或“境地”。
同样,Ver ilo g作为一种硬件描述语言,它也是优美、丰富而又简洁的语言,只有灵活合理地运
用,才能充分表达你的设计意图,才能设计出强壮、简洁的代码。但是Verilog也有一些容易混淆的
地方,若不注意就会写出错误的语句,例如阻塞赋值和非阻塞赋值,例如敏感列表不全。
................................................................................................
................................................................................................
................................................................................................
................................................................................................
 楼主| 发表于 2014-6-15 08:38:55 | 显示全部楼层
自己顶一下!
发表于 2014-6-15 22:16:26 | 显示全部楼层
这是在做广告吗
 楼主| 发表于 2014-6-16 23:00:23 | 显示全部楼层
是的。
发表于 2014-6-16 23:44:40 | 显示全部楼层
请问 在verilog 中如何处理 real float 类型的数据
 楼主| 发表于 2014-6-17 20:07:24 | 显示全部楼层
使用$realtobits 和 $bitstoreal 函数

1.$realtobits用于让实数能从模块端口传递过去,把实数转成64-bit的pattern。
2.$bitstoreal是$realtobits反向操作,把64-bit的pattern转成实数。pattern应该符合IEEE 754。

例子:
module driver (output [64:1] net_r);
real r;
assign net_r = $realtobits(r);
............
endmodule

module receiver (input [64:1] net_r);
real r;
assign r = $bitstoreal(net_r);
............
endmodule
发表于 2014-6-17 21:12:16 | 显示全部楼层
回复 61# weijiaming


   不知道你对图形化Verilog编写什么意见,但是像状态机,算法状态机,数据通路,其实都可以图形化编程,再自动生成代码。 用HDL Designer来图形化设计状态机,算法状态机,非常方便,而且支持交互仿真,既可以查看波形,又可以对应到状态图中具体的状态。
自动生成的代码 绝对可综合,且很规范。

另外,MATALB推出的HDL Coder基于simulink来设计数据通路,再自动生成代码,虽然用 matlab coder 设计算法状态机不方便,冗余。但是他设计数据通路还是非常快的。

而Mentor Graphics的HDL Designer图形化设计算法状态机,数据通路都是十分方便。
发表于 2014-6-18 15:00:18 | 显示全部楼层
很好,支持一下
发表于 2014-6-18 22:03:23 | 显示全部楼层
支持,顶
 楼主| 发表于 2014-6-19 07:34:29 | 显示全部楼层
回复 67# JoyShockley

我没有用过,但是如果能提高设计的生产力,那么就非常好。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-25 22:53 , Processed in 0.021090 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表