--- /dev/null
+
+(* techmap_celltype = "$mul" *)
+module mul_swap_ports (A, B, Y);
+
+parameter A_SIGNED = 0;
+parameter B_SIGNED = 0;
+parameter A_WIDTH = 1;
+parameter B_WIDTH = 1;
+parameter Y_WIDTH = 1;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+output [Y_WIDTH-1:0] Y;
+
+wire _TECHMAP_FAIL_ = A_WIDTH >= B_WIDTH;
+
+\$mul #(
+ .A_SIGNED(B_SIGNED),
+ .B_SIGNED(A_SIGNED),
+ .A_WIDTH(B_WIDTH),
+ .B_WIDTH(A_WIDTH),
+ .Y_WIDTH(Y_WIDTH)
+) _TECHMAP_REPLACE_ (
+ .A(B),
+ .B(A),
+ .Y(Y)
+);
+
+endmodule
+
--- /dev/null
+module test(a, b, c, d, e, f, y);
+input [19:0] a, b, c;
+input [15:0] d, e, f;
+output [41:0] y;
+assign y = a*b + c*d + e*f;
+endmodule
--- /dev/null
+read_verilog macc_xilinx_test.v
+read_verilog -lib -icells macc_xilinx_unwrap_map.v
+hierarchy -check -top test;;
+
+show -prefix macc_xilinx_test_a -format pdf -notitle
+
+techmap -map macc_xilinx_swap_map.v;;
+
+show -prefix macc_xilinx_test_b -format pdf -notitle
+
+techmap -map macc_xilinx_wrap_map.v
+
+connwrappers -unsigned $__mul_wrapper Y Y_WIDTH \
+ -unsigned $__add_wrapper Y Y_WIDTH;;
+
+show -prefix macc_xilinx_test_c -format pdf -notitle
+
--- /dev/null
+
+module \$__mul_wrapper (A, B, Y);
+
+parameter A_SIGNED = 0;
+parameter B_SIGNED = 0;
+parameter A_WIDTH = 1;
+parameter B_WIDTH = 1;
+parameter Y_WIDTH = 1;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+output [Y_WIDTH-1:0] Y;
+
+wire [A_WIDTH-1:0] A_ORIG = A;
+wire [B_WIDTH-1:0] B_ORIG = B;
+wire [Y_WIDTH-1:0] Y_ORIG;
+assign Y = Y_ORIG;
+
+\$mul #(
+ .A_SIGNED(A_SIGNED),
+ .B_SIGNED(B_SIGNED),
+ .A_WIDTH(A_WIDTH),
+ .B_WIDTH(B_WIDTH),
+ .Y_WIDTH(Y_WIDTH)
+) _TECHMAP_REPLACE_ (
+ .A(A_ORIG),
+ .B(B_ORIG),
+ .Y(Y_ORIG)
+);
+
+endmodule
+
+module \$__add_wrapper (A, B, Y);
+
+parameter A_SIGNED = 0;
+parameter B_SIGNED = 0;
+parameter A_WIDTH = 1;
+parameter B_WIDTH = 1;
+parameter Y_WIDTH = 1;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+output [Y_WIDTH-1:0] Y;
+
+wire [A_WIDTH-1:0] A_ORIG = A;
+wire [B_WIDTH-1:0] B_ORIG = B;
+wire [Y_WIDTH-1:0] Y_ORIG;
+assign Y = Y_ORIG;
+
+\$add #(
+ .A_SIGNED(A_SIGNED),
+ .B_SIGNED(B_SIGNED),
+ .A_WIDTH(A_WIDTH),
+ .B_WIDTH(B_WIDTH),
+ .Y_WIDTH(Y_WIDTH)
+) _TECHMAP_REPLACE_ (
+ .A(A_ORIG),
+ .B(B_ORIG),
+ .Y(Y_ORIG)
+);
+
+endmodule
+
--- /dev/null
+
+(* techmap_celltype = "$mul" *)
+module mul_wrap (A, B, Y);
+
+parameter A_SIGNED = 0;
+parameter B_SIGNED = 0;
+parameter A_WIDTH = 1;
+parameter B_WIDTH = 1;
+parameter Y_WIDTH = 1;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+output [Y_WIDTH-1:0] Y;
+
+wire [24:0] A_25 = A;
+wire [17:0] B_18 = B;
+wire [47:0] Y_48;
+assign Y = Y_48;
+
+wire [1023:0] _TECHMAP_DO_ = "proc; clean";
+
+reg _TECHMAP_FAIL_;
+initial begin
+ _TECHMAP_FAIL_ <= 0;
+ if (A_SIGNED || B_SIGNED)
+ _TECHMAP_FAIL_ <= 1;
+ if (A_WIDTH < 4 || B_WIDTH < 4)
+ _TECHMAP_FAIL_ <= 1;
+ if (A_WIDTH > 25 || B_WIDTH > 18)
+ _TECHMAP_FAIL_ <= 1;
+ if (A_WIDTH*B_WIDTH < 100)
+ _TECHMAP_FAIL_ <= 1;
+end
+
+\$__mul_wrapper #(
+ .A_SIGNED(A_SIGNED),
+ .B_SIGNED(B_SIGNED),
+ .A_WIDTH(A_WIDTH),
+ .B_WIDTH(B_WIDTH),
+ .Y_WIDTH(Y_WIDTH)
+) _TECHMAP_REPLACE_ (
+ .A(A_25),
+ .B(B_18),
+ .Y(Y_48)
+);
+
+endmodule
+
+(* techmap_celltype = "$add" *)
+module add_wrap (A, B, Y);
+
+parameter A_SIGNED = 0;
+parameter B_SIGNED = 0;
+parameter A_WIDTH = 1;
+parameter B_WIDTH = 1;
+parameter Y_WIDTH = 1;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+output [Y_WIDTH-1:0] Y;
+
+wire [47:0] A_48 = A;
+wire [47:0] B_48 = B;
+wire [47:0] Y_48;
+assign Y = Y_48;
+
+wire [1023:0] _TECHMAP_DO_ = "proc; clean";
+
+reg _TECHMAP_FAIL_;
+initial begin
+ _TECHMAP_FAIL_ <= 0;
+ if (A_SIGNED || B_SIGNED)
+ _TECHMAP_FAIL_ <= 1;
+ if (A_WIDTH < 10 && B_WIDTH < 10)
+ _TECHMAP_FAIL_ <= 1;
+end
+
+\$__add_wrapper #(
+ .A_SIGNED(A_SIGNED),
+ .B_SIGNED(B_SIGNED),
+ .A_WIDTH(A_WIDTH),
+ .B_WIDTH(B_WIDTH),
+ .Y_WIDTH(Y_WIDTH)
+) _TECHMAP_REPLACE_ (
+ .A(A_48),
+ .B(B_48),
+ .Y(Y_48)
+);
+
+endmodule
+