From 4724d94fbce587b39cd7343dc8de3b859311f55c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 30 Aug 2014 18:59:05 +0200 Subject: [PATCH] Added $alu cell type --- kernel/celltypes.h | 2 ++ kernel/rtlil.cc | 14 ++++++++++++ manual/CHAPTER_CellLib.tex | 4 ++++ techlibs/common/simlib.v | 45 ++++++++++++++++++++++++++++++++++++++ techlibs/common/techmap.v | 5 ++--- 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 515da25ce..c1bb1d036 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -108,6 +108,8 @@ struct CellTypes for (auto type : std::vector({"$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(), true); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7ba6911a2..96b651d89 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -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")); diff --git a/manual/CHAPTER_CellLib.tex b/manual/CHAPTER_CellLib.tex index 3eb2f9469..82473f6a2 100644 --- a/manual/CHAPTER_CellLib.tex +++ b/manual/CHAPTER_CellLib.tex @@ -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} diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 8c0a54e4e..09ffa9a68 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -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; diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 452b64b8f..d6b249456 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -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), -- 2.30.2