第四章 基于Xilinx芯片的Verilog进阶设计
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
嵌入式系统工程系
企业代码风格
8.赋值
force/release 仅用于debug,对寄存器和线网均有用; 避免使用Disable assign/deassign 仅用于仿真加速仅对寄存器有用; (可综合设计问题) 对任何reg赋值用非阻塞赋值代替阻塞赋值, reg 的非 阻塞赋值要加单位延迟,但异步复位可加可不加。 (reg赋值问题,仿真赋值延迟问题)
嵌入式系统工程系
面向硬件电路的设计方法
时序延迟信号
reg a, a_d1, a_d2; always @ (posedge clk or negedge rst) begin if (~rst) begin a_d1 <= #TP 0; a_d2 <= #TP 0; end else begin a_d1 <= #TP a; a_d2 <= #TP a_d1; end end
嵌入式系统工程系
代码风格与可综合设计
同步电路设计
嵌入式系统工程系
代码风格与可综合设计
同步电路设计的模块划分
信息隐蔽、抽象: • 避免跨模块控制,边界清晰; 端口明确: • 禁制多重功能和无用接口; 时钟域区分: • 异步FIFO或双端口RAM实现多时钟域隔离; • 低频时钟域尽可能划分到一个模块中; 资源优化: • 尽量使用厂商提供的原语 寄存器划分: • 模块的输出尽可能采用寄存器输出(reg型)
嵌入式系统工程系
面向硬件电路的设计方法
基于全局时钟的同步设计
数据存储在FPGA的寄存器或存储器中,时钟可看作执 行控制器; 串行算法的执行可以按照时钟节拍的顺序进行控制, 寄存器输出以及组合逻辑通常作为控制条件。 例如:采用计数器控制状态变化或数据处理过程。
嵌入式系统工程系
面向硬件电路的设计方法
嵌入式系统工程系
代码风格与可综合设计
Verilog HDL语言本身的规范只面向仿真
不使用综合工具不支持的Verilog结构
• 除了wire、reg的多数数据类型 • 开关级原语 • deassign、wait等行为语句 • UDP和specify模块 ……
遵循可综合设计原则
代码综合出预想的逻辑 行为描述的完整性
嵌入式系统工程系
企业代码风格
9.组合逻辑与时序逻辑
如果一个事件持续几个时钟周期设计时就用时序逻辑 代替组合逻辑; 内部总线不要悬空,在default状态要把它上拉或下拉。
嵌入式系统工程系
企业代码风格
10.宏与参数
为了保持代码的可读性常用 `define做常数声明; 把`define放在一个独立的文件中; 参数parameter 必须在一个模块中定义,不要传替参 数到模块; 如果希望宏的作用域仅在一个模块中就用参数来代替。
基于FPGA实现的Verilog设计特点
并行化
同步控制 实现代价
嵌入式系统工程系
面向硬件电路的设计方法
硬件实现的并行化
从电路上来看:
• 只要芯片上电,所有逻辑就开始工作。
从代码上来看:
• 所有的描述语句之间是并行执行的; • always语句在边沿触发条件下的行为描述均采用非阻塞 赋值,并行执行; • 面向RTL级电路的电路设计易于实现流水操作; • 与一般高级语言的顺序代码为主的设计方法有本质的区 别。
嵌入式系统工程系
企业代码风格
8.赋值
Verilog 支持两种赋值:过程赋值(procedural) 和连续 赋值(continuous) ,过程赋值用于过程代码(initial, always, task or function) 中 给 reg 和 integer 变 量 time\realtime、real赋值,而连续赋值一般给wire变 量赋值; (reg型与wire型赋值问题) always @(敏感表敏感表要完整如果不完整将会引起 仿真和综合结果不一致; (电平触发的意外锁存器问题)
嵌入式系统工程系
通用代码风格
if和case不完整分支造成的意外锁存器
当always语句使用电平触发时有可能产生锁存器。 参见P106例3-12和例3-13 当always语句使用时钟沿触发时不会产生,此时只产 生寄存器。
嵌入式系统工程系
通用代码风格
reg型信号只能在一个always语句中赋值
嵌入式系统工程系
代码风格与可综合设计
同步电路设计
优点 • 容易使用寄存器的异步复位/置位端,以使整个电路有一个确 定的初始状态; • 有效避免毛刺,提高可靠性; • 简化时序分析过程; • 减少对工作环境的依赖性,提高可移植性; 原则 • 尽可能使用单时钟(全局时钟) • 尽可能使用单时钟沿触发(posedge clk) • 避免使用门控时钟(组合逻辑驱动的时钟) • 若使用分频时钟应当统一管理
嵌入式系统工程系
第四章 基于Xilinx芯片Verilog进阶设计
面向硬件电路的设计方法
代码风格与可综合设计
通用代码风格 专用代码风格 企业代码风格
企业级大规模FPGA应用设计方法
原语的使用
嵌入式系统工程系
面向硬件电路的设计方法
将具体功能形成硬件的RTL级模型
编写代码始终要考虑硬件如何实现
嵌入式系统工程系
企业代码风格
2.Module
严格芯片级模块的划分,只有顶层包括IO引脚; 模块输出寄存器化,对所有模块的输出加以寄存,输 出的驱动强度和输入的延迟可以预测,从而使得模块 的综合过程更简单; 将关键路径逻辑和非关键路径逻辑放在不同模块,实 施不同的优化策略。
嵌入式系统工程系
目标:功能正确,性能最优
嵌入式系统工程系
通用代码风格
逻辑复用
Synplify提供逻辑复用选项,但若要获得最佳的复用 效果,在源代码设计中应采用显式的复用控制逻辑; 节约面积。
逻辑复制
Synplify提供最大扇出选项,如果扇出过大(驱动过 多后续逻辑),需增加缓冲器提高驱动能力,但信号 延迟增大; 增加面积。
嵌入式系统工程系
企业代码风格
2.Module
每行应限制在80个字符以内以保持代码的清晰美观和 层次感; 模块实例名应采用”U_xx”命名,端口采用显式关联 而非隐式关联; 用一个时钟的上沿或下沿采样信号,不能混合使用; 如果一定要使用时钟双沿,可使用180度相位时钟; 在模块中增加注释; Module 名要用大写标示,且应与文件名保持一致;
嵌入式系统工程系
企业代码风格
2.Module
顶层模块应只是内部模块间的互连,除了内部的互连 和模块的调用外尽量避免再做逻辑(如不能再出现对 reg变量的always赋值,不能再用assign语句完成复 杂逻辑); 每一个模块应在开始处注明文件名功能描述引用模块 设计者设计时间及版权信息(ISE生成模板); 不要对input进行驱动, 在module 内不要存在没有驱动 的信号,更不能在模块端口中出现没有驱动的输出信 号,避免在仿真或综合时产生warning,干扰错误定位; (避免由于未驱动产生的x,z)
实现代价
“面积”和“速度”的综合考虑:
• “面积”指所占用的FPGA资源(FF和LUT); • “速度”指芯片稳定运行所达到的最高频率。
“面积”和“速度”是一对矛盾,可相互转化:
• “面积”优先:资源复用; • “速度”优先:冗余同构部件。 ISE 的Map选项: 优化策略可选择Area和Speed的优化策略
嵌入式系统工程系
通用代码风格
逻辑结构
树状结构优于链式结构,缩短延迟级数。
if语句和case语句使用原则
if语句面积小,延迟大;case语句面积大,速度快。 if适合对速度无特殊要求的场合;case适合高速编解码 电路。 if分支具有优先级,case分支无优先级。 if不可嵌套技术过多,一般不超过3-4层。 兼顾面积和速度,if和case混合使用。
嵌入式系统工程系
代码风格与可综合设计
代码风格(包括书写规范和描述方法)
通用代码风格 • Verilo来自百度文库 HDL语言规范,硬件无关,性能未必最优; 专用代码风格 • 基于具体芯片的结构和资源,性能优化,移植性可能受影响。 “华为Verilog HDL设计规范” Sun公司 “Verilog Style and Coding Guidelines” “Actel HDL Coding Style Guider” 注重代码的硬件实现质量。
反向信号
尽量使用符号~,而不使用not原语; 不要尝试用多个反向器级联来增加需要的信号延迟; 反向信号驱动多个负载可采用分散反向。 (综合工具可自动优化)
嵌入式系统工程系
企业代码风格
1.基本书写规则
用有意义而有效的名字; 用连贯的缩写;
Clk Rst
用最右边(左边)的字符下划线表示低电平有效,高 电平有效的信号不得以下划线表示;
嵌入式系统工程系
专用代码风格
SRL16的使用
SRL16是一种基于LUT的移位寄存器; 可生成任意位宽和深度的移位寄存器; srl16_based_ram my_shift_ram ( .clk ( ), .d ( ), .q ( ) );
嵌入式系统工程系
专用代码风格
触发器资源分配
尽量使用库中的触发器资源; 状态机编码尽可能采用“独热码”(one-hot)。 (synplify综合工具可提供相关功能)
嵌入式系统工程系
企业代码风格
6. case语句
case语句通常综合成一级多路复用器,if-then-else则 综合成优先编码的串接的多个多路复用器; 所有的Case 应该有一个default case 允许空语句 Default : ;
嵌入式系统工程系
企业代码风格
7.函数
在function的最后给function赋值; 函数中避免使用全局变量,否则容易引起HDL行为级 仿真和门级仿真的差异。 注意:函数与任务的调用均为静态调用
Rst_ Trdy_
名 字 一 般 首 字 符 大 写 , 其 余 小 写 ( 但 parameter, integer 定义的数值名可全部用大写),两个词之间要 用下划线连接
Packet_addr Data_in
嵌入式系统工程系
企业代码风格
1.基本书写规则
全局信号名字中应包含信号来源的一些信息; 同一信号在不同层次应保持一致性; 自己定义的常数类型等用大写标识 parameter CYCLE = 100; 避免使用保留字作为信号、模块名称; 添加有意义的后缀使信号名更加明确。
企业代码风格
3.线网与寄存器
一个reg变量只能在一个always语句中赋值; 向量有效位顺序的定义一般是从大数到小数; 模块输出端口,对线网和寄存器类型的要做声明; 使用克综合的的线网和寄存器类型。
嵌入式系统工程系
企业代码风格
4.表达式
用括号来表示执行的优先级,使优先级阅读更清晰; (注意不要造成额外的延迟) 用一个函数(function)来代替表达式的多次重复,仿真 中经常使用的一组描述可以写到一个任务(task)中;
嵌入式系统工程系
通用代码风格
关键路径信号处理
引起电路建立时间不足的信号路径成为关键路径 组合电路关键路径提取采用逻辑拆分方式,降低关键 信号的组合延迟级数。 分析下面语句中b所经过的LUT级数。 assign y = a & b & c | d & e & b; assign t = a & c | d & e; assign y = b & t;
嵌入式系统工程系
企业代码风格
5. if语句
向量比较时比较的向量宽度要相等,不相等时建议采 用显示扩展; 每一个if 都应有一个else 和它相对应; 应注意if ..else if ...else if ...else 的优先级; 如果变量在if-else 或case 语句中做非完全赋值则应给 变量一个缺省值。 (always语句的自身要求)
最常见的HDL行为描述建模错误之一
避免assign不确定语句
assign signal_a = #4 ~signal_a; #4被综合工具忽略掉
嵌入式系统工程系
专用代码风格
时钟信号分配原则
使用全局时钟,通过BUFG驱动,时钟信号到达各个寄 存器的延迟相同。 减少时钟信号种类 避免时钟毛刺信号(不使用门控时钟)