mirror of https://github.com/YosysHQ/yosys.git
Add muxmode pass and tests
This commit is contained in:
parent
dacd882383
commit
161ff0fa3f
|
|
@ -290,8 +290,8 @@ inline std::string removeNumericSuffix(const std::string& str) {
|
|||
return str; // Return unchanged if no numeric suffix found
|
||||
}
|
||||
|
||||
#define NEW_ID2 module->uniquify(removeNumericSuffix(cell->name.str()))
|
||||
#define NEW_ID2_SUFFIX(suffix) module->uniquify(cell->name.str() + "_" + suffix)
|
||||
#define NEW_ID2 cell->module->uniquify(removeNumericSuffix(cell->name.str()))
|
||||
#define NEW_ID2_SUFFIX(suffix) cell->module->uniquify(cell->name.str() + "_" + suffix)
|
||||
#define NEW_ID3 module->uniquify(cell_name.str())
|
||||
#define NEW_ID3_SUFFIX(suffix) module->uniquify(cell_name.str() + "_" + suffix)
|
||||
#define NEW_ID4 module->uniquify(name.str())
|
||||
|
|
|
|||
|
|
@ -21,3 +21,14 @@ PEEPOPT_PATTERN = passes/silimate/peepopt_expand.pmg
|
|||
|
||||
passes/silimate/peepopt_expand.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN)
|
||||
$(P) mkdir -p $(dir $@) && $(PYTHON_EXECUTABLE) $< -o $@ -p peepopt $(filter-out $<,$^)
|
||||
|
||||
OBJS += passes/silimate/muxmode.o
|
||||
GENFILES += passes/silimate/peepopt_muxmode.h
|
||||
passes/silimate/muxmode.o: passes/silimate/peepopt_muxmode.h
|
||||
$(eval $(call add_extra_objs,passes/silimate/peepopt_muxmode.h))
|
||||
|
||||
PEEPOPT_PATTERN = passes/silimate/peepopt_muxmode.pmg
|
||||
PEEPOPT_PATTERN += passes/silimate/peepopt_muxinvprop.pmg
|
||||
|
||||
passes/silimate/peepopt_muxmode.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN)
|
||||
$(P) mkdir -p $(dir $@) && $(PYTHON_EXECUTABLE) $< -o $@ -p peepopt $(filter-out $<,$^)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
* 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
|
||||
|
||||
bool did_something;
|
||||
|
||||
#include "passes/silimate/peepopt_muxmode.h"
|
||||
|
||||
struct MuxmodePass : public Pass {
|
||||
MuxmodePass() : Pass("muxmode", "convert primitives to muxes") { }
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" muxmode [selection]\n");
|
||||
log("\n");
|
||||
log("This pass makes muxes of 1-bit primitives having an input coming from a mux.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
log_header(design, "Executing MUXMODE pass (make muxes from 1-bit primitives).\n");
|
||||
|
||||
size_t argidx = 1;
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
{
|
||||
did_something = true;
|
||||
for (int i = 0; did_something; i++)
|
||||
{
|
||||
log("ITERATION %d OF MUXMODE\n", i);
|
||||
did_something = false;
|
||||
peepopt_pm pm(module);
|
||||
pm.setup(module->selected_cells());
|
||||
pm.run_muxmode();
|
||||
pm.run_muxinvprop();
|
||||
}
|
||||
}
|
||||
}
|
||||
} PeepoptPass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
pattern muxinvprop
|
||||
//
|
||||
// Authored by Akash Levy of Silimate, Inc. under ISC license.
|
||||
//
|
||||
// Propagate inverters from mux outputs to inputs
|
||||
//
|
||||
// ~ (S ? A : B) ==> S ? ~A : ~B
|
||||
//
|
||||
|
||||
state <SigSpec> mux_a mux_b mux_y inv_a inv_y
|
||||
|
||||
match mux_gate
|
||||
// Select mux
|
||||
select mux_gate->type.in($mux)
|
||||
set mux_a port(mux_gate, \A)
|
||||
set mux_b port(mux_gate, \B)
|
||||
set mux_y port(mux_gate, \Y)
|
||||
endmatch
|
||||
|
||||
code
|
||||
// Fanout of each MUX gate Y bit should be 1 (no bit-split)
|
||||
if (nusers(mux_y) != 2)
|
||||
reject;
|
||||
endcode
|
||||
|
||||
match inv_gate
|
||||
// Select inverter
|
||||
select inv_gate->type.in($not)
|
||||
set inv_a port(inv_gate, \A)
|
||||
set inv_y port(inv_gate, \Y)
|
||||
|
||||
// Connection
|
||||
index <SigSpec> port(inv_gate, \A) === mux_y
|
||||
endmatch
|
||||
|
||||
code mux_a mux_b mux_y inv_a inv_y
|
||||
// Disconnect all ports
|
||||
mux_gate->unsetPort(\A);
|
||||
mux_gate->unsetPort(\B);
|
||||
mux_gate->unsetPort(\Y);
|
||||
inv_gate->unsetPort(\A);
|
||||
inv_gate->unsetPort(\Y);
|
||||
|
||||
// Set cell to mux_gate for naming
|
||||
Cell *cell = mux_gate;
|
||||
|
||||
// Set new ports
|
||||
mux_gate->setPort(\A, module->Not(NEW_ID2_SUFFIX("not_a"), mux_a, false, mux_gate->get_src_attribute()));
|
||||
mux_gate->setPort(\B, module->Not(NEW_ID2_SUFFIX("not_b"), mux_b, false, mux_gate->get_src_attribute()));
|
||||
mux_gate->setPort(\Y, inv_y);
|
||||
|
||||
// Rename MUX gate for formal
|
||||
module->rename(mux_gate, NEW_ID2_SUFFIX("not"));
|
||||
|
||||
// Log, fixup, accept
|
||||
log("muxinvprop pattern in %s: mux=%s, not=%s\n", log_id(module), log_id(mux_gate), log_id(inv_gate));
|
||||
autoremove(inv_gate);
|
||||
did_something = true;
|
||||
accept;
|
||||
endcode
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
pattern muxmode
|
||||
//
|
||||
// Authored by Akash Levy of Silimate, Inc. under ISC license.
|
||||
//
|
||||
// Make muxes of 1-bit primitives having an input coming from a mux
|
||||
//
|
||||
// A & B ==> A ? B : 0
|
||||
// A | B ==> A ? 1 : B
|
||||
// A ^ B ==> A ? ~B : B
|
||||
// A ^~ B ==> A ? B : ~B
|
||||
//
|
||||
|
||||
state <SigSpec> mux_y prim_a prim_b
|
||||
|
||||
match mux_gate
|
||||
// Select MUX that connects to one of the primitives' inputs
|
||||
select mux_gate->type.in($mux)
|
||||
filter param(mux_gate, \WIDTH) == 1
|
||||
set mux_y port(mux_gate, \Y)
|
||||
endmatch
|
||||
|
||||
match prim_gate
|
||||
// Select AND/OR (not XOR/XNOR for now)
|
||||
select prim_gate->type.in($and, $or)
|
||||
filter param(prim_gate, \A_WIDTH) == 1
|
||||
filter param(prim_gate, \B_WIDTH) == 1
|
||||
|
||||
// Set ports, allowing A and B to be swapped
|
||||
choice <IdString> A {\A, \B}
|
||||
define <IdString> B (A == \A ? \B : \A)
|
||||
set prim_a port(prim_gate, A)
|
||||
set prim_b port(prim_gate, B)
|
||||
|
||||
// Connection
|
||||
index <SigSpec> port(prim_gate, B) === mux_y
|
||||
endmatch
|
||||
|
||||
code mux_y prim_a prim_b
|
||||
// Unset ports/params of primitive
|
||||
prim_gate->unsetPort(\A);
|
||||
prim_gate->unsetPort(\B);
|
||||
prim_gate->unsetParam(\A_WIDTH);
|
||||
prim_gate->unsetParam(\A_SIGNED);
|
||||
prim_gate->unsetParam(\B_WIDTH);
|
||||
prim_gate->unsetParam(\B_SIGNED);
|
||||
prim_gate->unsetParam(\Y_WIDTH);
|
||||
|
||||
// Set mux's S port to primitive's A port
|
||||
prim_gate->setPort(\S, prim_a);
|
||||
|
||||
// Set cell to be prim_gate for naming
|
||||
Cell *cell = prim_gate;
|
||||
|
||||
// Set mux inputs
|
||||
if (prim_gate->type == $and) {
|
||||
prim_gate->setPort(\A, State::S0);
|
||||
prim_gate->setPort(\B, prim_b);
|
||||
} else if (prim_gate->type == $or) {
|
||||
prim_gate->setPort(\A, prim_b);
|
||||
prim_gate->setPort(\B, State::S1);
|
||||
} else if (prim_gate->type == $xor) {
|
||||
prim_gate->setPort(\A, prim_b);
|
||||
prim_gate->setPort(\B, module->Not(NEW_ID2, prim_b, false, cell->get_src_attribute()));
|
||||
} else if (prim_gate->type == $xnor) {
|
||||
prim_gate->setPort(\A, module->Not(NEW_ID2, prim_b, false, cell->get_src_attribute()));
|
||||
prim_gate->setPort(\B, prim_b);
|
||||
} else {
|
||||
log_abort();
|
||||
}
|
||||
|
||||
// Log, fixup type and parameters, accept
|
||||
log("muxmode pattern in %s: mux=%s, prim=%s, primtype=%s\n", log_id(module), log_id(mux_gate), log_id(prim_gate), log_id(prim_gate->type));
|
||||
prim_gate->type = $mux;
|
||||
prim_gate->fixup_parameters();
|
||||
did_something = true;
|
||||
accept;
|
||||
endcode
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
log -header "Simple positive case with 4-long mux chain and 1 inverted component"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [3:0] s,
|
||||
input wire [3:0] b,
|
||||
input wire a,
|
||||
output wire y
|
||||
);
|
||||
assign y = s[0] ? b[0] : (s[1] ? b[1] : ~(s[2] ? b[2] : (s[3] ? b[3] : a)));
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# # Show pre
|
||||
# autoname
|
||||
# write_json pre.json
|
||||
# exec -- netlistsvg pre.json -o pre.svg
|
||||
|
||||
# Check equivalence after muxmode
|
||||
equiv_opt -assert muxmode
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$mux
|
||||
select -assert-count 3 t:$not
|
||||
|
||||
# # Show post
|
||||
# autoname
|
||||
# write_json post.json
|
||||
# exec -- netlistsvg post.json -o post.svg
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Simple negative case with 4-long mux chain and 1 inverted fo2 component"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [3:0] s,
|
||||
input wire [3:0] b,
|
||||
input wire a,
|
||||
output wire y,
|
||||
output wire y2
|
||||
);
|
||||
wire m;
|
||||
assign m = s[2] ? b[2] : (s[3] ? b[3] : a);
|
||||
assign y2 = m;
|
||||
assign y = s[0] ? b[0] : (s[1] ? b[1] : ~m);
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# # Show pre
|
||||
# autoname
|
||||
# write_json pre.json
|
||||
# exec -- netlistsvg pre.json -o pre.svg
|
||||
|
||||
# Check equivalence after muxmode
|
||||
equiv_opt -assert muxmode
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$mux
|
||||
select -assert-count 1 t:$not
|
||||
|
||||
# # Show post
|
||||
# autoname
|
||||
# write_json post.json
|
||||
# exec -- netlistsvg post.json -o post.svg
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
|
@ -0,0 +1,362 @@
|
|||
log -header "Simple positive case with AND"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire s1,
|
||||
input wire s2,
|
||||
input wire a,
|
||||
input wire b,
|
||||
input wire c,
|
||||
input wire d,
|
||||
output wire x
|
||||
);
|
||||
wire m1, m2;
|
||||
|
||||
assign m1 = s1 ? b : a;
|
||||
assign m2 = m1 & c;
|
||||
assign x = s2 ? m2 : d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# # Show pre
|
||||
# autoname
|
||||
# write_json pre.json
|
||||
# exec -- netlistsvg pre.json -o pre.svg
|
||||
|
||||
# Check equivalence after muxmode
|
||||
equiv_opt -assert muxmode
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 3 t:$mux
|
||||
|
||||
# # Show post
|
||||
# autoname
|
||||
# write_json post.json
|
||||
# exec -- netlistsvg post.json -o post.svg
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Simple positive case with AND (order reversed)"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire s1,
|
||||
input wire s2,
|
||||
input wire a,
|
||||
input wire b,
|
||||
input wire c,
|
||||
input wire d,
|
||||
output wire x
|
||||
);
|
||||
wire m1, m2;
|
||||
|
||||
assign m1 = s1 ? b : a;
|
||||
assign m2 = c & m1;
|
||||
assign x = s2 ? m2 : d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# # Show pre
|
||||
# autoname
|
||||
# write_json pre.json
|
||||
# exec -- netlistsvg pre.json -o pre.svg
|
||||
|
||||
# Check equivalence after muxmode
|
||||
equiv_opt -assert muxmode
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 3 t:$mux
|
||||
|
||||
# # Show post
|
||||
# autoname
|
||||
# write_json post.json
|
||||
# exec -- netlistsvg post.json -o post.svg
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Simple positive case with OR"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire s1,
|
||||
input wire s2,
|
||||
input wire a,
|
||||
input wire b,
|
||||
input wire c,
|
||||
input wire d,
|
||||
output wire x
|
||||
);
|
||||
wire m1, m2;
|
||||
|
||||
assign m1 = s1 ? b : a;
|
||||
assign m2 = m1 | c;
|
||||
assign x = s2 ? m2 : d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# # Show pre
|
||||
# autoname
|
||||
# write_json pre.json
|
||||
# exec -- netlistsvg pre.json -o pre.svg
|
||||
|
||||
# Check equivalence after muxmode
|
||||
equiv_opt -assert muxmode
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 3 t:$mux
|
||||
|
||||
# # Show post
|
||||
# autoname
|
||||
# write_json post.json
|
||||
# exec -- netlistsvg post.json -o post.svg
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Simple positive case with OR (order reversed)"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire s1,
|
||||
input wire s2,
|
||||
input wire a,
|
||||
input wire b,
|
||||
input wire c,
|
||||
input wire d,
|
||||
output wire x
|
||||
);
|
||||
wire m1, m2;
|
||||
|
||||
assign m1 = s1 ? b : a;
|
||||
assign m2 = c | m1;
|
||||
assign x = s2 ? m2 : d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# # Show pre
|
||||
# autoname
|
||||
# write_json pre.json
|
||||
# exec -- netlistsvg pre.json -o pre.svg
|
||||
|
||||
# Check equivalence after muxmode
|
||||
equiv_opt -assert muxmode
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 3 t:$mux
|
||||
|
||||
# # Show post
|
||||
# autoname
|
||||
# write_json post.json
|
||||
# exec -- netlistsvg post.json -o post.svg
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
log -header "Simple negative case with multi-bit AND"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [1:0] s1,
|
||||
input wire [1:0] s2,
|
||||
input wire [1:0] a,
|
||||
input wire [1:0] b,
|
||||
input wire [1:0] c,
|
||||
input wire [1:0] d,
|
||||
output wire [1:0] x
|
||||
);
|
||||
wire m1, m2;
|
||||
|
||||
assign m1 = s1 ? b : a;
|
||||
assign m2 = m1 & c;
|
||||
assign x = s2 ? m2 : d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# # Show pre
|
||||
# autoname
|
||||
# write_json pre.json
|
||||
# exec -- netlistsvg pre.json -o pre.svg
|
||||
|
||||
# Check equivalence after muxmode
|
||||
equiv_opt -assert muxmode
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$and
|
||||
select -assert-count 2 t:$mux
|
||||
|
||||
# # Show post
|
||||
# autoname
|
||||
# write_json post.json
|
||||
# exec -- netlistsvg post.json -o post.svg
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Simple negative case with multi-bit AND (order reversed)"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [1:0] s1,
|
||||
input wire [1:0] s2,
|
||||
input wire [1:0] a,
|
||||
input wire [1:0] b,
|
||||
input wire [1:0] c,
|
||||
input wire [1:0] d,
|
||||
output wire [1:0] x
|
||||
);
|
||||
wire m1, m2;
|
||||
|
||||
assign m1 = s1 ? b : a;
|
||||
assign m2 = c & m1;
|
||||
assign x = s2 ? m2 : d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# # Show pre
|
||||
# autoname
|
||||
# write_json pre.json
|
||||
# exec -- netlistsvg pre.json -o pre.svg
|
||||
|
||||
# Check equivalence after muxmode
|
||||
equiv_opt -assert muxmode
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$and
|
||||
select -assert-count 2 t:$mux
|
||||
|
||||
# # Show post
|
||||
# autoname
|
||||
# write_json post.json
|
||||
# exec -- netlistsvg post.json -o post.svg
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Simple negative case with OR"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [1:0] s1,
|
||||
input wire [1:0] s2,
|
||||
input wire [1:0] a,
|
||||
input wire [1:0] b,
|
||||
input wire [1:0] c,
|
||||
input wire [1:0] d,
|
||||
output wire [1:0] x
|
||||
);
|
||||
wire m1, m2;
|
||||
|
||||
assign m1 = s1 ? b : a;
|
||||
assign m2 = m1 | c;
|
||||
assign x = s2 ? m2 : d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# # Show pre
|
||||
# autoname
|
||||
# write_json pre.json
|
||||
# exec -- netlistsvg pre.json -o pre.svg
|
||||
|
||||
# Check equivalence after muxmode
|
||||
equiv_opt -assert muxmode
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$or
|
||||
select -assert-count 2 t:$mux
|
||||
|
||||
# # Show post
|
||||
# autoname
|
||||
# write_json post.json
|
||||
# exec -- netlistsvg post.json -o post.svg
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Simple negative case with multi-bit OR (order reversed)"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [1:0] s1,
|
||||
input wire [1:0] s2,
|
||||
input wire [1:0] a,
|
||||
input wire [1:0] b,
|
||||
input wire [1:0] c,
|
||||
input wire [1:0] d,
|
||||
output wire [1:0] x
|
||||
);
|
||||
wire m1, m2;
|
||||
|
||||
assign m1 = s1 ? b : a;
|
||||
assign m2 = c | m1;
|
||||
assign x = s2 ? m2 : d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# # Show pre
|
||||
# autoname
|
||||
# write_json pre.json
|
||||
# exec -- netlistsvg pre.json -o pre.svg
|
||||
|
||||
# Check equivalence after muxmode
|
||||
equiv_opt -assert muxmode
|
||||
|
||||
# Check final design has correct number of gates
|
||||
design -load postopt
|
||||
select -assert-count 1 t:$or
|
||||
select -assert-count 2 t:$mux
|
||||
|
||||
# # Show post
|
||||
# autoname
|
||||
# write_json post.json
|
||||
# exec -- netlistsvg post.json -o post.svg
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
Loading…
Reference in New Issue