Using maccmap for $macc and $mul techmap
authorClifford Wolf <clifford@clifford.at>
Sun, 7 Sep 2014 16:24:08 +0000 (18:24 +0200)
committerClifford Wolf <clifford@clifford.at>
Sun, 7 Sep 2014 16:24:08 +0000 (18:24 +0200)
techlibs/common/techmap.v

index 3fc6ccb8e6355b223461e88ea44223630dac665d..dc52ca5fa4240c84df4f409bc4624b1ea7e6ae49 100644 (file)
@@ -455,102 +455,8 @@ endmodule
 // Multiply
 // --------------------------------------------------------
 
-module \$__acc_set (acc_new, value);
-       parameter WIDTH = 1;
-       output reg [2*WIDTH-1:0] acc_new;
-       input [WIDTH-1:0] value;
-
-       wire [1023:0] _TECHMAP_DO_ = "proc;;;";
-
-       integer k;
-       always @* begin
-               for (k = 0; k < WIDTH; k = k+1) begin
-                       acc_new[2*k +: 2] = value[k];
-               end
-       end
-endmodule
-
-module \$__acc_add (acc_new, acc_old, value);
-       parameter WIDTH = 1;
-       output reg [2*WIDTH-1:0] acc_new;
-       input [2*WIDTH-1:0] acc_old;
-       input [WIDTH-1:0] value;
-
-       wire [1023:0] _TECHMAP_DO_ = "proc; simplemap; opt -purge";
-
-       integer k;
-       reg a, b, c;
-
-       always @* begin
-               for (k = 0; k < WIDTH; k = k+1) begin
-                       a = acc_old[2*k];
-                       b = k ? acc_old[2*k-1] : 1'b0;
-                       c = value[k];
-                       acc_new[2*k] = (a ^ b) ^ c;
-                       acc_new[2*k+1] = (a & b) | ((a ^ b) & c);
-               end
-       end
-endmodule
-
-module \$__acc_get (value, acc);
-       parameter WIDTH = 1;
-       output reg [WIDTH-1:0] value;
-       input [2*WIDTH-1:0] acc;
-
-       wire [1023:0] _TECHMAP_DO_ = "proc;;;";
-
-       integer k;
-
-       always @* begin
-               // at the end of the multiplier chain the carry-save accumulator
-               // should also have propagated all carries. thus we just need to
-               // copy the even bits from the carry accumulator to the output.
-               for (k = 0; k < WIDTH; k = k+1) begin
-                       value[k] = acc[2*k];
-               end
-       end
-endmodule
-
-module \$__acc_mul (A, B, Y);
-       parameter WIDTH = 1;
-       input [WIDTH-1:0] A, B;
-       output [WIDTH-1:0] Y;
-
-       wire [1023:0] _TECHMAP_DO_ = "proc;;";
-
-       integer i;
-       reg [WIDTH-1:0] x;
-       reg [2*WIDTH-1:0] y;
-
-       (* via_celltype = "\\$__acc_set acc_new" *)
-       (* via_celltype_defparam_WIDTH = WIDTH *)
-       function [2*WIDTH-1:0] acc_set;
-               input [WIDTH-1:0] value;
-       endfunction
-
-       (* via_celltype = "\\$__acc_add acc_new" *)
-       (* via_celltype_defparam_WIDTH = WIDTH *)
-       function [2*WIDTH-1:0] acc_add;
-               input [2*WIDTH-1:0] acc_old;
-               input [WIDTH-1:0] value;
-       endfunction
-
-       (* via_celltype = "\\$__acc_get value" *)
-       (* via_celltype_defparam_WIDTH = WIDTH *)
-       function [WIDTH-1:0] acc_get;
-               input [2*WIDTH-1:0] acc;
-       endfunction
-
-       always @* begin
-               x = B;
-               y = acc_set(A[0] ? x : 1'b0);
-               for (i = 1; i < WIDTH; i = i+1) begin
-                       x = {x[WIDTH-2:0], 1'b0};
-                       y = acc_add(y, A[i] ? x : 1'b0);
-               end
-       end
-
-       assign Y = acc_get(y);
+(* techmap_maccmap *)
+module \$macc ;
 endmodule
 
 module \$mul (A, B, Y);
@@ -566,105 +472,25 @@ module \$mul (A, B, Y);
 
        wire [1023:0] _TECHMAP_DO_ = "RECURSION; CONSTMAP; opt -purge";
 
-       wire [Y_WIDTH-1:0] A_buf, B_buf;
-       \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
-       \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
-
-       \$__acc_mul #(
-               .WIDTH(Y_WIDTH)
+       localparam [ 3:0] CONFIG_WIDTH_BITS = 15;
+       localparam [ 0:0] CONFIG_IS_SIGNED = A_SIGNED && B_SIGNED;
+       localparam [ 0:0] CONFIG_DO_SUBTRACT = 0;
+       localparam [14:0] CONFIG_A_WIDTH = A_WIDTH;
+       localparam [14:0] CONFIG_B_WIDTH = B_WIDTH;
+
+       \$macc #(
+               .CONFIG({CONFIG_B_WIDTH, CONFIG_A_WIDTH, CONFIG_DO_SUBTRACT, CONFIG_IS_SIGNED, CONFIG_WIDTH_BITS}),
+               .CONFIG_WIDTH(15 + 15 + 2 + 4),
+               .A_WIDTH(B_WIDTH + A_WIDTH),
+               .B_WIDTH(0),
+               .Y_WIDTH(Y_WIDTH)
        ) _TECHMAP_REPLACE_ (
-               .A(A_buf),
-               .B(B_buf),
+               .A({B, A}),
+               .B(),
                .Y(Y)
        );
 endmodule
 
-module \$macc (A, B, Y);
-       parameter A_WIDTH = 0;
-       parameter B_WIDTH = 0;
-       parameter Y_WIDTH = 0;
-       parameter CONFIG = 4'b0000;
-       parameter CONFIG_WIDTH = 4;
-
-       input [A_WIDTH-1:0] A;
-       input [B_WIDTH-1:0] B;
-       output reg [Y_WIDTH-1:0] Y;
-
-       wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast";
-
-       localparam integer num_bits = CONFIG[3:0];
-       localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits);
-       localparam integer num_abits = $clog2(A_WIDTH) > 0 ? $clog2(A_WIDTH) : 1;
-
-       function [2*num_ports*num_abits-1:0] get_port_offsets;
-               input [CONFIG_WIDTH-1:0] cfg;
-               integer i, cursor;
-               begin
-                       cursor = 0;
-                       get_port_offsets = 0;
-                       for (i = 0; i < num_ports; i = i+1) begin
-                               get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor;
-                               cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 +: num_bits];
-                               get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor;
-                               cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits];
-                       end
-               end
-       endfunction
-
-       localparam [2*num_ports*num_abits-1:0] port_offsets = get_port_offsets(CONFIG);
-
-       `define PORT_IS_SIGNED   (0 + CONFIG[4 + i*(2 + 2*num_bits)])
-       `define PORT_DO_SUBTRACT (0 + CONFIG[4 + i*(2 + 2*num_bits) + 1])
-       `define PORT_SIZE_A      (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits])
-       `define PORT_SIZE_B      (0 + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits])
-       `define PORT_OFFSET_A    (0 + port_offsets[2*i*num_abits +: num_abits])
-       `define PORT_OFFSET_B    (0 + port_offsets[2*i*num_abits + num_abits +: num_abits])
-
-       integer i, j;
-       reg [Y_WIDTH-1:0] tmp_a, tmp_b;
-
-       always @* begin
-               Y = 0;
-               for (i = 0; i < num_ports; i = i+1)
-               begin
-                       tmp_a = 0;
-                       tmp_b = 0;
-
-                       for (j = 0; j < `PORT_SIZE_A; j = j+1)
-                               tmp_a[j] = A[`PORT_OFFSET_A + j];
-
-                       if (`PORT_IS_SIGNED && `PORT_SIZE_A > 0)
-                               for (j = `PORT_SIZE_A; j < Y_WIDTH; j = j+1)
-                                       tmp_a[j] = tmp_a[`PORT_SIZE_A-1];
-
-                       for (j = 0; j < `PORT_SIZE_B; j = j+1)
-                               tmp_b[j] = A[`PORT_OFFSET_B + j];
-
-                       if (`PORT_IS_SIGNED && `PORT_SIZE_B > 0)
-                               for (j = `PORT_SIZE_B; j < Y_WIDTH; j = j+1)
-                                       tmp_b[j] = tmp_b[`PORT_SIZE_B-1];
-
-                       if (`PORT_SIZE_B > 0)
-                               tmp_a = tmp_a * tmp_b;
-
-                       if (`PORT_DO_SUBTRACT)
-                               Y = Y - tmp_a;
-                       else
-                               Y = Y + tmp_a;
-               end
-               for (i = 0; i < B_WIDTH; i = i+1) begin
-                       Y = Y + B[i];
-               end
-       end
-
-       `undef PORT_IS_SIGNED
-       `undef PORT_DO_SUBTRACT
-       `undef PORT_SIZE_A
-       `undef PORT_SIZE_B
-       `undef PORT_OFFSET_A
-       `undef PORT_OFFSET_B
-endmodule
-
 
 // --------------------------------------------------------
 // Divide and Modulo