Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: azonenberg/yosys
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: bc9380be32e0
Choose a base ref
...
head repository: azonenberg/yosys
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8a5ce48b1468
Choose a head ref
  • 9 commits
  • 7 files changed
  • 1 contributor

Commits on Aug 10, 2017

  1. recover_adder_core: Initial commit

    The code seems to correctly traverse adder chains and terminates
    correctly. The code to add $add/$sub/$alu has not yet been written.
    ArcaneNibble committed Aug 10, 2017
    Copy the full SHA
    93dc009 View commit details
  2. recover_adder_core: Generate $add/$sub in the simple case

    $add can be generated as long as there is no carry-in or fanouts on the
    carry signals. $sub currently is only implemented if there is neither a
    carry-in nor a carry-out.
    ArcaneNibble committed Aug 10, 2017
    Copy the full SHA
    1afc71f View commit details

Commits on Aug 11, 2017

  1. Copy the full SHA
    1e36e59 View commit details
  2. Copy the full SHA
    2a4380a View commit details
  3. Copy the full SHA
    36165c9 View commit details
  4. Copy the full SHA
    a869d58 View commit details
  5. Copy the full SHA
    be50b96 View commit details
  6. Copy the full SHA
    0a1ac88 View commit details
  7. Copy the full SHA
    8a5ce48 View commit details
5 changes: 5 additions & 0 deletions passes/techmap/Makefile.inc
Original file line number Diff line number Diff line change
@@ -16,6 +16,11 @@ ifneq ($(SMALL),1)
OBJS += passes/techmap/iopadmap.o
OBJS += passes/techmap/hilomap.o
OBJS += passes/techmap/extract.o
OBJS += passes/techmap/recover_adder.o
$(eval $(call add_share_file,share/untechmap,passes/techmap/adder_untechmap.lib))
$(eval $(call add_share_file,share/untechmap,passes/techmap/adder_untechmap.v))
$(eval $(call add_share_file,share/untechmap,passes/techmap/adder_untechmap_gates.v))
OBJS += passes/techmap/recover_adder_core.o
OBJS += passes/techmap/alumacc.o
OBJS += passes/techmap/dff2dffe.o
OBJS += passes/techmap/dffinit.o
3 changes: 3 additions & 0 deletions passes/techmap/abc.cc
Original file line number Diff line number Diff line change
@@ -1431,17 +1431,20 @@ struct AbcPass : public Pass {
}
if (arg == "-script" && argidx+1 < args.size()) {
script_file = args[++argidx];
rewrite_filename(script_file);
if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+')
script_file = std::string(pwd) + "/" + script_file;
continue;
}
if (arg == "-liberty" && argidx+1 < args.size()) {
liberty_file = args[++argidx];
rewrite_filename(liberty_file);
if (!liberty_file.empty() && !is_absolute_path(liberty_file))
liberty_file = std::string(pwd) + "/" + liberty_file;
continue;
}
if (arg == "-constr" && argidx+1 < args.size()) {
rewrite_filename(constr_file);
constr_file = args[++argidx];
if (!constr_file.empty() && !is_absolute_path(constr_file))
constr_file = std::string(pwd) + "/" + constr_file;
79 changes: 79 additions & 0 deletions passes/techmap/adder_untechmap.lib
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
library(adder_unmap) {
cell($_BUF_) {
pin(A) {
direction: input;
}
pin(Y) {
direction: output;
function: "A";
}
}

cell($_NOT_) {
pin(A) {
direction: input;
}
pin(Y) {
direction: output;
function: "!A";
}
}

cell($_AND_) {
pin(A) {
direction: input;
}
pin(B) {
direction: input;
}
pin(Y) {
direction: output;
function: "(A B)";
}
}

cell($_XOR_) {
pin(A) {
direction: input;
}
pin(B) {
direction: input;
}
pin(Y) {
direction: output;
function: "(A^B)";
}
}

cell(__XOR3_) {
pin(A) {
direction: input;
}
pin(B) {
direction: input;
}
pin(C) {
direction: input;
}
pin(Y) {
direction: output;
function: "(A^B^C)";
}
}

cell(__MAJ_) {
pin(A) {
direction: input;
}
pin(B) {
direction: input;
}
pin(C) {
direction: input;
}
pin(Y) {
direction: output;
function: "((A B)+(A C)+(B C))";
}
}
}
73 changes: 73 additions & 0 deletions passes/techmap/adder_untechmap.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
module __FULL_ADDER_ (input A, input B, input Cin, output Y, output Cout);
__XOR3_ xor3 (
.A(A),
.B(B),
.C(Cin),
.Y(Y),
);

__MAJ_ maj (
.A(A),
.B(B),
.C(Cin),
.Y(Cout),
);
endmodule

module __HALF_ADDER_ (input A, input B, output Y, output Cout);
$_XOR_ xorgate (
.A(A),
.B(B),
.Y(Y),
);

$_AND_ andgate (
.A(A),
.B(B),
.Y(Cout),
);
endmodule

module __FULL_SUBTRACTOR_ (input A, input B, input Bin, output Y, output Bout);
wire nA;

$_NOT_ notgate (
.A(A),
.Y(nA),
);

__XOR3_ xor3 (
.A(A),
.B(B),
.C(Bin),
.Y(Y),
);

__MAJ_ maj (
.A(nA),
.B(B),
.C(Bin),
.Y(Bout),
);
endmodule

module __HALF_SUBTRACTOR_ (input A, input B, output Y, output Bout);
wire nA;

$_NOT_ notgate (
.A(A),
.Y(nA),
);

$_XOR_ xorgate (
.A(A),
.B(B),
.Y(Y),
);

$_AND_ andgate (
.A(nA),
.B(B),
.Y(Bout),
);
endmodule
7 changes: 7 additions & 0 deletions passes/techmap/adder_untechmap_gates.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module __XOR3_ (input A, input B, input C, output Y);
assign Y = A ^ B ^ C;
endmodule

module __MAJ_ (input A, input B, input C, output Y);
assign Y = (A & B) | (A & C) | (B & C);
endmodule
121 changes: 121 additions & 0 deletions passes/techmap/recover_adder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2017 Robert Ou <rqou@robertou.com>
*
* 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.
*
*/

// The approach used in this adder recovery pass is vaguely inspired by the paper
// "Improved Carry Chain Mapping for the VTR Flow" by Petkovska et. al. The key takeaway
// from that paper is that it is easy for ABC to find 3-input XOR gates and majority gates
// once the input circuit has been mapped to an AIG. Rather than writing a custom pass
// for ABC, this script simply tells ABC to techmap to a library containing only AND, NOT,
// XOR, and majority gates. ABC thus cannot find any other types of gates. Once the netlist
// has been transformed, it is possible to use the yosys native subcircuit extraction code
// to find half and full adders. A custom yosys pass then looks for these chains and converts
// them back into an $alu/$add/$sub cell. Finally, any combinatorial logic that is left is
// put back into ABC with the normal cell library to be re-optimized.

#include "kernel/yosys.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct RecoverAdderPass : public ScriptPass
{
RecoverAdderPass() : ScriptPass("recover_adder", "recovers $alu/$add/$sub cells from gates") {}
virtual void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" recover_adder [options]\n");
log("\n");
log("recovers $alu/$add/$sub cells from gates\n");
log("\n");
log("Reconstructs adders and subtractors given a netlist of gates. This pass is\n");
log("intended to be used as part of a circuit reverse-engineering workflow, but it\n");
log("does also work with synthesis. Note that this command will completely destroy\n");
log("the structure of combinatorial logic as it works.\n");
log("\n");
log("\n");
log("The following commands are executed by this command:\n");
help_script();
log("\n");
}

