Added $alu cell type
authorClifford Wolf <clifford@clifford.at>
Sat, 30 Aug 2014 16:59:05 +0000 (18:59 +0200)
committerClifford Wolf <clifford@clifford.at>
Sat, 30 Aug 2014 16:59:05 +0000 (18:59 +0200)
kernel/celltypes.h
kernel/rtlil.cc
manual/CHAPTER_CellLib.tex
techlibs/common/simlib.v
techlibs/common/techmap.v

index 515da25ce2e11121b8f65c8f3a15e475b99c210a..c1bb1d036e659f568a8a7615a1eb1588c7d153f8 100644 (file)
@@ -108,6 +108,8 @@ struct CellTypes
                for (auto type : std::vector<RTLIL::IdString>({"$mux", "$pmux"}))
                        setup_type(type, {"\\A", "\\B", "\\S"}, {"\\Y"}, true);
 
+               setup_type("$alu", {"\\A", "\\B", "\\CI", "\\BI"}, {"\\X", "\\Y", "\\CO"}, true);
+
                setup_type("$assert", {"\\A", "\\EN"}, std::set<RTLIL::IdString>(), true);
        }
 
index 7ba6911a2b95b5021b416ebccbc1388d9b24ccb6..96b651d89c28dfc2af5a02a689db570d90fea571 100644 (file)
@@ -557,6 +557,20 @@ namespace {
                                return;
                        }
 
+                       if (cell->type == "$alu") {
+                               param_bool("\\A_SIGNED");
+                               param_bool("\\B_SIGNED");
+                               port("\\A", param("\\A_WIDTH"));
+                               port("\\B", param("\\B_WIDTH"));
+                               port("\\CI", 1);
+                               port("\\BI", 1);
+                               port("\\X", param("\\Y_WIDTH"));
+                               port("\\Y", param("\\Y_WIDTH"));
+                               port("\\CO", param("\\Y_WIDTH"));
+                               check_expected();
+                               return;
+                       }
+
                        if (cell->type == "$logic_not") {
                                param_bool("\\A_SIGNED");
                                port("\\A", param("\\A_WIDTH"));
index 3eb2f9469c9d725d4255b4a6c8f3a93559388230..82473f6a2ff539f425bd1c758b23c3668b587013 100644 (file)
@@ -430,6 +430,10 @@ Add information about {\tt \$assert} cells.
 Add information about {\tt \$slice} and {\tt \$concat} cells.
 \end{fixme}
 
+\begin{fixme}
+Add information about {\tt \$alu} cells.
+\end{fixme}
+
 \begin{fixme}
 Add information about {\tt \$\_NAND\_}, {\tt \$\_NOR\_}, {\tt \$\_XNOR\_}, {\tt \$\_AOI3\_}, {\tt \$\_OAI3\_}, {\tt \$\_AOI4\_}, and {\tt \$\_OAI4\_} cells.
 \end{fixme}
index 8c0a54e4e6d64eea10f783730605f184d05c44ff..09ffa9a688517285b47acc2cd7407e88bafc9c7c 100644 (file)
@@ -467,6 +467,51 @@ endmodule
 
 // --------------------------------------------------------
 
+module \$alu (A, B, CI, BI, X, Y, CO);
+
+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] X, Y;
+
+input CI, BI;
+output [Y_WIDTH-1:0] CO;
+
+wire [Y_WIDTH-1:0] AA, BB;
+
+generate
+       if (A_SIGNED && B_SIGNED) begin:BLOCK1
+               assign AA = $signed(A), BB = BI ? ~$signed(B) : $signed(B);
+       end else begin:BLOCK2
+               assign AA = $unsigned(A), BB = BI ? ~$unsigned(B) : $unsigned(B);
+       end
+endgenerate
+
+assign X = AA ^ BB;
+assign Y = AA + BB + CI;
+
+function get_carry;
+       input a, b, c;
+       get_carry = (a&b) | (a&c) | (b&c);
+endfunction
+
+genvar i;
+generate
+       assign CO[0] = get_carry(AA[0], BB[0], CI);
+       for (i = 1; i < Y_WIDTH; i = i+1) begin:BLOCK3
+               assign CO[i] = get_carry(AA[i], BB[i], CO[i-1]);
+       end
+endgenerate
+
+endmodule
+
+// --------------------------------------------------------
+
 module \$lt (A, B, Y);
 
 parameter A_SIGNED = 0;
index 452b64b8f7bd9297d4777c861b8e1443c978ad7a..d6b24945694280fa1c8dafb3f87b41b80276ae47 100644 (file)
@@ -359,7 +359,7 @@ module \$__alu_lookahead (A, B, CI, X, Y, CO);
        assign carry = {CO, CI};
 endmodule
 
-module \$__alu (A, B, CI, BI, X, Y, CO);
+module \$alu (A, B, CI, BI, X, Y, CO);
        parameter A_SIGNED = 0;
        parameter B_SIGNED = 0;
        parameter A_WIDTH = 1;
@@ -370,7 +370,6 @@ module \$__alu (A, B, CI, BI, X, Y, CO);
        input [B_WIDTH-1:0] B;
        output [Y_WIDTH-1:0] X, Y;
 
-       // carry in, sub, carry out, carry sign
        input CI, BI;
        output [Y_WIDTH-1:0] CO;
 
@@ -410,7 +409,7 @@ endmodule
        wire [WIDTH-1:0] alu_x, alu_y, alu_co;
        wire [WIDTH:0] carry = {alu_co, |_sub};
 
-       \$__alu #(
+       \$alu #(
                .A_SIGNED(A_SIGNED),
                .B_SIGNED(B_SIGNED),
                .A_WIDTH(A_WIDTH),