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: 24cbc324967a^
Choose a base ref
...
head repository: azonenberg/yosys
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: cc82845dedb0
Choose a head ref
  • 10 commits
  • 6 files changed
  • 1 contributor

Commits on Aug 14, 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 authored and azonenberg committed Aug 14, 2017
    Copy the full SHA
    24cbc32 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 authored and azonenberg committed Aug 14, 2017
    Copy the full SHA
    abae7f6 View commit details
  3. Copy the full SHA
    4641f1f View commit details
  4. Copy the full SHA
    72c613f View commit details
  5. Copy the full SHA
    66a13ae View commit details
  6. Copy the full SHA
    addb739 View commit details
  7. Copy the full SHA
    dff76f6 View commit details
  8. Copy the full SHA
    ec2d6e5 View commit details
  9. recover_adder: Replace XOR3 and MAJ gates with structural Verilog

    This way, they generate the uppercase cells rather than the lowercase
    cells, and it is possible to directly run abc afterwards. Before this
    change, it would be necessary to run simplemap first, which might
    destroy some other cells that have been recovered.
    ArcaneNibble authored and azonenberg committed Aug 14, 2017
    Copy the full SHA
    eb5a0e4 View commit details
  10. Copy the full SHA
    cc82845 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
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
53 changes: 53 additions & 0 deletions passes/techmap/adder_untechmap_gates.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
module __XOR3_ (input A, input B, input C, output Y);
wire intermed;

$_XOR_ xorgate1(
.A(A),
.B(B),
.Y(intermed),
);

$_XOR_ xorgate2(
.A(intermed),
.B(C),
.Y(Y),
);
endmodule

module __MAJ_ (input A, input B, input C, output Y);
wire intermed1;
wire intermed2;
wire intermed3;

wire intermed4;

$_AND_ andgate1(
.A(A),
.B(B),
.Y(intermed1),
);

$_AND_ andgate2(
.A(A),
.B(C),
.Y(intermed2),
);

$_AND_ andgate3(
.A(B),
.B(C),
.Y(intermed3),
);

$_OR_ orgate1(
.A(intermed1),
.B(intermed2),
.Y(intermed4),
);

$_OR_ orgate2(
.A(intermed4),
.B(intermed3),
.Y(Y),
);
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