相关阅读数字IC前端https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482进位保留乘法器仍然保留了阵列乘法器的排列规则只不过其进位沿斜下方向传递。如果进一步利用树形结构来组织这些进位保留加法器就能够获得更短的关键路径延迟和更小的器件开销这种乘法器结构就称为华莱士树(Wallace Tree)乘法器。图1给出了一个四位华莱士树乘法器的例子。图中共有十六个部分积这些部分积分别由被乘数和乘数各位进行与运算得到。图中的斜杠/表示一个全加器其输出分别连接到右上角的本位和以及左下角送往高位的进位带反斜杠\的/表示半加器。图1 华莱士树乘法器的覆盖过程华莱士树的第一阶段是将所有部分积按行分组每三行作为一组并在组内使用进位保留加法器进行压缩。这里的进位保留加法器包括全加器和半加器两种形式当某一列中有三个部分积时使用全加器进行压缩当某一列中有两个部分积时使用半加器进行压缩当某一列中只有一个部分积时则无需压缩直接保留。在分组过程中若存在无法凑满三行的多余部分则不在本阶段压缩而是直接传递到下一阶段。在本例中这对应的就是第四行部分积。在下一阶段中继续按照“三行一组”的方式进行压缩直到最终只剩下两行部分积。此时再使用一个普通的多位传播进位加法器、超前进位加法器或其他两数相加的向量合并器对这两行结果做最后合并。可以看到在这个四乘四的例子中只需要两个压缩阶段就能将十六个部分积压缩为两行。整个结构共使用了五个全加器和三个半加器这里不包括最后的向量合并加法器。具体的Verilog实现见附录使用Modelsim进行仿真的结果如图2所示。采用Synopsys的综合工具Design Compiler并基于0.13μm工艺库进行综合得到的结果如图3所示。图2 华莱士树乘法器仿真结果图3华莱士树乘法器综合结果在Design Compiler中使用report_timing命令可以得到关键路径延迟如图4所示。可以看出该乘法器的关键路径延迟仅为1.39ns。其性能优于进位保留乘法器也明显优于普通阵列乘法器。这是因为华莱士树结构将部分积进行分组并并行处理结果大约在三级加法器延迟之后即可得到从而显著缩短了关键路径。图4 华莱士树乘法器关键路径报告在Design Compiler中使用report_area命令可以得到所设计电路的面积占用情况如图5所示。可以看到该结构的面积略大于阵列乘法器这主要是由于最后一级向量合并加法器带来的额外开销。不过这部分面积并不会随着数据位宽的增加而急剧增长。如果暂时不考虑最终向量合并加法器的影响那么阵列乘法器使用了八个全加器和四个半加器进位保留乘法器使用了六个全加器和六个半加器华莱士树乘法器仅使用了五个全加器和三个半加器。因此华莱士树乘法器在较大位宽情况下能够有效降低硬件开销同时对传播延迟的优化也十分明显。图5 华莱士树乘法器面积报告下面给出一个四乘四Wallace Tree乘法器的Verilog实现其中三个主要阶段已经使用注释标出。module Wallace_Multiplier( input [3:0] A, input [3:0] B, output [7:0] Sum ); wire [3:0] partial_product [3:0]; wire [3:0] W_level1_sum, W_level1_carry; wire [3:0] W_level2_sum, W_level2_carry; // 产生部分积 assign partial_product[0] B[0]?A:0; assign partial_product[1] B[1]?A:0; assign partial_product[2] B[2]?A:0; assign partial_product[3] B[3]?A:0; // 阶段1 // *************************************************** Adder_half adder_half_u1( .Add1 (partial_product[0][1]), .Add2 (partial_product[1][0]), .Res (Sum[1]), .Carry (W_level1_carry[0]) ); Adder adder_u1( .Add1 (partial_product[0][2]), .Add2 (partial_product[1][1]), .I_carry (partial_product[2][0]), .Res (W_level1_sum[1]), .Carry (W_level1_carry[1]) ); Adder adder_u2( .Add1 (partial_product[0][3]), .Add2 (partial_product[1][2]), .I_carry (partial_product[2][1]), .Res (W_level1_sum[2]), .Carry (W_level1_carry[2]) ); Adder_half adder_half_u2( .Add1 (partial_product[1][3]), .Add2 (partial_product[2][2]), .Res (W_level1_sum[3]), .Carry (W_level1_carry[3]) ); // *************************************************** // 阶段2 // *************************************************** Adder_half adder_half_u3 ( .Add1 (W_level1_sum[1]), .Add2 (W_level1_carry[0]), .Res (Sum[2]), .Carry (W_level2_carry[0]) ); Adder adder_u3 ( .Add1 (W_level1_sum[2]), .Add2 (W_level1_carry[1]), .I_carry (partial_product[3][0]), .Res (W_level2_sum[1]), .Carry (W_level2_carry[1]) ); Adder adder_u4 ( .Add1 (W_level1_sum[3]), .Add2 (W_level1_carry[2]), .I_carry (partial_product[3][1]), .Res (W_level2_sum[2]), .Carry (W_level2_carry[2]) ); Adder adder_u5 ( .Add1 (W_level1_carry[3]), .Add2 (partial_product[2][3]), .I_carry (partial_product[3][2]), .Res (W_level2_sum[3]), .Carry (W_level2_carry[3]) ); // *************************************************** // 向量合并 // *************************************************** assign Sum[7:3] {partial_product[3][3], W_level2_sum[3:1]} {W_level2_carry[3:0]}; assign Sum[0] partial_product[0][0]; // *************************************************** endmodule // 半加器 module Adder_half( input Add1, input Add2, output Res, output Carry ); assign Res Add1 ^ Add2; assign Carry Add1 Add2; endmodule // 全加器 module Adder( input Add1, input Add2, input I_carry, output Res, output Carry ); assign Res Add1 ^ Add2 ^ I_carry; assign Carry (Add1 Add2) | ((Add1 ^ Add2) I_carry); endmodule华莱士树乘法器这种分阶段压缩的特点也使其非常适合进行流水线设计。通过引入流水线可以进一步提高数据吞吐率。因此Wallace Tree乘法器不仅在组合逻辑延迟方面具有优势在高性能数字电路设计中也具有很高的应用价值。关于带流水线的Wallace Tree乘法器可见下面的文章。数字IC前端学习笔记数字乘法器的优化设计带流水线的Wallace Tree乘法器https://chenzhang.blog.csdn.net/article/details/138902353