当前位置: 首页 > news >正文

Library Compiler:时序弧建模与约束全解析(一)

相关阅读

Library Compilerhttps://blog.csdn.net/weixin_45791458/category_13154201.html?spm=1001.2014.3001.5482


时序弧主要分为两大类:时序延迟(timing delays),即电路的实际时序行为,以及时序约束(timing constraints),即电路边界处的约束条件。本系列将介绍相关的时序概念,并说明用于设置约束和定义延迟的timing组。

理解时序弧

时序弧(timing arcs)与网表中的互连信息一起,构成了路径分析过程中路径追踪器(path tracer)所遍历的时序路径,这正如静态时序分析:典型与非典型时序路径的约束详解(一)一文所说。每一条时序弧都包含一个起点(startpoint)和一个终点(endpoint)(注意将其与时序路径的起点和终点区分开来),起点可以是输入引脚、输出引脚(似乎不那么常见,见“建模方法的选择”一节)或双向引脚,终点则始终是输出引脚或双向引脚。唯一的例外是约束类时序弧,例如两个输入引脚之间的建立时间(setup)或保持时间(hold)约束。

图1展示了一个与门拥有的两个时序弧,它们都是从输入到输出的延迟类时序弧。

图1 与门的AC和BC时序弧

除此之外,还必须区分组合逻辑类型(combinational timing)和时序逻辑类型(sequential timing)的时序弧,因为两者用途不同,可通过timing组中的timing_type属性进行区分。

Design Compiler使用组合逻辑时序弧信息来计算时序传播过程中的物理延迟,并进行路径追踪,时序分析工具同样依赖这些时序弧来完成电路的时序分析。

Design Compiler使用时序逻辑时序弧信息来确定设计的优化约束(optimization constraint),关于优化约束的更多内容,可以参考下面的博客。

Design Compiler:什么是代价函数(Cost Function)?https://blog.csdn.net/weixin_45791458/article/details/149296216?ops_request_misc=elastic_search_misc&request_id=c62c8dec320922145e6e1d0963128fcc&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~ElasticSearch~search_v2-1-149296216-null-null.nonecase&utm_term=cost&spm=1018.2226.3001.4450

组合逻辑时序弧

组合逻辑时序弧用于描述组合逻辑单元的时序信息。该时序弧附着在一个输出引脚(output pin)上,其相关引脚(related pin)可以是输入引脚,也可以是另一个输出引脚。组合逻辑时序弧的timing_type属性可以是以下类型之一(它们都是延迟类时序弧):

  • combinational
  • combinational_rise
  • combinational_fall
  • three_state_disable
  • three_state_disable_rise
  • three_state_disable_fall
  • three_state_enable
  • three_state_enable_rise
  • three_state_enable_fall

时序逻辑时序弧

时序逻辑时序弧用于描述时序逻辑单元的时序信息。在描述时钟沿与数据输出之间关系时,该时序弧被视为延迟类时序弧。而在描述时钟沿与数据输入之间关系时,该时序弧被视为约束类时序弧。时序逻辑时序弧的timing_type属性可以是以下类型之一:

  • 边沿敏感延迟:rising_edge、falling_edge
  • 异步置位和复位延迟:preset、clear
  • 建立/保持时间约束:setup_rising、setup_falling、hold_rising、hold_falling
  • 非时序建立/保持时间约束:non_seq_setup_rising、non_seq_setup_falling、non_seq_hold_rising、non_seq_hold_falling
  • 恢复/移除时间约束:recovery_rising、recovery_falling、removal_rising、removal_falling
  • 不变化约束:nochange_high_high、nochange_high_low、nochange_low_high、nochange_low_low

关于timing_type属性的更多介绍,可以参考下面的博客。

Library Compiler:时序弧建模与约束全解析(二)https://blog.csdn.net/weixin_45791458/article/details/160691625?spm=1001.2014.3001.5501

建模方法的选择

对于如图2所示的组合逻辑单元,其时序信息可以采用两种方式进行建模,如图3所示。

图2 两个反相器组成的单元

