juremy420

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

完成了昨晚的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;


参考文章

posted on 2023-09-03 01:51  Juremy-420-bling  阅读(29)  评论(0编辑  收藏  举报