这本书可以帮助工程师写出更好的Verilog/SystemVerilog的设计和验证代码,书中阐述了使用Verilog和
SystemVerilog语言时超过100个常见的编码错误;每一个例子都详细说明了错误的症状、错误的语言规则以及正确的编码方式。这本书能帮助数字
设计工程师和验证工程师有效地识别与避免这些常见的编码错误。书中列举的这些错误许多是非常微妙的,有可能需要花费几个小时或几天的时间才能发现或调试。
编辑推荐
《Verilog与SystemVerilog编程陷阱:如何避免101个常犯的编码错误》由机械工业出版社出版。
名人推荐
“我中意的陷阱是‘陷阱65:死循环’。为什么呢?我为了调试这个程序缺陷付出了一个芯片的代价。相信我,当一个模型错误毁掉你的芯片时,你绝对不会忘记
它是怎么发生的。可是那时我没有这本书来帮助我避免这个错误,而你有!把这本书放在你的手边,经常翻阅它,祝你的模型编译顺利,不陷入死循环。”
——SleVe Golson,Verilog设计咨询专家,Tdlobyte Systems公司
“每
周我都会收到因为客户遭遇SystemVerilog陷阱而申请技术支持的请求,甚至经验丰富的Verilog用户在他们的代码由于棘手的端口方向问题
(陷阱69)而不能编译时也会给我发电子邮件。而掌握面向对象程序设计的验证工程师由于他们的信箱充斥着错误数值(陷阱73)也会向我求助,他们可能会忘
记静态代码(陷阱7、陷阱76和陷阱77),或者混淆对象和句柄(陷阱74)。为了节省你调试的时间成本,请首先参考这本书以避免这些陷阱吧。”
——Chris Spear,验证专家,Synopsys公司
作者简介
关 于 作 者Stuart Sutherland是IEEE
1800工作组的成员,该工作组负责起草Verilog和SystemVerilog标准。早在1993年也就是Verilog标准的诞生之际,他就已经
涉足其标准的定义。同时他参与SystemVerilog标准也可追溯到2001年。此外,Stuart是IEEE官方Verilog和
SystemVerilog语言参考手册的技术编辑。Stuart先生作为独立Verilog顾问,专注提供针对Verilog
HDL、SystemVerilog 和PLI的综合性专家训练。Stuart是《SystemVerilog for
Design》《Verilog-2001:A Guide to the New Features in the Verilog Hardware
Description Language》的合著者,也是《The Verilog PLI Handbook》和颇受推崇的《Verilog
HDL Quick Reference Guide》及《Verilog PLI Quick Reference
Guide》的作者。Stuart同时发表了诸多涉及Verilog和SystemVerilog的技术文章。
Don
Mills从1986年开始涉足ASIC的设计。在此期间,他参与了超过30个ASIC项目。Don从1991开始使用自顶向下的设计方法(综合设计编译
器1.2)。Don在几个公司开发并实施了自顶向下的ASIC设计流程。他精通工具整合和流程自动化。Don作为SystemVerilog和
Verilog内部咨询师服务于美国微芯技术公司。Don是IEEE
Verilog和SystemVerilog委员会的成员,该委员会致力于Verilog和SystemVerilog语言的发布和完善。Don是多篇文
章的作者或合著者,例如《SystemVerilog Assertions are for Design Engineers
Too!》及《RTLCoding Styles that Yield Simulation and Synthesis Mismatches》。
目录
译者序
序
关于作者
第1章什么是“编程陷阱”
什么是Verilog和SystemVerilog
什么是陷阱
Verilog和SystemVerilog标准
第2章声明以及字符表述类陷阱
陷阱1:字母大小写的敏感性
陷阱2:网表的隐式声明
陷阱3:默认的1bit内部网
陷阱4:单文件和多文件编译的$unit声明
陷阱5:局部变量的声明
陷阱6:分层路径的转义名称
陷阱7:自动变量的分层引用
陷阱8:未命名模块中的变量分层引用
陷阱9:分层引用一个导入的包项目
陷阱10:从程序包中导入枚举类型
陷阱11:导入多个程序包
陷阱12:默认的整数进制
陷阱13:有符号整数
陷阱14:有符号数的位宽扩展
陷阱15:变量位宽与赋值位宽的不一致
陷阱16:将矢量全置为1
陷阱17:合并数组和并置
陷阱18:端口连接的几点规则
陷阱19:后驱动端口
陷阱20:实型(浮点型)数字的端口间传送
第3章RTL建模中的陷阱
陷阱21:包含函数调用的组合逻辑灵敏度列表
陷阱22:灵敏度列表中的数组
陷阱23:时序逻辑灵敏度列表中的向量
陷阱24:灵敏度列表中的操作
陷阱25:使用begin...end的时序逻辑块
陷阱26:带复位的顺序逻辑块
陷阱27:异步设置
陷阱28:顺序程序块中的阻塞赋值
陷阱29:要求阻塞赋值的顺序逻辑
陷阱30:组合逻辑中的非阻塞赋值
陷阱31:错误顺序的组合逻辑赋值语句
陷阱32:case表达式中casez
陷阱33:不完备的判决语句
陷阱34:重叠判决语句
陷阱35:不恰当使用unique条件语句
陷阱36:2—状态模型的复位
陷阱37:枚举类型锁定状态机的建模
陷阱38:4—状态逻辑中隐藏的设计问题
陷阱39:2—状态类型中隐藏的设计问题
陷阱40:越界数组访问中的隐藏问题
陷阱41:枚举类型的越界赋值
陷阱42:模块中未检测到共享变量
陷阱43:在接口和程序包中未见共享变量
第4章运算符陷阱
陷阱44:表达式的赋值
陷阱45:操作符的自定义和上下文定义
陷阱46:赋值语句中的运算位宽和符号扩展
陷阱47:有符号数的算数运算规则
陷阱48:基于位选择的操作
陷阱49:递增、递减和赋值运算符
陷阱50:前加与后加运算
陷阱51:一条语句中变量的多次改变
陷阱52:运算求值短路
陷阱53:逻辑非(!)与按位求反符(~)
陷阱54:数组的运算
陷阱55:针对数组子集的运算
第5章常见的编程陷阱
陷阱56:验证零时刻的异步和同步复位
陷阱57:if...else嵌套语块
陷阱58:4—状态值下等号求值
陷阱59:事件触发竞争条件
陷阱60:使用信号量的同步
陷阱61:使用邮箱的同步
陷阱62:时钟块的触发
陷阱63:判断语句后错误使用分号
陷阱64:for循环语句中分号的错误使用
陷阱65:死循环
陷阱66:由于并发for循环引起的死锁
陷阱67:循环控制变量的引用
陷阱68:函数返回默认的位宽
陷阱69:任务
陷阱70:为避免毛刺而采用延迟的连续赋值
第6章面向对象和多线程编程中的陷阱
陷阱71:类定义的编程语句
陷阱72:基于面向对象接口的测试平台
陷阱73:邮箱中的所有对象具有相同的值
陷阱74:使用input或ref参数的句柄传递
陷阱75:构建一个基于对象的数组
陷阱76:静态任务和功能的非可重入性
陷阱77:静态变量与自动变量的初始化
陷阱78:叉型编程线程需要自动变量
陷阱79:禁用fork将终止多个线程
陷阱80:禁用一个语句块却未如所愿
陷阱81:仿真在测试完毕前过早退出
第7章随机化、覆盖率和断言类陷阱
陷阱82:随机化声明的变量并未随机化
陷阱83:未被检测的随机化失败
陷阱84:$assertoff可以禁止随机化
陷阱85:两个以上随机变量的布尔约束条件
陷阱86:不必要的负随机值
陷阱87:覆盖报告默认基于组而非箱
陷阱88:覆盖率始终报告0%
陷阱89:覆盖报告将所有实例混在一起
陷阱90:覆盖组的参数方向具有粘黏性
陷阱91:断言传递语句与空成功一同执行
陷阱92:程序块中的并发断言
陷阱93:assert...else语句中的不匹配
陷阱94:不能失败的断言
第8章工具兼容性陷阱
陷阱95:默认的仿真时间单位和精度
陷阱96:程序包链接
陷阱97:不同工具的随机数生成不一致
陷阱98:使用always_latch
陷阱99:非标准语言扩展
陷阱100:数组常量的级联
陷阱101:传输浮点数值(实数类型)的模块端口
文摘
上
例中,第一个陷阱是枚举变量State的声明使用了字母大小写混合,而在代码的后半部分,也许是在声明的上百行代码后引用了一个名为state的信号。在
英语中这些标识符读起来是一样的,但是在Verilog或SystemVerilog工具中,它们是不同的名字,这是陷阱!
第二个陷阱是枚举标
签LOAD的所有字母均为大写。而在后面的代码部分却引用了一个叫LOAD的标识符。猛一看,这些标识符好像一样,但是对于
Verilog/SystemVerilog工具而言,它们大相径庭。二者的差异是该枚举标签的名字包含了大写字母“O”(发音同“oh”),而代码中所
引用的名字包含了数字“O”(即零)。又掉入陷阱了!
在上述例子中第三个陷阱涉及枚举标签WAIT。尽管语法正确,但对一个标识符来说这并非一
个好的选择,因为Verilog/SystemVerilog的关键词中有wait。而在该模块的后部分,变量nState由wait赋值。这
样,Verilog/SystemVerilog工具针对这个并未声明的标识符便不会报错。它将会产生在预期表达式处导致一个关于程序wait语句的错
误。如果使用大写字母标识符的名字和使用全小写字母关键词的名字相同,将会降低代码可读性,并导致很难发现的代码错误,同时会引起原因不明的语法错误信
息。第三次进入陷阱!
在上述例子中,名字的拼写错误会导致编译错误,这或许令人沮丧,但至少不会导致没有错误提示但产生非预期行为的陷阱。大小写敏感错误也会导致通过编译且没有任何错误提示的陷阱,从而带来设计上的功能性问题。陷阱2会给出一个这样的例子。
如何避免此类陷阱
一种避免这种字母大小写敏感性陷阱的途径就是在公司内部采用良好的命名规定,并在之后严格执行这些规定。本书中使用的命名规定是:
口变量和网表的命名用小写字母。
用户自定义类型命名以t结束。
枚举变量命名以e结束。
低态有效信号命名以n结束。