Verilog综合原理

        逻辑综合是在标准单元库和特定的设计约束的基础上,把设计的高层次描述转换成优化的门级网表的过程。标准单元库可以包含简单的单元,例如与门、或门和或非门等基本逻辑门,或者宏单元,例如加法器、多路选择器和特殊的触发器。标准单元库也就是大家熟知的工艺库。

     逻辑综合工具并不能处理随意编写的Verilog结构描述。通常,任何采用周期到周期的RTLVerilog结构描述都能为逻辑综合工具所接受。如下列出了逻辑综合工具通常所能接受的结构列表。  

        端口  input , inout , output 
 
        参数  parameter 
 
        模块定义 module
  
        信号和变量 wire, reg , tri 允许使用矢量表示
 
        实例的调用(引用) module instance, primitive gate instance

              例如:mymux m1(out,i0,i1,s);

              nand (out, a,b ) ;
 
        函数和任务  function, task 不考虑时序结构
 
        过程 always , if , then, else, case ,casex , casez 不支持initial过程的综合

        过程块 begin, end, named blocks ,disable 命名块的禁止是允许的

        数据流 assign 不考虑延迟信息
 
        循环 for , while , forever    while和forever循环必须包含@(posedge clk)或者@(negedge clk)

    

    要记住,我们提供的是电路的周期到周期的RTL描述。因此,这些语言结构用于逻辑综合工具的方式有一些限制。例如,while和forever循环必须由@(posedge clock)或者@(negedge clock)语句终止循环,以此强制具有周期到周期的行为,避免组合反馈。另一个限制是逻辑综合忽略所有由#<delay>结构指定的时序延迟。因此,综合前后Verilog的仿真结果可能不同。设计者必须尽量减少使用这些有可能导致Verilog的前后仿真结果不一致的描述风格。此外,逻辑综合工具也不支持initial结构的转换。因而设计者必须使用复位机制来取代initial结构,进行电路信号的初始化。

      推荐明确地指定信号和变量宽度。定义未指定宽度的变量可能产生庞大的门级网表,因为综合工具可能根据变量定义生成不必要的逻辑。

       Verilog描述的风格对最终设计有很大的影响。就逻辑综合而言,重要的是考虑实际的硬件实现问题。在不牺牲高抽象层次优势的情况下,RTL描述应该尽可能地接近预期的结构。在设计抽象层次和控制逻辑综合输出结构之间存在一个折衷。在很高的抽象层次进行设计,综合工具会产生不可预料的逻辑结构。在很低的抽象层次(例如,手工调用每个单元)使设计者丧失高层次设计不依赖于工艺的优势。同时,对不同的逻辑综合工具来说,“好”的风格也会有所不同。然而,许多规则对各种逻辑综合工具是一致的。下面列出的是RTL设计中设计者应该考虑的一些设计原则。

      使用有意义的信号和变量名称。信号和变量的命名应该具有意义,以便代码自身具有清晰的注释信息,增强可读性。

      避免混合使用上升沿和下降沿触发的触发器。混合使用上升沿和下降沿触发的触发器可能在时钟树中引入反向器和缓冲器。 一般不希望出现这种情况,因为这将在电路中引入时钟偏斜。

       使用基本构造模块与使用连续赋值语句的对比。RTL描述中使用基本的构造模块和使用连续赋值语句各有优缺点。连续赋值语句是一种非常简洁的表示功能的方式,通常能生成性能很好的随机逻辑电路。然而,最终的逻辑结构并不一定是对称的。调用基本构造模块可以产生对称的设计,并且逻辑综合工具能够更高效地优化小模块。然而,调用构造模块是一种不太简洁的设计描述方式;它制约了针对变化工艺的重定向,并且通常会降低仿真器性能。

       调用多路选择器与使用if-else或者case语句的对比if-else和case语句常常被综合成硬件中的多路选择器。如果需要结构化的实现,最好直接使用多路选择器来实现模块,因为if-else或者case语句可能使综合工具产生不可预期的随机逻辑。调用多路选择器的方式更容易控制,综合速度也更快,但它存在依赖于工艺的不利因素,并且表达多路选择器的代码比较长。另一方面,if-else和case语句可以简洁地表示多路选择器,常用于建立不依赖工艺的RTL描述。

       显式地定义if-else或者case语句。在if-else或者case语句中必须说明各种可能的条件分支。否则可能产生电平敏感的锁存器,而不是多路选择器。

 设计约束指定

         若想得到最理想的设计,设计约束与高效率的HDL描述一样重要。时序、面积、功耗和环境参数,例如输入驱动强度、输出负载、输入到达时间等的精确描述对产生最优的门级网表至关重要。违反正确的约束或者忽略约束都可能导致非最优化的设计。必须小心地指定设计约束

 