在图3中,模型A定义了两条时序弧:第一条时序弧从输入引脚A开始到输出引脚Y结束;第二条时序弧从输入引脚A开始到输出引脚Z结束。这是最简单的建模方式。

对于该单元的模型B,同样包含两条时序弧,但相比模型A更加精确:第一条时序弧从输入引脚A开始到输出引脚Y结束(与模型A相同);第二条时序弧则不同,它从输出引脚Y开始到输出引脚Z结束,该时序弧用于建模输出引脚Y端负载对输出引脚Z延迟的影响。

图3 两种建模方法对比

模型B展示的输出引脚到输出引脚的时序弧既可以用于组合逻辑单元,也可以用于时序逻辑单元。

定义timing组

timing组包含下游工具在建模时序弧和进行路径追踪时所需的信息。它用于定义单元内部的时序弧,以及时钟信号与数据信号之间的关系。timing组可以描述以下内容:

  • 输入引脚和输出引脚之间的时序关系
  • 两个输出引脚之间的时序关系
  • 通过非组合逻辑单元的时序弧
  • 触发器或锁存器输入端的建立时间和保持时间约束(输入引脚到输入引脚)
  • (可选)时序弧的名称

timing组一般定义在pin组(也可以是bundle组)中,其语法如下所示:

library (lib_name) { cell (cell_name) { pin (pin_name) { timing () { ... timing description ... } } } }

timing组应定义在时序弧终点所在的pin组中,如“理解时序弧”一节中图示的输出引脚C。需要注意的是,虽然Library Compiler允许在两个引脚之间定义多条时序弧,但其他工具在解析同一对引脚上的多条时序弧时,可能会存在兼容性问题。

使用timing组对时序弧命名

在timing组中,可以为不同的时序弧指定名称。在最简单的情况下,一条时序弧存在于一个已定义的引脚和一个通过related_pin属性指定的相关引脚之间。

然而,在实际建模中,可能会存在多条时序弧,其形式多种多样。下面列出了六种可能的多重时序弧情况,后续章节将进一步说明如何配置这些情况:

  • 单个相关引脚与已定义的bundle组中的多个成员引脚之间
  • 多个相关引脚与已定义的bundle组中的多个成员引脚之间
  • 单个相关引脚与已定义的bus组中的多个比特之间
  • 多个相关引脚与已定义的bus组中的多个比特之间
  • 已定义的bus组中的多个比特与相关bus引脚(具有指定宽度)之间
  • 内部引脚与终点bus组中的所有比特之间
单个引脚与单个相关引脚之间的时序弧

对于单个引脚与单个相关引脚之间的时序弧,可以在timing组中通过指定名称来标识,如下例所示:

cell (my_inverter) { ... pin (A) { direction : input; capacitance : 1; } pin (B) { direction : output; function : "A'"; timing (A_B) { related_pin : "A"; ... } /* end timing() */ } /* end pin B */ } /* end cell */

该时序弧的定义如下表所示:

起点终点名称
ABA_B
单个引脚与多个相关引脚之间的时序弧

本节描述当timing组位于某个pin组中,且时序弧具有多个相关引脚时,如何标识这些时序弧。如下例所示,可以通过在timing组中使用名称列表来标识多条时序弧。

cell (my_and) { ... pin (A) { direction : input; capacitance : 1; } pin (B) { direction : input; capacitance : 2; } pin (C) { direction : output function : "A B"; timing (A_C, B_C) { related_pin : "A B"; ... }/* end timing() */ }/* end pin B */ }/* end cell */

这些时序弧的定义如下表所示:

起点终点名称
ACA_C
BCB_C
bundle组与单个相关引脚之间的时序弧

当timing组位于一个包含多个成员引脚的bundle组中,并且只有一个相关引脚时,需要在timing组中通过名称列表来指定由此产生的多条时序弧。

Library Compiler假定:名称列表中的第一个名称,对应从相关引脚到bundle组的成员列表中第一个引脚的时序弧,名称列表中的第二个名称,对应从相关引脚到bundle组的成员列表中第二个引脚的时序弧,依此类推。下面展示了一个例子。

