
soc设计6_rtl代码概要.ppt
36页第六章,RTL代码编写指南,内容大纲,编写RTL代码之前的准备 可综合RTL代码编写指南 调用Synopsys DesignWare来优化设计,内容大纲,编写RTL代码之前的准备 可综合RTL代码编写指南 调用Synopsys DesignWare来优化设计,编写RTL代码之前的准备,RTL代码编写前需要讨论并确定的问题 是否与设计团队共同讨论过设计中将会发生的关键问题 是否已准备好设计文档了 设计文档中总线是如何定义的 设计文档中是否定义了设计的划分方法 设计中的时钟是怎样考虑的 对I/O是否有特殊需求 是否需要其他IP,这些IP的包装(Package)是否完整地包括了每一步设计所需的文件 是否考虑了IP复用设计 是否考虑了可测性设计 整个设计的面积是引脚限制还是门数限制 设计的运行速度是否能超过工艺速度极限 时序和后端设计是否有特殊的需求,与团队共同讨论设计中的问题,通过讨论,团队的每个成员必须清楚设计规则 版本控制、目录树和其他设计组织的问题也必须在团队内广泛讨论,达成共识 这些问题都属于顶层问题或项目管理问题,大家必须遵守同一个设计规则 团队成员间的充分交流是一个设计能够成功的关键因素,根据芯片结构准备设计说明书,模块功能的简要介绍 顶层模块的接口信号; 所有控制寄存器地址及功能描述; 顶层模块的主要结构图; 子模块功能; 子模块的接口信号; 子模块的主要结构图; 子模块的实现原理; 时钟信号的连接(如Multicycle Path、FalsePath、Negedge Clock、Generated Clock) 复位信号的连接(如Gated Reset、Soft Reset),总线设计的考虑,如果不是特别要求的话,尽量使用单向总线 但是如果在以前出于布线和其他以前版本兼容性的考虑,一直采用的是双向总线,现在如果没有很好的处理而使用单向总线也可能会产生问题 在开始编码前获得每一条总线和接口的设计文档,确保对其功能和时序都很清楚,这样的话可以帮助在编写代码前创建高层次的模型。
模块的划分,模块的划分,模块的划分——芯片级的模块划分,顶层模块组织结构图,模块的划分——核心逻辑的模块划分,在对核心逻辑进行模块划分时,要避免子模块间出现连接用的粘附逻辑,粘附逻辑,消除粘附逻辑,模块的划分——核心逻辑的模块划分,应尽可能地把相关的组合逻辑集中到一个模块中处理,这是因为综合器在默认的工作模式下综合优化时,不能跨越模块边界对相关的组合逻辑做归并优化处理组合逻辑被分散在多个模块,组合逻辑归并,模块的划分——把多周期路径或伪路径限制到一个模块中,如果在设计中包含了多周期路径或伪路径,应尽可能地把这些逻辑限制到一个模块中,并在代码编写时用注释行明确指出 把多周期路径限制到一个模块中处理可以减少综合时间和优化非多周期路径的综合结果 把多周期路径或伪路径限制到一个模块中,可以方便设计者给出相关的综合及静态时序分析的约束,同时也便于设计者在后端设计实现后进行检查,多周期路径,模块的划分——根据时钟的相关性划分模块,应当尽量根据时钟的相关性来划分模块简单地说,就是将时钟分频、门控单元和复位产生等电路尽量放在同一模块中 这么做使得在综合的时候便于设置时钟约束,同步时钟模块,对时钟的处理,设计中需要多少个时钟 芯片中的时钟是从哪里来的呢 是内部产生的吗 是由锁相环(PLL)产生的吗 还是由电路分频器、异步计数器、串行计数器或者同步计数器提供的时钟,IP的选择及设计复用的考虑,系统结构设计做好模块划分时,必须确定哪些模块基于标准单元库进行设计,哪些模块需要购买IP,IP模块的对接需要增加哪些连接性设计 模块间的接口协议要尽可能的简单,模块间的接口定义要尽可能与国际上通用的接口协议完全一致 要注意积累IP和IP集成的经验 如果是对硬IP的集成,还必须在时钟分布、关键路径的布线、电源和地线的布线、IP模块支持的测试结构等方面进行考虑,与系统芯片保持一致,对可测性的考虑,复位信号在测试过程中应该被设置为无效,否则测试过程可能被复位信号打乱 门控时钟在测试中应当有效 三态的驱动在测试中必须有可知的输出 边界扫描(Boundary Scan)问题:边界扫描的逻辑应当放在一个单独的设计模块中,边界扫描的生成主要在综合中进行 RAM的测试 测试控制:建议将测试控制逻辑(如测试模式选择)、测试时钟及复位信号的控制信号等放在单独的模块中,对芯片速度的考虑,设计者计划在设计中实现多少功能,运行在什么速度下 采用什么工艺实现,对设计做什么改动来实现速度要求 选择流水线结构还是寄存器重新排序 组合逻辑不能太多地集中在两个寄存器之间 有时候为了改进速度,会选择特殊的结构单元,如单周期乘法器、串行加法器链、复杂控制逻辑、大指令解码单元等,这些可以在RTL中直接调用Synopsys的DesignWare库,对布线的考虑,把大量信号组合起来形成一个大的逻辑,不仅会造成由于这一级组合电路太多而难以满足时序要求,而且会形成一个很大的多路选择器(Mux),造成连线过于集中,从而在一小块面积内占用大量的布线资源 多个片上RAM/ROM共用一个BIST模块,由于BIST信号将连到每一块RAM/ROM上,在这个BIST模块附近常会出现布线阻塞,内容大纲,编写RTL代码之前的准备 可综合RTL代码编写指南 调用Synopsys DesignWare来优化设计,可综合RTL代码的编写准则——命名,模块的命名 在系统设计阶段应该为每个模块进行命名,最终的顶层模块应该以芯片的名称来命名 在顶层模块中,除I/O引脚和不需要综合的模块外,其余作为次级顶层模块,建议以xx_core.v命名 对于多处理器的设计,共享模块以(模块名_处理器名)命名 模块的命名和该模块的功能相结合,可综合RTL代码的编写准则——命名,信号的命名 所有信号的命名由小写字母、下划线和数字组成,并且以小写字母开头 低电平有效的信号后一律加下划线和字母n或b,如sysrst_n、fifofull_b 总线由高位到低位命名,如bus[31∶0] 不需要在信号名字中表明信号的方向,如用my_signal比my_signal_in更简明 命名应当尽量保持一致性,一些全局的信号(clock,reset)在每个子模块中都有相同的名字,两个子模块的接口信号也应当一致。
在信号列表中,以注释形式指明信号的方向 my_module ( my_signal, // input from other_module );,可综合RTL代码的编写准则——命名,信号的命名 在模块的例化过程中采用信号名称连形式,避免使用指明位置的形式,并且每行例化一个信号 my_module my_module_inst( .signal (signal), //signal input from other module .a_bus (a_bus), //address bus from core module ); 在信号列表中,将clk、reset等扇出较大的信号列在最后,统一规范,便于阅读 my_module ( signals_to_from_block_A, // description signals_to_from_block_B, // description reset, clk ); 命名要尽量显得有意义,说明它的用途、目的、功能等,可综合RTL代码的编写准则——命名,同步触发器的命名 如果有异步信号需要同步,那么该同步触发器的命名建议加上“synch”,如synch_stage_1 时钟信号的命名 全局时钟以clk命名 其他时钟信号的命名需要包含相关的频率信息,如clk_32k 文件的命名 一个文件只能包含一个模块,而文件名应该与模块名相同,这样做可以方便修改设计,可综合RTL代码的编写准则——编码风格,利用缩进来显示代码的逻辑结构,缩进一致,并以Tab为单位 语句块之间由begin和end划分清楚 首行缩进使得代码结构清晰,可读性增强 同一个层次的所有语句左对齐 initial、always等语句块的begin关键词跟在本行的末尾,相应的end关键词与initial、always对齐 对于时序单元必须采用非阻塞赋值 组合逻辑采用阻塞赋值 不要将阻塞赋值和非阻塞赋值混合在一个程序块中 保证敏感列表完整,避免仿真和综合过程中出现功能错误 尽量不使用循环结构 对代码加上适当的注释,编码风格——阻塞赋值,Data_Out所赋的值将是信号Intermediate_Variable的新值,即In_A end,编码风格——非阻塞赋值,Data_Out所赋的值将是Intermediate Variable原来的值,所以在进行代码编写时必须根据功能需求来决定采用何种赋值形式。
reg Data_Out; reg Intermediate_Variable; always @(In_A, In_B, Intermediate_Variable) begin Intermediate_Variable = In_A end,可综合RTL代码的编写准则——综合考虑,每个模块尽可能只使用一个主时钟 复位信号以“reset”命名,表示高电平有效,如果低电平有效则命名为“reset_b”通常来说复位信号为异步信号 模块的分割最好能够使得在模块内部的输入和输出端直接和触发器相连接,这样在综合的过程中,时序约束的设置将非常方便 不在数据通路上的触发器都需要有复位信号 数据通路上触发器的复位信号根据流水线的划分来设置 如果电路中同时存在具备复位信号的触发器和不具备复位信号的触发器,不要将它们放在一个程序块中 在case语句中,指明所有可能出现的情况,如果不需要所有情况,加上default语句,可综合RTL代码的编写准则——综合考虑,代码的描述应该尽量简单 尽量保证每个模块的简练和易读性,如果模块太大时可以考虑将其划分为几个子模块 在内部逻辑中避免使用三态逻辑 不要在代码描述中加入specify语句去规定多周期路径 避免触发器在综合过程中生成锁存器,在if else语句中,如果设计没有很好地覆盖到各种情况,就很有可能综合产生一些锁存器的结构 尽量避免异步逻辑、带有反馈环的组合电路及自同步逻辑 尽量把需要综合的代码置于节点模块,层次化模块仅起到连接节点模块的作用 输入和输出信号在声明的时候默认为wire类型,可综合RTL代码的编写准则——综合考虑,避免不必要的函数调用,重复的函数调用会增加综合次数,不仅造成电路面积的浪费,还会使综合时间变长 通常在Verilog语言中,有always和initial两个程序块,synopsys的综合工具忽略initial程序块,并将产生警告 在综合过程中,工具将忽略电路中的延时语句,利用综合进行代码质量检查,作为一个前端设计工程师,在RTL代码编写好后,无论是否负责代码的综合,在提交RTL代码之前,都应该检查RTL代码的可综合性 在综合的log file中,可能有出错的警告吗?是否逐条检查了这些警告? 在综合的log file中,除了会报出RTL的问题外,还会报出约束条件是否存在的问题 在时序分析报告中,哪里是设计的关键路径?它们是设计者所想得到的吗?不满足时序要求的原因明显吗?能通过简单修改代码就解决吗?能隔离这条路径或者它是一大堆逻辑中的一部分吗? 在设计中有多少路径违反了时序约束,违反了多少,这是对结果质量的度量,也是对“还有多少工作要做”的度量。
这些违反时序的路径是否是公用起始点或终止点 关键路径里包含多少级逻辑单元,内容大纲,编写RTL代码之前的准备 可综合RTL代码编写指南 调用Synopsys DesignWare来优化设计,调用Synopsys DesignWare优化设计,DesignWare是由Synopsys公司提供的IP库,其中的Foundation IP中包含很多设计中经常会用到的功能单元,这些功能单元是用特定的架构实现的 使用Synopsys的综合工具时调用DesignWare中的IP进。
