仅对英特尔可见 — GUID: olu1504069671746
Ixiasoft
2.4.2.1. 高速时钟域(High-Speed Clock Domains)
2.4.2.2. 重构环路(Restructuring Loops)
2.4.2.3. 控制信号反压(Control Signal Backpressure)
2.4.2.4. 使用FIFO状态信号的流程控制
2.4.2.5. 包含skid缓冲器的流程控制
2.4.2.6. Read-Modify-Write存储器
2.4.2.7. 计数器和累加器
2.4.2.8. 状态机
2.4.2.9. 储存器
2.4.2.10. DSP模块
2.4.2.11. 一般逻辑
2.4.2.12. 求模与除法
2.4.2.13. 复位
2.4.2.14. 硬件重用
2.4.2.15. 算法要求
2.4.2.16. FIFO
2.4.2.17. 三元加法器(Ternary Adders)
5.2.1. 不足的寄存器(insufficient Registers)
5.2.2. 短路径/长路径(short path/long path)
5.2.3. 快进限制(Fast Forward Limit)
5.2.4. 环路(loop)
5.2.5. 每个时钟域一个关键链
5.2.6. 相关时钟组中的关键链
5.2.7. 复杂的关键链
5.2.8. 延伸到可定位的节点
5.2.9. 域边界入口和域边界出口(Domain Boundary Entry and Domain Boundary Exit)
5.2.10. 包括双时钟存储器的关键链
5.2.11. 关键链比特和总线
5.2.12. 延迟线
仅对英特尔可见 — GUID: olu1504069671746
Ixiasoft
2.4.1.4.2. 环路流水线演示
以下演示了用于优化实例设计中的累加器的正确环路流水线化。在最初的实现中,累加器数据输入 in乘以x,然后与之前的out值相加,乘以y。此演示使用以下技术来提高性能:
- 实现正向逻辑的分离
- 重定时环路寄存器
- 通过级联逻辑创建反馈环路等同
图 54. 原始环路结构
原始环路结构实例Verilog HDL代码
module orig_loop_strct (rstn, clk, in, x, y, out); input clk, rstn, in, x, y; output out; reg out; reg in_reg; always @ ( posedge clk ) if ( !rstn ) begin in_reg <= 1'b0; end else begin in_reg <= in; end always @ ( posedge clk ) if ( !rstn ) begin out <= 1'b0; end else begin out <= y*out + x*in_reg; end endmodule //orig_loop_strct
优化的第一阶段是重写逻辑,从环路(loop)中移除尽可能多的逻辑,并创建一个正向逻辑模块。重写的目标是从反馈环路中去除尽可能多的工作。Compiler无法自动优化反馈环路中的任何逻辑。从环路中删除逻辑时,请考虑以下建议:
- 在环路之前评估尽可能多的决策并执行尽可能多的计算(不直接依赖环路值)。
- 在将逻辑传递到环路前首先将其传递到寄存器阶段。
重写逻辑之后,Compiler现在可以自由地重定时移动到正向路径上的逻辑。
图 55. 从环路中分离出正向逻辑
在下一个优化阶段,重定时环路寄存器,以确保设计功能与原始环路电路相同。
图 56. 重定时环路寄存器
最后,通过高显边界中的逻辑来重复第一个优化步骤,从而进一步优化环路。
图 57. 级联环路逻辑,Hyper-Retimer和综合优化的结果(四级优化)
四级优化实例Verilog HDL代码
module cll_hypr_rtm_synopt ( rstn, clk, x, y, in, out); input rstn, clk, x, y, in; output out; reg out; reg in_reg; wire out_add1; wire out_add2; wire out_add3; wire out_add4; reg out_add1_reg1; reg out_add1_reg2; reg out_add1_reg3; reg out_add1_reg4; always @ ( posedge clk ) if ( !rstn ) begin in_reg <= 0; end else begin in_reg <= in; end always @ ( posedge clk ) if ( !rstn ) begin out_add1_reg1 <= 0; out_add1_reg2 <= 0; out_add1_reg3 <= 0; out_add1_reg4 <= 0; end else begin out_add1_reg1 <= out_add1; out_add1_reg2 <= out_add1_reg1; out_add1_reg3 <= out_add1_reg2; out_add1_reg4 <= out_add1_reg3; end assign out_add1 = x*in_reg + ((((y*out_add1_reg4)*y)*y)*y); assign out_add2 = out_add1 + (y*out_add1_reg1); assign out_add3 = out_add2 + ((y*out_add1_reg2)*y); assign out_add4 = out_add3 + (((y*out_add1_reg3)*y)*y); always @ ( posedge clk ) begin if ( !rstn ) out <= 0; else out <= out_add4; end endmodule //cll_hypr_rtm_synopt