目 录 译者序 前言 第1章 概论 1 1.1 为什么要用编译器 2 1.2 与编译器相关的程序 3 1.3 翻译步骤 5 1.4 编译器中的主要数据结构 8 1.5 编译器结构中的其他问题 10 1.6 自举与移植 12 1.7 TINY样本语言与编译器 14 1.7.1 TINY语言 15 1.7.2 TINY编译器 15 1.7.3 TM机 17 1.8 C-Minus:编译器项目的一种语言 18 练习 19 注意与参考 20 第2章 词法分析 21 2.1 扫描处理 21 2.2 正则表达式 23 2.2.1 正则表达式的定义 23 2.2.2 正则表达式的扩展 27 2.2.3 程序设计语言记号的正则表达式 29 2.3 有穷自动机 32 2.3.1 确定性有穷自动机的定义 32 2.3.2 先行、回溯和非确定性自动机 36 2.3.3 用代码实现有穷自动机 41 2.4 从正则表达式到DFA 45 2.4.1 从正则表达式到NFA 45 2.4.2 从NFA到DFA 48 2.4.3 利用子集构造模拟NFA 50 2.4.4 将DFA中的状态数最小化 51 2.5 TINY扫描程序的实现 52 2.5.1 为样本语言TINY实现一个扫描 程序 53 2.5.2 保留字与标识符 56 2.5.3 为标识符分配空间 57 2.6 利用Lex 自动生成扫描程序 57 2.6.1 正则表达式的Lex 约定 58 2.6.2 Lex输入文件的格式 59 2.6.3 使用Lex的TINY扫描程序 64 练习 65 编程练习 67 注意与参考 67 第3章 上下文无关文法及分析 69 3.1 分析过程 69 3.2 上下文无关文法 70 3.2.1 与正则表达式比较 70 3.2.2 上下文无关文法规则的说明 71 3.2.3 推导及由文法定义的语言 72 3.3 分析树与抽象语法树 77 3.3.1 分析树 77 3.3.2 抽象语法树 79 3.4 二义性 83 3.4.1 二义性文法 83 3.4.2 优先权和结合性 85 3.4.3 悬挂else问题 87 3.4.4 无关紧要的二义性 89 3.5 扩展的表示法:EBNF和语法图 89 3.5.1 EBNF表示法 89 3.5.2 语法图 91 3.6 上下文无关语言的形式特性 93 3.6.1 上下文无关语言的形式定义 93 3.6.2 文法规则和等式 94 3.6.3 乔姆斯基层次和作为上下文无关 规则的语法局限 95 3.7 TINY语言的语法 97 3.7.1 TINY的上下文无关文法 97 3.7.2 TINY编译器的语法树结构 98 练习 101 注意与参考 104 第4章 自顶向下的分析 105 4.1 使用递归下降分析算法进行自顶向下 的分析 105 4.1.1 递归下降分析的基本方法 105 4.1.2 重复和选择:使用EBNF 107 4.1.3 其他决定问题 112 4.2 LL(1)分析 113 4.2.1 LL(1)分析的基本方法 113 4.2.2 LL(1)分析与算法 114 4.2.3 消除左递归和提取左因子 117 4.2.4 在LL(1)分析中构造语法树 124 4.3 First集合和Follow集合 125 4.3.1 First 集合 125 4.3.2 Follow 集合 130 4.3.3 构造LL(1)分析表 134 4.3.4 再向前:LL(k)分析程序 135 4.4 TINY语言的递归下降分析程序 136 4.5 自顶向下分析程序中的错误校正 137 4.5.1 在递归下降分析程序中的错误 校正 138 4.5.2 在LL(1)分析程序中的错误校正 140 4.5.3 在TINY分析程序中的错误校正 141 练习 143 编程练习 146 注意与参考 148 第5章 自底向上的分析 150 5.1 自底向上分析概览 151 5.2 LR(0)项的有穷自动机与LR(0)分析 153 5.2.1 LR(0)项 153 5.2.2 项目的有穷自动机 154 5.2.3 LR(0)分析算法 157 5.3 SLR(1)分析 160 5.3.1 SLR(1)分析算法 160 5.3.2 用于分析冲突的消除二义性 规则 163 5.3.3 SLR(1)分析能力的局限性 164 5.3.4 SLR(k)文法 165 5.4 一般的LR(1)和LALR(1)分析 166 5.4.1 LR(1)项的有穷自动机 166 5.4.2 LR(1)分析算法 169 5.4.3 LALR(1)分析 171 5.5 Yacc:一个LALR(1)分析程序的 生成器 173 5.5.1 Yacc基础 173 5.5.2 Yacc选项 176 5.5.3 分析冲突与消除二义性的规则 180 5.5.4 描述Yacc分析程序的执行 183 5.5.5 Yacc中的任意值类型 184 5.5.6 Yacc中嵌入的动作 185 5.6 使用Yacc生成TINY分析程序 186 5.7 自底向上分析程序中的错误校正 188 5.7.1 自底向上分析中的错误检测 188 5.7.2 应急方式错误校正 188 5.7.3 Yacc中的错误校正 189 5.7.4 TINY中的错误校正 192 练习 192 编程练习 195 注意与参考 197 第6章 语义分析 198 6.1 属性和属性文法 199 6.1.1 属性文法 200 6.1.2 属性文法的简化和扩充 206 6.2 属性计算算法 207 6.2.1 相关图和赋值顺序 208 6.2.2 合成和继承属性 212 6.2.3 作为参数和返回值的属性 219 6.2.4 使用扩展数据结构存储属性值 221 6.2.5 语法分析时属性的计算 223 6.2.6 语法中属性计算的相关性 226 6.3 符号表 227 6.3.1 符号表的结构 228 6.3.2 说明 230 6.3.3 作用域规则和块结构 232 6.3.4 同层说明的相互作用 236 6.3.5 使用符号表的属性文法的一个 扩充例子 237 6.4 数据类型和类型检查 241 6.4.1 类型表达式和类型构造器 242 6.4.2 类型名、类型说明和递归类型 246 6.4.3 类型等价 248 6.4.4 类型推论和类型检查 253 6.4.5 类型检查的其他主题 255 6.5 TINY语言的语义分析 257 6.5.1 TINY的符号表 258 6.5.2 TINY语义分析程序 259 练习 260 编程练习 264 注意与参考 264 第7章 运行时环境 266 7.1 程序执行时的存储器组织 266 7.2 完全静态运行时环境 269 7.3 基于栈的运行时环境 271 7.3.1 没有局部过程的基于栈的环境 271 7.3.2 带有局部过程的基于栈的环境 281 7.3.3 带有过程参数的基于栈的环境 284 7.4 动态存储器 286 7.4.1 完全动态运行时环境 286 7.4.2 面向对象的语言中的动态存储器 287 7.4.3 堆管理 289 7.4.4 堆的自动管理 292 7.5 参数传递机制 292 7.5.1 值传递 293 7.5.2 引用传递 294 7.5.3 值结果传递 295 7.5.4 名字传递 295 7.6 TINY语言的运行时环境 296 练习 297 编程练习 303 注意与参考 304 第8章 代码生成 305 8.1 中间代码和用于代码生成的数据 结构 305 8.1.1 三地址码 306 8.1.2 用于实现三地址码的数据结构 308 8.1.3 P-代码 310 8.2 基本的代码生成技术 312 8.2.1 作为合成属性的中间代码或目标 代码 312 8.2.2 实际的代码生成 314 8.2.3 从中间代码生成目标代码 317 8.3 数据结构引用的代码生成 319 8.3.1 地址计算 319 8.3.2 数组引用 320 8.3.3 栈记录结构和指针引用 325 8.4 控制语句和逻辑表达式的代码生成 328 8.4.1 if 和while 语句的代码生成 328 8.4.2 标号的生成和回填 330 8.4.3 逻辑表达式的代码生成 330 8.4.4 if 和while 语句的代码生成过程 样例 331 8.5 过程和函数调用的代码生成 334 8.5.1 过程和函数的中间代码 334 8.5.2 函数定义和调用的代码生成过程 336 8.6 商用编译器中的代码生成:两个案 例研究 339 8.6.1 对于80×86的Borland 3.0版C编 译器 339 8.6.2 Sun SparcStation的Sun 2.0 C编 译器 343 8.7 TM:简单的目标机器 346 8.7.1 Tiny Machine的基本结构 347 8.7.2 TM模拟器 349 8.8 TINY语言的代码生成器 351 8.8.1 TINY代码生成器的TM接口 351 8.8.2 TINY代码生成器 352 8.8.3 用TINY编译器产生和使用TM 代码文件 354 8.8.4 TINY编译器生成的TM代码文 件示例 355 8.9 代码优化技术考察 357 8.9.1 代码优化的主要来源 358 8.9.2 优化分类 360 8.9.3 优化的数据结构和实现技术 362 8.10 TINY代码生成器的简单优化 366 8.10.1 将临时变量放入寄存器 366 8.10.2 在寄存器中保存变量 367 8.10.3 优化测试表达式 367 练习 368 编程练习 371 注意与参考 372 附录A 编译器设计方案 373 附录B 小型编译器列表 381 附录C Tiny Machine模拟器列表 417
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值