From 4aa9fbbf3fe095220895dd2508ac6118b7382493 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 24 Dec 2014 10:49:24 +0100 Subject: [PATCH] Improvements in simplemap api, added $ne $nex $eq $eqx support --- passes/techmap/simplemap.cc | 81 ++++++++++++++++++++++++++----------- passes/techmap/simplemap.h | 48 ++++++++++++++++++++++ passes/techmap/techmap.cc | 4 +- techlibs/common/techmap.v | 54 +++---------------------- 4 files changed, 112 insertions(+), 75 deletions(-) create mode 100644 passes/techmap/simplemap.h diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index c1c0f76a8..694ebf226 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -17,17 +17,16 @@ * */ -#include "kernel/register.h" +#include "simplemap.h" #include "kernel/sigtools.h" -#include "kernel/log.h" #include #include #include 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 &mappers); - void simplemap_get_mappers(std::map &mappers) { mappers["$not"] = simplemap_not; @@ -416,6 +434,10 @@ void simplemap_get_mappers(std::map 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 index 000000000..dc2a395d3 --- /dev/null +++ b/passes/techmap/simplemap.h @@ -0,0 +1,48 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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 &mappers); + +YOSYS_NAMESPACE_END + +#endif diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index e109c5b58..04d345d31 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -26,13 +26,11 @@ #include #include +#include "simplemap.h" #include "passes/techmap/techmap.inc" YOSYS_NAMESPACE_BEGIN -// see simplemap.cc -extern void simplemap_get_mappers(std::map &mappers); - // see maccmap.cc extern void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap = false); diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 7b5528560..e0ecf0c48 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -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 // -------------------------------------------------------- -- 2.30.2