... bundle (Q){ members (Q0, Q1, Q2, Q3); direction : output; function : "IQ"; timing (G_Q0, G_Q1, G_Q2, G_Q3){ timing_type : rising_edge; related_pin : "G"; } }

如果G是一个引脚(而不是另一个bundle组),这些时序弧的定义如下表所示:

起点终点名称
GQ0G_Q0
GQ1G_Q1
GQ2G_Q2
GQ3G_Q3

如果G是另一个成员数为4的bundle组,且G0、G1、G2和G3是G的成员引脚,这些时序弧的定义如下表所示:

起点终点名称
G0Q0G_Q0
G1Q1G_Q1
G2Q2G_Q2
G3Q3G_Q3
bundle组与多个相关引脚之间的时序弧

当timing组位于一个包含多个成员的bundle组内,并且每个成员都有对应的相关引脚时,需要在timing组中通过名称列表来指定由此产生的多条时序弧。

Library Compiler假定:名称列表中的第一个名称,对应从第一个相关引脚到bundle组的成员列表中第一个引脚的时序弧,名称列表中的第二个名称,对应从第二个相关引脚到bundle组的成员列表中第二个引脚的时序弧,依此类推。下面展示了一个例子。

bundle (Q){ members (Q0, Q1, Q2, Q3); direction : output; function : "IQ"; timing (G_Q0, H_Q0, G_Q1, H_Q1, G_Q2, H_Q2, G_Q3, H_Q3){ timing_type : rising_edge; related_pin : "G H"; } }

如果G是一个引脚(而不是另一个bundle组),这些时序弧的定义如下表所示:

起点终点名称
GQ0G_Q0
HQ0H_Q0
GQ1G_Q1
HQ1H_Q1
GQ2G_Q2
HQ2H_Q2
GQ3G_Q3
HQ3H_Q3

如果G是另一个成员数为4的bundle组,且G0、G1、G2和G3是G的成员引脚,这些时序弧的定义如下表所示:

起点终点名称
G0Q0G_Q0
HQ0H_Q0
G1Q1G_Q1
HQ1H_Q1
G2Q2G_Q2
HQ2H_Q2
G3Q3G_Q3
HQ3H_Q3

如果H也是一个成员数为4的bundle组,则适用同样的规则。

bus组与单个相关引脚之间的时序弧

本节描述当timing组位于一个包含多个比特的bus组中,并且这些比特共享同一个相关引脚时,如何标识由此产生的时序弧。可以通过在timing组中使用名称列表来标识这些多条时序弧。

Library Compiler假定:名称列表中的第一个名称,对应从相关引脚到bus组中最高有效位(MSB)的时序弧,名称列表中的第二个名称,对应从相关引脚到bus组中第二个最高有效位的时序弧,依此类推。下面展示了一个例子。

... bus (X){ /* assuming MSB is X[0] */ bus_type : bus4; direction : output; capacitance : 1; pin (X[0:3]){ function : "B'"; timing (B_X0, B_X1, B_X2, B_X3){ related_pin : "B"; } } }

如果B是一个引脚(而不是另一个4位的bus组),这些时序弧的定义如下表所示:

起点终点名称
BX[0]B_X0
BX[1]B_X1
BX[2]B_X2
BX[3]B_X3

如果B是另一个4位的bus组,且B[0]是B的最高有效位,这些时序弧的定义如下表所示:

起点终点名称
B[0]X[0]B_X0
B[1]X[1]B_X1
B[2]X[2]B_X2
B[3]X[3]B_X3
bus组与多个相关引脚之间的时序弧

本节描述当timing组位于一个包含多个比特的bus组中,并且每个比特都有其对应的相关引脚时所产生的时序弧。可以通过在timing组中输入名称列表来标识这些多条时序弧。

Library Compiler假定:名称列表中的第一个名称,对应从第一个相关引脚到bus组中最高有效位的时序弧,名称列表中的第二个名称,对应从第二个相关引脚到bus组中第二个最高有效位的时序弧,依此类推。下面展示了一个例子。

