Improvements in simplemap api, added $ne $nex $eq $eqx support
authorClifford Wolf <clifford@clifford.at>
Wed, 24 Dec 2014 09:49:24 +0000 (10:49 +0100)
committerClifford Wolf <clifford@clifford.at>
Wed, 24 Dec 2014 09:49:24 +0000 (10:49 +0100)
passes/techmap/simplemap.cc
passes/techmap/simplemap.h [new file with mode: 0644]
passes/techmap/techmap.cc
techlibs/common/techmap.v

index c1c0f76a8c7794283be087f6457b47110712f490..694ebf226fb8fd9d73510dae9873aa06b296da10 100644 (file)
  *
  */
 
-#include "kernel/register.h"
+#include "simplemap.h"
 #include "kernel/sigtools.h"
-#include "kernel/log.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
 USING_YOSYS_NAMESPACE
-PRIVATE_NAMESPACE_BEGIN
+YOSYS_NAMESPACE_BEGIN
 
-static void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        RTLIL::SigSpec sig_a = cell->getPort("\\A");
        RTLIL::SigSpec sig_y = cell->getPort("\\Y");
@@ -41,7 +40,7 @@ static void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell)
        }
 }
 
-static void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        RTLIL::SigSpec sig_a = cell->getPort("\\A");
        RTLIL::SigSpec sig_y = cell->getPort("\\Y");
@@ -51,7 +50,7 @@ static void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell)
        module->connect(RTLIL::SigSig(sig_y, sig_a));
 }
 
-static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        RTLIL::SigSpec sig_a = cell->getPort("\\A");
        RTLIL::SigSpec sig_b = cell->getPort("\\B");
@@ -88,7 +87,7 @@ static void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
        }
 }
 
-static void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        RTLIL::SigSpec sig_a = cell->getPort("\\A");
        RTLIL::SigSpec sig_y = cell->getPort("\\Y");
@@ -183,7 +182,7 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig)
                sig = RTLIL::SigSpec(0, 1);
 }
 
-static void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        RTLIL::SigSpec sig_a = cell->getPort("\\A");
        logic_reduce(module, sig_a);
@@ -203,7 +202,7 @@ static void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
        gate->setPort("\\Y", sig_y);
 }
 
-static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        RTLIL::SigSpec sig_a = cell->getPort("\\A");
        logic_reduce(module, sig_a);
@@ -232,7 +231,31 @@ static void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
        gate->setPort("\\Y", sig_y);
 }
 
-static void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell)
+{
+       RTLIL::SigSpec sig_a = cell->getPort("\\A");
+       RTLIL::SigSpec sig_b = cell->getPort("\\B");
+       RTLIL::SigSpec sig_y = cell->getPort("\\Y");
+       bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool();
+       bool is_ne = cell->type == "$ne" || cell->type == "$nex";
+
+       RTLIL::SigSpec xor_out = module->addWire(NEW_ID, std::max(GetSize(sig_a), GetSize(sig_b)));
+       RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed);
+
+       RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID);
+       RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID, xor_out, reduce_out);
+
+       if (!is_ne)
+               module->addNotGate(NEW_ID, reduce_out, sig_y);
+
+       simplemap_bitop(module, xor_cell);
+       module->remove(xor_cell);
+
+       simplemap_reduce(module, reduce_cell);
+       module->remove(reduce_cell);
+}
+
+void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        RTLIL::SigSpec sig_a = cell->getPort("\\A");
        RTLIL::SigSpec sig_b = cell->getPort("\\B");
@@ -247,7 +270,7 @@ static void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
        }
 }
 
-static void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        int offset = cell->parameters.at("\\OFFSET").as_int();
        RTLIL::SigSpec sig_a = cell->getPort("\\A");
@@ -255,7 +278,7 @@ static void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell)
        module->connect(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size())));
 }
 
-static void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        RTLIL::SigSpec sig_ab = cell->getPort("\\A");
        sig_ab.append(cell->getPort("\\B"));
@@ -263,7 +286,7 @@ static void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell)
        module->connect(RTLIL::SigSig(sig_y, sig_ab));
 }
 
-static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        int width = cell->parameters.at("\\WIDTH").as_int();
        char set_pol = cell->parameters.at("\\SET_POLARITY").as_bool() ? 'P' : 'N';
@@ -283,7 +306,7 @@ static void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell)
        }
 }
 
-static void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        int width = cell->parameters.at("\\WIDTH").as_int();
        char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N';
@@ -302,7 +325,7 @@ static void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell)
        }
 }
 
-static void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        int width = cell->parameters.at("\\WIDTH").as_int();
        char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N';
@@ -324,7 +347,7 @@ static void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell)
        }
 }
 
-static void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        int width = cell->parameters.at("\\WIDTH").as_int();
        char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N';
@@ -349,7 +372,7 @@ static void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell)
        }
 }
 
-static void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        int width = cell->parameters.at("\\WIDTH").as_int();
        char clk_pol = cell->parameters.at("\\CLK_POLARITY").as_bool() ? 'P' : 'N';
@@ -376,7 +399,7 @@ static void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell)
        }
 }
 