bool keep_bit_adders, keep_gates, no_final_abc;

virtual void clear_flags() YS_OVERRIDE
{
keep_bit_adders = false;
keep_gates = false;
no_final_abc = false;
}

virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
clear_flags();

size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
if (args[argidx] == "-keep_bit_adders") {
keep_bit_adders = true;
continue;
}
if (args[argidx] == "-keep_gates") {
keep_gates = true;
continue;
}
if (args[argidx] == "-no_final_abc") {
no_final_abc = true;
continue;
}
break;
}
extra_args(args, argidx, design);

log_header(design, "Executing recover_adder.\n");
log_push();

run_script(design, "", "");

log_pop();
}

virtual void script() YS_OVERRIDE
{
run("abc -liberty +/untechmap/adder_untechmap.lib");
run("extract -map +/untechmap/adder_untechmap.v -swap __XOR3_ A,B,C -swap __MAJ_ A,B,C");
run("recover_adder_core");

if (!keep_bit_adders)
run("techmap -autoproc -map +/untechmap/adder_untechmap.v");
else
run("read_verilog -lib +/untechmap/adder_untechmap.v");

if (!keep_gates)
run("techmap -autoproc -map +/untechmap/adder_untechmap_gates.v");
else
run("read_verilog -lib +/untechmap/adder_untechmap_gates.v");

if (!no_final_abc)
run("abc");

run("clean");
}
} RecoverAdderPass;

PRIVATE_NAMESPACE_END
Loading