mirror of
https://github.com/YosysHQ/yosys
synced 2026-01-08 12:01:18 +00:00
Merge 99e05506a0 into 17ca71e1ab
This commit is contained in:
commit
b9f718d47e
4 changed files with 1116 additions and 0 deletions
2
.gitattributes
vendored
2
.gitattributes
vendored
|
|
@ -1,2 +1,4 @@
|
|||
*.v linguist-language=Verilog
|
||||
/.gitcommit export-subst
|
||||
|
||||
*.ys text eol=lf
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ OBJS += passes/techmap/extract.o
|
|||
OBJS += passes/techmap/extract_fa.o
|
||||
OBJS += passes/techmap/extract_counter.o
|
||||
OBJS += passes/techmap/extract_reduce.o
|
||||
OBJS += passes/techmap/breakreduce.o
|
||||
OBJS += passes/techmap/alumacc.o
|
||||
OBJS += passes/techmap/dffinit.o
|
||||
OBJS += passes/techmap/pmuxtree.o
|
||||
|
|
|
|||
241
passes/techmap/breakreduce.cc
Normal file
241
passes/techmap/breakreduce.cc
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
* Copyright (C) 2025 Akash Levy <akash@silimate.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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/sigtools.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell *cell)
|
||||
{
|
||||
while (sig.size() > 1)
|
||||
{
|
||||
RTLIL::SigSpec sig_t = module->addWire(NEW_ID_SUFFIX("t"), sig.size() / 2);
|
||||
|
||||
for (int i = 0; i < sig.size(); i += 2)
|
||||
{
|
||||
if (i+1 == sig.size()) {
|
||||
sig_t.append(sig[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($or));
|
||||
gate->attributes = cell->attributes;
|
||||
gate->setPort(ID::A, sig[i]);
|
||||
gate->setPort(ID::B, sig[i+1]);
|
||||
gate->setPort(ID::Y, sig_t[i/2]);
|
||||
gate->fixup_parameters();
|
||||
}
|
||||
|
||||
sig = sig_t;
|
||||
}
|
||||
|
||||
if (sig.size() == 0)
|
||||
sig = State::S0;
|
||||
}
|
||||
|
||||
void breakreduce(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||
{
|
||||
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
|
||||
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
|
||||
|
||||
if (sig_y.size() == 0)
|
||||
return;
|
||||
|
||||
if (sig_a.size() == 0) {
|
||||
if (cell->type == ID($reduce_and)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size())));
|
||||
if (cell->type == ID($reduce_or)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
|
||||
if (cell->type == ID($reduce_xor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
|
||||
if (cell->type == ID($reduce_xnor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size())));
|
||||
if (cell->type == ID($reduce_bool)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
|
||||
return;
|
||||
}
|
||||
|
||||
if (sig_y.size() > 1) {
|
||||
module->connect(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1)));
|
||||
sig_y = sig_y.extract(0, 1);
|
||||
}
|
||||
|
||||
IdString gate_type;
|
||||
if (cell->type == ID($reduce_and)) gate_type = ID($and);
|
||||
if (cell->type == ID($reduce_or)) gate_type = ID($or);
|
||||
if (cell->type == ID($reduce_xor)) gate_type = ID($xor);
|
||||
if (cell->type == ID($reduce_xnor)) gate_type = ID($xor);
|
||||
if (cell->type == ID($reduce_bool)) gate_type = ID($or);
|
||||
log_assert(!gate_type.empty());
|
||||
|
||||
RTLIL::Cell *last_output_cell = NULL;
|
||||
|
||||
while (sig_a.size() > 1)
|
||||
{
|
||||
RTLIL::SigSpec sig_t = module->addWire(NEW_ID_SUFFIX("t"), sig_a.size() / 2);
|
||||
|
||||
for (int i = 0; i < sig_a.size(); i += 2)
|
||||
{
|
||||
if (i+1 == sig_a.size()) {
|
||||
sig_t.append(sig_a[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||
gate->attributes = cell->attributes;
|
||||
gate->setPort(ID::A, sig_a[i]);
|
||||
gate->setPort(ID::B, sig_a[i+1]);
|
||||
gate->setPort(ID::Y, sig_t[i/2]);
|
||||
gate->fixup_parameters();
|
||||
last_output_cell = gate;
|
||||
}
|
||||
|
||||
sig_a = sig_t;
|
||||
}
|
||||
|
||||
if (cell->type == ID($reduce_xnor)) {
|
||||
RTLIL::SigSpec sig_t = module->addWire(NEW_ID_SUFFIX("t"));
|
||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($not));
|
||||
gate->attributes = cell->attributes;
|
||||
gate->setPort(ID::A, sig_a);
|
||||
gate->setPort(ID::Y, sig_t);
|
||||
gate->fixup_parameters();
|
||||
last_output_cell = gate;
|
||||
sig_a = sig_t;
|
||||
}
|
||||
|
||||
if (last_output_cell == NULL) {
|
||||
module->connect(RTLIL::SigSig(sig_y, sig_a));
|
||||
} else {
|
||||
last_output_cell->setPort(ID::Y, sig_y);
|
||||
}
|
||||
|
||||
module->remove(cell);
|
||||
}
|
||||
|
||||
void breaklognot(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||
{
|
||||
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
|
||||
logic_reduce(module, sig_a, cell);
|
||||
|
||||
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
|
||||
|
||||
if (sig_y.size() == 0)
|
||||
return;
|
||||
|
||||
if (sig_y.size() > 1) {
|
||||
module->connect(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1)));
|
||||
sig_y = sig_y.extract(0, 1);
|
||||
}
|
||||
|
||||
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($not));
|
||||
gate->attributes = cell->attributes;
|
||||
gate->setPort(ID::A, sig_a);
|
||||
gate->setPort(ID::Y, sig_y);
|
||||
gate->fixup_parameters();
|
||||
|
||||
module->remove(cell);
|
||||
}
|
||||
|
||||
void breaklogbin(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||
{
|
||||
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
|
||||
logic_reduce(module, sig_a, cell);
|
||||
|
||||
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
|
||||
logic_reduce(module, sig_b, cell);
|
||||
|
||||
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
|
||||
|
||||
if (sig_y.size() == 0)
|
||||
return;
|
||||
|
||||
if (sig_y.size() > 1) {
|
||||
module->connect(RTLIL::SigSig(sig_y.extract(1, sig_y.size()-1), RTLIL::SigSpec(0, sig_y.size()-1)));
|
||||
sig_y = sig_y.extract(0, 1);
|
||||
}
|
||||
|
||||
IdString gate_type;
|
||||
if (cell->type == ID($logic_and)) gate_type = ID($and);
|
||||
if (cell->type == ID($logic_or)) gate_type = ID($or);
|
||||
log_assert(!gate_type.empty());
|
||||
|
||||
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
|
||||
gate->attributes = cell->attributes;
|
||||
gate->setPort(ID::A, sig_a);
|
||||
gate->setPort(ID::B, sig_b);
|
||||
gate->setPort(ID::Y, sig_y);
|
||||
gate->fixup_parameters();
|
||||
|
||||
module->remove(cell);
|
||||
}
|
||||
|
||||
void breakeqne(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||
{
|
||||
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
|
||||
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
|
||||
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
|
||||
bool is_signed = cell->parameters.at(ID::A_SIGNED).as_bool();
|
||||
bool is_ne = cell->type.in(ID($ne), ID($nex));
|
||||
|
||||
RTLIL::SigSpec xor_out = module->addWire(NEW_ID_SUFFIX("xor"), max(GetSize(sig_a), GetSize(sig_b)));
|
||||
RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed, cell->get_src_attribute());
|
||||
xor_cell->attributes = cell->attributes;
|
||||
|
||||
RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID_SUFFIX("reduce_out"));
|
||||
RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID_SUFFIX("reduce_or"), xor_out, reduce_out, false, cell->get_src_attribute());
|
||||
reduce_cell->attributes = cell->attributes;
|
||||
breakreduce(module, reduce_cell);
|
||||
|
||||
if (!is_ne) {
|
||||
RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID_SUFFIX("not"), reduce_out, sig_y, false, cell->get_src_attribute());
|
||||
not_cell->attributes = cell->attributes;
|
||||
breaklognot(module, not_cell);
|
||||
}
|
||||
|
||||
module->remove(cell);
|
||||
}
|
||||
|
||||
struct BreakReducePass : public Pass {
|
||||
BreakReducePass() : Pass("breakreduce", "break reduce-style cells into trees of primitives") { }
|
||||
void help() override
|
||||
{
|
||||
log("\n");
|
||||
log(" breakreduce [selection]\n");
|
||||
log("\n");
|
||||
log("Break reduce-style ($reduce_*/$logic_*/$*eq*) cells into trees of primitives.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
log_header(design, "Executing BREAKREDUCE pass (break reduce-style cells into trees of primitives).\n");
|
||||
extra_args(args, 1, design);
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
for (auto cell : module->selected_cells())
|
||||
if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool"))
|
||||
breakreduce(module, cell);
|
||||
else if (cell->type.in("$logic_and", "$logic_or"))
|
||||
breaklogbin(module, cell);
|
||||
else if (cell->type.in("$logic_not"))
|
||||
breaklognot(module, cell);
|
||||
else if (cell->type.in("$eq", "$ne", "$eqx", "$nex"))
|
||||
breakeqne(module, cell);
|
||||
}
|
||||
} BreakReducePass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
||||
872
tests/techmap/breakreduce.ys
Normal file
872
tests/techmap/breakreduce.ys
Normal file
|
|
@ -0,0 +1,872 @@
|
|||
###################################################################
|
||||
# Reduce AND Test Cases
|
||||
###################################################################
|
||||
|
||||
log -header "Simple positive reduce AND case"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = &a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 7 t:$and
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Two reduce ANDs"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (&a) | (&b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 14 t:$and
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Reduce AND on bit slice"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = &a[3:0];
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 3 t:$and
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Single bit input"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire a,
|
||||
output wire x
|
||||
);
|
||||
assign x = &a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 0 t:$and
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Unbalanced"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = &a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$and
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Reduce OR Test Cases
|
||||
###################################################################
|
||||
|
||||
log -header "Simple positive reduce OR case"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = |a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 7 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Two reduce ORs"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (|a) & (|b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 14 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Reduce OR on bit slice"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = |a[3:0];
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 3 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Single bit input"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire a,
|
||||
output wire x
|
||||
);
|
||||
assign x = |a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 0 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Unbalanced"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = |a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Reduce XOR Test Cases
|
||||
###################################################################
|
||||
|
||||
log -header "Simple positive reduce XOR case"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = ^a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 7 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Two reduce XORs"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (^a) & (^b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 14 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Reduce XOR on bit slice"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = ^a[3:0];
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 3 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Single bit input"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire a,
|
||||
output wire x
|
||||
);
|
||||
assign x = ^a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 0 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Unbalanced"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = ^a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Reduce XNOR Test Cases
|
||||
###################################################################
|
||||
|
||||
log -header "Simple positive reduce XNOR case"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = ~^a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$not
|
||||
select -assert-count 7 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Two reduce XNORs"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (~^a) & (~^b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 2 t:$not
|
||||
select -assert-count 14 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Reduce XNOR on bit slice"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = ~^a[3:0];
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$not
|
||||
select -assert-count 3 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Single bit input"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire a,
|
||||
output wire x
|
||||
);
|
||||
assign x = ~^a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 0 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Unbalanced"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = ~^a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$not
|
||||
select -assert-count 4 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Break EQ Test Cases
|
||||
###################################################################
|
||||
|
||||
log -header "Simple positive EQ case"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (a == b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$not
|
||||
select -assert-count 7 t:$or
|
||||
select -assert-count 1 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "EQ case with odd bit width and bit slice"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (a[4:0] == b[4:0]);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$not
|
||||
select -assert-count 4 t:$or
|
||||
select -assert-count 1 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Break NE Test Cases
|
||||
###################################################################
|
||||
|
||||
log -header "Simple positive NE case"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (a != b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 0 t:$not
|
||||
select -assert-count 7 t:$or
|
||||
select -assert-count 1 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "NE case with odd bit width and bit slice"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (a[4:0] != b[4:0]);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 0 t:$not
|
||||
select -assert-count 4 t:$or
|
||||
select -assert-count 1 t:$xor
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Break Logic AND Test Cases
|
||||
###################################################################
|
||||
|
||||
log -header "Simple positive AND case"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (a && b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$and
|
||||
select -assert-count 14 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Bit width mismatch and bit slicing"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [5:0] a,
|
||||
input wire [4:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (a[3:0] && b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$and
|
||||
select -assert-count 7 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Use bitwise AND and ensure it is not getting converted"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (a & b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$and
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Break Logic OR Test Cases
|
||||
###################################################################
|
||||
|
||||
log -header "Simple positive OR case"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (a || b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 15 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Bit width mismatch and bit slicing"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [5:0] a,
|
||||
input wire [4:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (a[3:0] || b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 8 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Use bitwise OR and ensure it is not getting converted"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
output wire x
|
||||
);
|
||||
assign x = (a | b);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Break Logic NOT Test Cases
|
||||
###################################################################
|
||||
|
||||
log -header "Simple positive NOT case"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = !a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$not
|
||||
select -assert-count 7 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Odd bit width"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = !a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$not
|
||||
select -assert-count 4 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Use bitwise not and ensure it is not getting converted"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = ~a;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after breakreduce
|
||||
equiv_opt -assert breakreduce
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 0 t:$or
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
Loading…
Add table
Add a link
Reference in a new issue