IC设计时序优化 笔记
完成了昨晚的IC设计的笔试之后,认识到自己遗忘了很多设计方面的知识。而设计和验证的笔试题风格又完全不一样。
特此开一个系列来整理IC设计相关的知识,设计的题目需要掌握:数电基础(甚至是晶体管级的门电路和晶体管的特性),Verilog熟练程度,常见电路设计,时序优化,计算slack和相关计算。这样自己复习的时候也可以用上。
根据自己的掌握情况来看,只需要整理三个专题,分别是常见电路设计,时序优化,slack计算等。
优先级选择逻辑的拆分
- 特点:级联的多个mux,由有优先级的多个选择信号端,多个待选择的输入信号构成输入输出。此时,存在一路待选择输入信号的关键路径(意思是该输入延时最大,最晚到达)。
- 问题:上述特点的电路存在什么问题呢,低优先级的输入所在的关键路径,导致整个电路的时延很大。
wire src0_sel, src1_sel, src2_sel, src3_sel, src4_sel;
wire src0_data, src1_data, src2_data, src3_data, src4_data, src5_data;
wire output;
//priority 0>1>2>3>4
//before
assign output = src0_sel ? src0_data :
src1_sel ? src1_data :
src2_sel ? src2_data :
src3_sel ? src3_data :
src4_sel ? src4_data :
src5_data ?
- 分析:假设现在src3_data为关键路径,位于5级深度中的第4级,对整个电路的延时非常有影响
- 优化方法:将高于关键路径的分支并行单独进行判断,最后再与关键路径进行优先级判断
//after
wire rslt_dat_hi_pri;
wire src_hi_pri_sel;
assign src_hi_pri_sel = src0_sel | src1_sel | src2_sel;
assign rslt_dat_hi_pri = src0_sel ? src0_data :
src1_sel ? src1_data :
src2_data;
assign output = src_hi_pri_sel ? rslt_dat_hi_pri :
src3_sel ? src3_data :
src4_sel ? src4_data :
src5_data;
{width=20% height=auto}
- 结果:整个电路的深度变为4级,而原来关键路径的逻辑深度,从原来的4级变为2级,能极大降低时延,但是又保证功能的正确性
- 代价:增加了一个多输入的or,和一个2选1的mux。
- 方法描述:将关键路径的前一级mux前移,该mux的输入是用一个或门对所有更高优先级信号的判断。需要注意的是,src2_sel的选择已经在或门中实现了,所以src2_data可以直接作为src1_sel=0时的数据输入端。
大位宽比较器的巧用
- 背景:由于非2的整数次幂位宽的比较器在综合时默认会向上取2的整数次幂。现在该大位宽的比较器位于关键路径上
- 解决:将与该比较器有关的逻辑纳入比较器的输入进行比较,可以减少一级逻辑深度。
wire cmp_rslt_valid;
wire cmp_rslt;
wire [37:0] cmp_src_0, cmp_src_1;
//before
assign cmp_rslt = cmp_rslt_valid & (cmp_src_0 == cmp_src_1);
//after
assign cmp_rslt = {cmp_rslt_valid,cmp_src_0} == {1'b1, cmp_src_1};
2选1选择逻辑的优化
这里还没有弄明白,为什么将相与放到打拍前,就能优化时序,跟pipeline有关?
wire clk, rstn
wire src0_sel;
wire[7:0] src0_dat_pre, src1_dat_pre;
reg [7:0] src0_dat, src1_dat;
wire rslt_dat;
//before
always @ (posedge clk) begin
src0_dat <= src0_dat_pre;
src1_dat <= src1_dat_pre;
end
assign rslt_dat = {8{src0_da == 1'b1}} & src0_dat |
{8{src0_da == 1'b0}} & src1_dat;
//after
always @ (posedge clk) begin
src0_dat <= {8{src0_da == 1'b1}} & src0_dat;
src1_dat <= {8{src0_da == 1'b0}} & src1_dat;
end
assign rslt_dat = src0_dat | src1_dat;
参考文章