3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-01-08 12:01:18 +00:00
This commit is contained in:
nataliakokoromyti 2025-12-24 11:35:04 +03:00 committed by GitHub
commit b9f718d47e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 1116 additions and 0 deletions

2
.gitattributes vendored
View file

@ -1,2 +1,4 @@
*.v linguist-language=Verilog
/.gitcommit export-subst
*.ys text eol=lf

View file

@ -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

View 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

View 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