bus (X){ /* assuming MSB is X[0] */ bus_type : bus4; direction : output; capacitance : 1; pin (X[0:3]){ function : "B'"; timing (B_X0, C_X0, B_X1, C_X1, B_X2, C_X2, B_X3, C_X3){ related_pin : "B C"; } } }

如果B是引脚(而不是另一个4位的bus组),这些时序弧的定义如下表所示:

起点终点名称
BX[0]B_X0
CX[0]C_X0
BX[1]B_X1
CX[1]C_X1
BX[2]B_X2
CX[2]C_X2
BX[3]B_X3
CX[3]C_X3

如果B是另一个4位的bus组,且B[0]是B的最高有效位,这些时序弧的定义如下表所示:

起点终点名称
B[0]X[0]B_X0
CX[0]C_X0
B[1]X[1]B_X1
CX[1]C_X1
B[2]X[2]B_X2
CX[2]C_X2
B[3]X[3]B_X3
CX[3]C_X3

如果C也是一个4位的bus组,则适用同样的规则。

http://www.jsqmd.com/news/747285/

相关文章:

  • 终极指南:5个可复用转录UI组件,快速构建实时语音识别界面
  • Word分节符实战:搞定复杂页码、页眉页脚独立设置的终极指南
  • 使用 minimax-pdf 技能生成专业PDF文档
  • 为什么你的遥感模型总过拟合?Python解译中被忽视的3类空间自相关陷阱及scikit-learn+spatialEco双校正方案
  • LoongCollector SPL引擎详解:强大的流处理语言实战
  • 终极Postgres Explain可视化指南:掌握查询计划标签系统与异常节点检测技巧
  • 基于Qt C++的社区安防监控系统
  • 如何快速安装200+插件整合补丁:Honey Select 2终极增强指南
  • LM文生图镜像详细步骤:从https://gpu-q28fnko994-7860.web.gpu.csdn.net/访问到下载原图
  • 多机器人协同控制理论多移动机械臂【附代码】
  • 【2026年最新600套毕设项目分享】“校园资料分享微信小程序”(30218)
  • 基于Qt C++的赛事计时计分系统
  • 紧急!春耕部署倒计时15天:Java农业物联网平台上线前必须完成的12项合规性检查(含等保2.0农林专项条款)
  • 基于科幻小说《月球基底建造》第一章,世界观与国家航天中长期规划,环月轨道集群与太阳系深空前哨体系可行性研究报告
  • 从Faster R-CNN到Mask R-CNN:手把手解析ROIAlign如何解决像素偏差,提升分割精度
  • 终极GoCV人脸检测指南:5分钟掌握Haar级联分类器实战
  • StyleCopAnalyzers性能优化技巧:10个实战经验提升大型项目代码分析速度
  • Java AI推理引擎国产化落地:从零部署到高并发调优的7天速成手册
  • 【2026年最新600套毕设项目分享】微信评分小程序(30219)
  • 别被官方例程吓到!拆解SRIO IP的srio_request_gen模块,5步搞定自定义数据收发
  • 那台开始自己写代码的机器——Intern-Atlas 与自动架构师的崛起
  • 通过 Hermes Agent 配置指南快速接入 Taotoken 平台
  • 别再只会用示波器了!用Python+声卡DIY一个简易数字锁相放大器(DLIA)来测微弱信号
  • 终极指南:如何为你的项目选择最佳计算机视觉模型
  • KaTrain快捷键大全:30个高效操作技巧让你的训练事半功倍
  • Godot SpriteMesh插件:2D像素精灵转3D网格的完整指南
  • FPGA课程设计避坑指南:如何为你的MIPS模型机设计高效的测试程序(Modelsim+Vivado)
  • RAG系统出错别再“重跑“了!Doctor-RAG教你精准定位、局部修复
  • 【2026年最新600套毕设项目分享】英语互助小程序(30220)
  • 故障预警准确率提升68%的关键技巧,深度拆解LSTM+Prophet融合预测架构