-static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell)
+void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell)
 {
        int width = cell->parameters.at("\\WIDTH").as_int();
        char en_pol = cell->parameters.at("\\EN_POLARITY").as_bool() ? 'P' : 'N';
@@ -395,11 +418,6 @@ static void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell)
        }
 }
 
-PRIVATE_NAMESPACE_END
-YOSYS_NAMESPACE_BEGIN
-
-extern void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers);
-
 void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers)
 {
        mappers["$not"]         = simplemap_not;
@@ -416,6 +434,10 @@ void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTL
        mappers["$logic_not"]   = simplemap_lognot;
        mappers["$logic_and"]   = simplemap_logbin;
        mappers["$logic_or"]    = simplemap_logbin;
+       mappers["$eq"]          = simplemap_eqne;
+       mappers["$eqx"]         = simplemap_eqne;
+       mappers["$ne"]          = simplemap_eqne;
+       mappers["$nex"]         = simplemap_eqne;
        mappers["$mux"]         = simplemap_mux;
        mappers["$slice"]       = simplemap_slice;
        mappers["$concat"]      = simplemap_concat;
@@ -427,6 +449,19 @@ void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTL
        mappers["$dlatch"]      = simplemap_dlatch;
 }
 
+void simplemap(RTLIL::Module *module, RTLIL::Cell *cell)
+{
+       static std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> mappers;
+       static bool initialized_mappers = false;
+
+       if (!initialized_mappers) {
+               simplemap_get_mappers(mappers);
+               initialized_mappers = true;
+       }
+
+       mappers.at(cell->type)(module, cell);
+}
+
 YOSYS_NAMESPACE_END
 PRIVATE_NAMESPACE_BEGIN
 
diff --git a/passes/techmap/simplemap.h b/passes/techmap/simplemap.h
new file mode 100644 (file)
index 0000000..dc2a395
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
+ *  
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *  
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef SIMPLEMAP_H
+#define SIMPLEMAP_H
+
+#include "kernel/yosys.h"
+
+YOSYS_NAMESPACE_BEGIN
+
+extern void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell);
+extern void simplemap(RTLIL::Module *module, RTLIL::Cell *cell);
+
+extern void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers);
+
+YOSYS_NAMESPACE_END
+
+#endif
index e109c5b58fd1f7bdac42dd52a2f3dfad6a38320d..04d345d31c016bb5b2ddac02e0ee874cecb1367c 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
+#include "simplemap.h"
 #include "passes/techmap/techmap.inc"
 
 YOSYS_NAMESPACE_BEGIN
 
-// see simplemap.cc
-extern void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers);
-
 // see maccmap.cc
 extern void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap = false);
 
index 7b5528560d810dd030ae2aa4013cf10fda812c58..e0ecf0c480e6cfc0c7fd4fb5db0a82e2c938f2e1 100644 (file)
@@ -53,6 +53,11 @@ endmodule
 module _90_simplemap_logic_ops;
 endmodule
 
+(* techmap_simplemap *)
+(* techmap_celltype = "$eq $eqx $ne $nex" *)
+module _90_simplemap_compare_ops;
+endmodule
+
 (* techmap_simplemap *)
 (* techmap_celltype = "$pos $slice $concat $mux" *)
 module _90_simplemap_various;
@@ -406,55 +411,6 @@ module _90_pow (A, B, Y);
 endmodule
 
 
-// --------------------------------------------------------
-// Equal and Not-Equal
-// --------------------------------------------------------
-
-(* techmap_celltype = "$eq $eqx" *)
-module _90_eq_eqx (A, B, Y);
-       parameter A_SIGNED = 0;
-       parameter B_SIGNED = 0;
-       parameter A_WIDTH = 1;
-       parameter B_WIDTH = 1;
-       parameter Y_WIDTH = 1;
-
-       localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH;
-
-       input [A_WIDTH-1:0] A;
-       input [B_WIDTH-1:0] B;
-       output [Y_WIDTH-1:0] Y;
-
-       wire carry, carry_sign;
-       wire [WIDTH-1:0] A_buf, B_buf;
-       \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf));
-       \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf));
-
-       assign Y = ~|(A_buf ^ B_buf);
-endmodule
-
-(* techmap_celltype = "$ne $nex" *)
-module _90_ne_nex (A, B, Y);
-       parameter A_SIGNED = 0;
-       parameter B_SIGNED = 0;
-       parameter A_WIDTH = 1;
-       parameter B_WIDTH = 1;
-       parameter Y_WIDTH = 1;
-
-       localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH;
-
-       input [A_WIDTH-1:0] A;
-       input [B_WIDTH-1:0] B;
-       output [Y_WIDTH-1:0] Y;
-
-       wire carry, carry_sign;
-       wire [WIDTH-1:0] A_buf, B_buf;
-       \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(WIDTH)) A_conv (.A(A), .Y(A_buf));
-       \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(WIDTH)) B_conv (.A(B), .Y(B_buf));
-
-       assign Y = |(A_buf ^ B_buf);
-endmodule
-
-
 // --------------------------------------------------------
 // Parallel Multiplexers
 // --------------------------------------------------------