mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #78 from williamzhu17/extract_reduce-tests
extract_reduce tests and removed XNOR functionality from extract_reduce
This commit is contained in:
commit
809a38a597
|
|
@ -30,7 +30,6 @@ struct ExtractReducePass : public Pass
|
|||
And,
|
||||
Or,
|
||||
Xor,
|
||||
Xnor,
|
||||
Mux
|
||||
};
|
||||
|
||||
|
|
@ -51,8 +50,8 @@ struct ExtractReducePass : public Pass
|
|||
log("to map the design to only $_AND_ cells, run extract_reduce, map the remaining\n");
|
||||
log("parts of the design to AND/OR/XOR cells, and run extract_reduce a second time.\n");
|
||||
log("\n");
|
||||
log("Silimate has modified this pass to support word-level cells ($and, $or, $xor,\n");
|
||||
log("and $xnor) as well as the single-bit cells ($_AND_, $_OR_, $_XOR_, and $_XNOR_).\n");
|
||||
log("Silimate has modified this pass to support word-level cells ($and, $or, \n");
|
||||
log("and $xor) as well as the single-bit cells ($_AND_, $_OR_, and $_XOR_).\n");
|
||||
log("Mux cells ($mux, $_MUX_) can also be reduced to $pmux cells with the mods.\n");
|
||||
log("\n");
|
||||
log(" -allow-off-chain\n");
|
||||
|
|
@ -86,12 +85,10 @@ struct ExtractReducePass : public Pass
|
|||
return (cell->type == ID($_AND_) && gt == GateType::And) ||
|
||||
(cell->type == ID($_OR_) && gt == GateType::Or) ||
|
||||
(cell->type == ID($_XOR_) && gt == GateType::Xor) ||
|
||||
(cell->type == ID($_XNOR_) && gt == GateType::Xnor) ||
|
||||
(cell->type == ID($_MUX_) && gt == GateType::Mux) ||
|
||||
(cell->type == ID($and) && IsSingleBit(cell) && gt == GateType::And) ||
|
||||
(cell->type == ID($or) && IsSingleBit(cell) && gt == GateType::Or) ||
|
||||
(cell->type == ID($xor) && IsSingleBit(cell) && gt == GateType::Xor) ||
|
||||
(cell->type == ID($xnor) && IsSingleBit(cell) && gt == GateType::Xnor) ||
|
||||
(cell->type == ID($mux) && IsSingleBit(cell) && gt == GateType::Mux);
|
||||
}
|
||||
|
||||
|
|
@ -177,8 +174,6 @@ struct ExtractReducePass : public Pass
|
|||
gt = GateType::Or;
|
||||
else if (cell->type == ID($_XOR_))
|
||||
gt = GateType::Xor;
|
||||
else if (cell->type == ID($_XNOR_))
|
||||
gt = GateType::Xnor;
|
||||
else if (cell->type == ID($_MUX_))
|
||||
gt = GateType::Mux;
|
||||
else if (cell->type == ID($and) && IsSingleBit(cell))
|
||||
|
|
@ -187,8 +182,6 @@ struct ExtractReducePass : public Pass
|
|||
gt = GateType::Or;
|
||||
else if (cell->type == ID($xor) && IsSingleBit(cell))
|
||||
gt = GateType::Xor;
|
||||
else if (cell->type == ID($xnor) && IsSingleBit(cell))
|
||||
gt = GateType::Xnor;
|
||||
else if (cell->type == ID($mux) && IsSingleBit(cell))
|
||||
gt = GateType::Mux;
|
||||
else
|
||||
|
|
@ -355,7 +348,7 @@ struct ExtractReducePass : public Pass
|
|||
SigSpec input, sel;
|
||||
for (auto it : sources) {
|
||||
bool cond;
|
||||
if (head_cell->type == ID($_XOR_) || head_cell->type == ID($xor) || head_cell->type == ID($_XNOR_) || head_cell->type == ID($xnor))
|
||||
if (head_cell->type == ID($_XOR_) || head_cell->type == ID($xor))
|
||||
cond = it.second & 1;
|
||||
else
|
||||
cond = it.second != 0;
|
||||
|
|
@ -375,8 +368,6 @@ struct ExtractReducePass : public Pass
|
|||
module->addReduceOr(NEW_ID2_SUFFIX("reduce_or"), input, output, false, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
} else if (head_cell->type == ID($_XOR_) || head_cell->type == ID($xor)) {
|
||||
module->addReduceXor(NEW_ID2_SUFFIX("reduce_xor"), input, output, false, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
} else if (head_cell->type == ID($_XNOR_) || head_cell->type == ID($xnor)) {
|
||||
module->addReduceXnor(NEW_ID2_SUFFIX("reduce_xnor"), input, output, false, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
} else if (head_cell->type == ID($_MUX_) || head_cell->type == ID($mux)) {
|
||||
module->addPmux(NEW_ID2_SUFFIX("pmux"), State::Sx, input, sel, output, cell->get_src_attribute()); // SILIMATE: Improve the naming
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,950 @@
|
|||
###################################################################
|
||||
# Extract Reduce AND Gates Tests
|
||||
###################################################################
|
||||
|
||||
log -header "Simple AND chain"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [3:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = a[0] & a[1] & a[2] & a[3];
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 1 t:$reduce_and
|
||||
select -assert-count 1 t:$reduce_and r:A_WIDTH=4 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "AND chain with constants"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [2:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = a[0] & a[1] & a[2] & 1'b1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 1 t:$reduce_and
|
||||
select -assert-count 1 t:$reduce_and r:A_WIDTH=4 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "AND chain with multiple branches"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [5:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1, w2, w3;
|
||||
|
||||
assign w0 = a[0] & a[1];
|
||||
assign w1 = a[2] & a[3];
|
||||
assign w2 = a[4] & a[5];
|
||||
assign w3 = w0 & w1;
|
||||
assign x = w2 & w3;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 1 t:$reduce_and
|
||||
select -assert-count 1 t:$reduce_and r:A_WIDTH=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "No off-chain for AND"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0, w1, w2;
|
||||
|
||||
assign w0 = a[0] & a[1];
|
||||
assign w1 = w0 & a[2];
|
||||
assign w2 = w1 & a[3];
|
||||
assign x = w2 & a[4];
|
||||
|
||||
// Off-chain use of w1
|
||||
assign y = w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 2 t:$reduce_and
|
||||
select -assert-count 2 t:$reduce_and
|
||||
|
||||
# Check that both gates are 3 bits wide
|
||||
select -assert-none t:$reduce_and r:A_WIDTH!=3 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Allow off-chain for AND"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0, w1, w2;
|
||||
|
||||
assign w0 = a[0] & a[1];
|
||||
assign w1 = w0 & a[2];
|
||||
assign w2 = w1 & a[3];
|
||||
assign x = w2 & a[4];
|
||||
|
||||
// Off-chain use of w1
|
||||
assign y = w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce -allow-off-chain
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 2 t:$reduce_and
|
||||
|
||||
# Check that only one gate has a width of 5 and one gate has a width of 3
|
||||
select -assert-count 1 t:$reduce_and r:A_WIDTH=5 %i
|
||||
select -assert-count 1 t:$reduce_and r:A_WIDTH=3 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "No off-chain with branches for AND"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [10:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0;
|
||||
|
||||
assign w0 = a[0] & a[1] & a[2] & (a[3] & a[4]) & a[5];
|
||||
assign x = w0 & a[6] & a[7] & (a[8] & a[9]) & a[10];
|
||||
|
||||
// Off-chain use of w0
|
||||
assign y = w0;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 2 t:$reduce_and
|
||||
|
||||
# Check that both gates are 6 bits wide
|
||||
select -assert-none t:$reduce_and r:A_WIDTH!=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Allow off-chain with branches for AND"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [10:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0;
|
||||
|
||||
assign w0 = a[0] & a[1] & a[2] & (a[3] & a[4]) & a[5];
|
||||
assign x = w0 & a[6] & a[7] & (a[8] & a[9]) & a[10];
|
||||
|
||||
// Off-chain use of w0
|
||||
assign y = w0;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce -allow-off-chain
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 2 t:$reduce_and
|
||||
|
||||
# Check that only one gate has a width of 11 and one gate has a width of 6
|
||||
select -assert-count 1 t:$reduce_and r:A_WIDTH=11 %i
|
||||
select -assert-count 1 t:$reduce_and r:A_WIDTH=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Extract Reduce OR Gates Tests
|
||||
###################################################################
|
||||
|
||||
log -header "Simple OR chain"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [3:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = a[0] | a[1] | a[2] | a[3];
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$or
|
||||
select -assert-count 1 t:$reduce_or
|
||||
select -assert-count 1 t:$reduce_or r:A_WIDTH=4 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "OR chain with constants"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [3:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = a[0] | a[1] | a[2] | 1'b1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$or
|
||||
select -assert-count 1 t:$reduce_or
|
||||
select -assert-count 1 t:$reduce_or r:A_WIDTH=4 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "OR chain with multiple branches"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [5:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1, w2, w3;
|
||||
|
||||
assign w0 = a[0] | a[1];
|
||||
assign w1 = a[2] | a[3];
|
||||
assign w2 = a[4] | a[5];
|
||||
assign w3 = w0 | w1;
|
||||
assign x = w2 | w3;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$or
|
||||
select -assert-count 1 t:$reduce_or
|
||||
select -assert-count 1 t:$reduce_or r:A_WIDTH=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "No off-chain OR"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0, w1, w2;
|
||||
|
||||
assign w0 = a[0] | a[1];
|
||||
assign w1 = w0 | a[2];
|
||||
assign w2 = w1 | a[3];
|
||||
assign x = w2 | a[4];
|
||||
|
||||
// Off-chain use of w1
|
||||
assign y = w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$or
|
||||
select -assert-count 2 t:$reduce_or
|
||||
|
||||
# Check that both gates are 3 bits wide
|
||||
select -assert-none t:$reduce_or r:A_WIDTH!=3 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Allow off-chain for OR"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0, w1, w2;
|
||||
|
||||
assign w0 = a[0] | a[1];
|
||||
assign w1 = w0 | a[2];
|
||||
assign w2 = w1 | a[3];
|
||||
assign x = w2 | a[4];
|
||||
|
||||
// Off-chain use of w1
|
||||
assign y = w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce -allow-off-chain
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$or
|
||||
select -assert-count 2 t:$reduce_or
|
||||
|
||||
# Check that only one gate has a width of 5 and one gate has a width of 3
|
||||
select -assert-count 1 t:$reduce_or r:A_WIDTH=5 %i
|
||||
select -assert-count 1 t:$reduce_or r:A_WIDTH=3 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "No off-chain with branches for OR"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [10:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0;
|
||||
|
||||
assign w0 = a[0] | a[1] | a[2] | (a[3] | a[4]) | a[5];
|
||||
assign x = w0 | a[6] | a[7] | (a[8] | a[9]) | a[10];
|
||||
|
||||
// Off-chain use of w0
|
||||
assign y = w0;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 2 t:$reduce_or
|
||||
|
||||
# Check that both gates are 6 bits wide
|
||||
select -assert-none t:$reduce_or r:A_WIDTH!=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Allow off-chain with branches for OR"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [10:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0;
|
||||
|
||||
assign w0 = a[0] | a[1] | a[2] | (a[3] | a[4]) | a[5];
|
||||
assign x = w0 | a[6] | a[7] | (a[8] | a[9]) | a[10];
|
||||
|
||||
// Off-chain use of w0
|
||||
assign y = w0;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce -allow-off-chain
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$or
|
||||
select -assert-count 2 t:$reduce_or
|
||||
|
||||
# Check that only one gate has a width of 11 and one gate has a width of 6
|
||||
select -assert-count 1 t:$reduce_or r:A_WIDTH=11 %i
|
||||
select -assert-count 1 t:$reduce_or r:A_WIDTH=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Extract Reduce XOR Gates Tests
|
||||
###################################################################
|
||||
|
||||
log -header "Simple XOR chain"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [3:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = a[0] ^ a[1] ^ a[2] ^ a[3];
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$xor
|
||||
select -assert-count 1 t:$reduce_xor
|
||||
select -assert-count 1 t:$reduce_xor r:A_WIDTH=4 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "XOR chain with constants"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [3:0] a,
|
||||
output wire x
|
||||
);
|
||||
assign x = a[0] ^ a[1] ^ a[2] ^ 1'b1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$xor
|
||||
select -assert-count 1 t:$reduce_xor
|
||||
select -assert-count 1 t:$reduce_xor r:A_WIDTH=4 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "XOR chain with multiple branches"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [5:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1, w2, w3;
|
||||
|
||||
assign w0 = a[0] ^ a[1];
|
||||
assign w1 = a[2] ^ a[3];
|
||||
assign w2 = a[4] ^ a[5];
|
||||
assign w3 = w0 ^ w1;
|
||||
assign x = w2 ^ w3;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$xor
|
||||
select -assert-count 1 t:$reduce_xor
|
||||
select -assert-count 1 t:$reduce_xor r:A_WIDTH=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "No off-chain XOR"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0, w1, w2;
|
||||
|
||||
assign w0 = a[0] ^ a[1];
|
||||
assign w1 = w0 ^ a[2];
|
||||
assign w2 = w1 ^ a[3];
|
||||
assign x = w2 ^ a[4];
|
||||
|
||||
// Off-chain use of w1
|
||||
assign y = w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$xor
|
||||
select -assert-count 2 t:$reduce_xor
|
||||
|
||||
# Check that both gates are 3 bits wide
|
||||
select -assert-none t:$reduce_xor r:A_WIDTH!=3 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Allow off-chain for XOR"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [4:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0, w1, w2;
|
||||
|
||||
assign w0 = a[0] ^ a[1];
|
||||
assign w1 = w0 ^ a[2];
|
||||
assign w2 = w1 ^ a[3];
|
||||
assign x = w2 ^ a[4];
|
||||
|
||||
// Off-chain use of w1
|
||||
assign y = w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce -allow-off-chain
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$xor
|
||||
select -assert-count 2 t:$reduce_xor
|
||||
|
||||
# Check that only one gate has a width of 5 and one gate has a width of 3
|
||||
select -assert-count 1 t:$reduce_xor r:A_WIDTH=5 %i
|
||||
select -assert-count 1 t:$reduce_xor r:A_WIDTH=3 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "No off-chain with branches for XOR"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [10:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0;
|
||||
|
||||
assign w0 = a[0] ^ a[1] ^ a[2] ^ (a[3] ^ a[4]) ^ a[5];
|
||||
assign x = w0 ^ a[6] ^ a[7] ^ (a[8] ^ a[9]) ^ a[10];
|
||||
|
||||
// Off-chain use of w0
|
||||
assign y = w0;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$xor
|
||||
select -assert-count 2 t:$reduce_xor
|
||||
|
||||
# Check that both gates are 6 bits wide
|
||||
select -assert-none t:$reduce_xor r:A_WIDTH!=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Allow off-chain with branches for XOR"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [10:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0;
|
||||
|
||||
assign w0 = a[0] ^ a[1] ^ a[2] ^ (a[3] ^ a[4]) ^ a[5];
|
||||
assign x = w0 ^ a[6] ^ a[7] ^ (a[8] ^ a[9]) ^ a[10];
|
||||
|
||||
// Off-chain use of w0
|
||||
assign y = w0;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce -allow-off-chain
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates
|
||||
select -assert-count 0 t:$xor
|
||||
select -assert-count 2 t:$reduce_xor
|
||||
|
||||
# Check that only one gate has a width of 11 and one gate has a width of 6
|
||||
select -assert-count 1 t:$reduce_xor r:A_WIDTH=11 %i
|
||||
select -assert-count 1 t:$reduce_xor r:A_WIDTH=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
###################################################################
|
||||
# Edge Cases
|
||||
###################################################################
|
||||
|
||||
log -header "Reconvergence"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
output wire y
|
||||
);
|
||||
wire w0, w1, w2, w3, w4, w5, w6;
|
||||
|
||||
assign w0 = a[0] & a[1];
|
||||
assign w1 = a[2] & a[3];
|
||||
assign w2 = w0 & w1;
|
||||
assign w3 = w2 & a[4];
|
||||
assign w4 = w2 & a[5];
|
||||
assign w5 = w3 & a[6];
|
||||
assign w6 = w4 & a[7];
|
||||
assign y = w5 & w6;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 2 t:$reduce_and
|
||||
select -assert-count 1 t:$reduce_and r:A_WIDTH=4 %i
|
||||
select -assert-count 1 t:$reduce_and r:A_WIDTH=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Stress test"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a0,
|
||||
input wire [7:0] a1,
|
||||
input wire [7:0] a2,
|
||||
output wire y
|
||||
);
|
||||
wire c0, c1, c2;
|
||||
|
||||
// Stage 0
|
||||
wire s0_w0 = a0[0] & a0[1];
|
||||
wire s0_w1 = a0[2] & a0[3];
|
||||
wire s0_w2 = s0_w0 & s0_w1;
|
||||
wire s0_w3 = s0_w2 & a0[4];
|
||||
wire s0_w4 = a0[0] & a0[5];
|
||||
wire s0_w5 = s0_w3 & a0[6];
|
||||
wire s0_w6 = s0_w4 & a0[7];
|
||||
assign c0 = s0_w5 & s0_w6;
|
||||
|
||||
// Stage 1
|
||||
wire s1_w0 = a1[0] & a1[1];
|
||||
wire s1_w1 = a1[2] & a1[3];
|
||||
wire s1_w2 = s1_w0 & s1_w1;
|
||||
wire s1_w3 = s1_w2 & a1[4];
|
||||
wire s1_w4 = c0 & a1[5];
|
||||
wire s1_w5 = s1_w3 & a1[6];
|
||||
wire s1_w6 = s1_w4 & a1[7];
|
||||
assign c1 = s1_w5 & s1_w6;
|
||||
|
||||
// Stage 2
|
||||
wire s2_w0 = a2[0] & a2[1];
|
||||
wire s2_w1 = a2[2] & a2[3];
|
||||
wire s2_w2 = s2_w0 & s2_w1;
|
||||
wire s2_w3 = s2_w2 & a2[4];
|
||||
wire s2_w4 = c1 & a2[5];
|
||||
wire s2_w5 = s2_w3 & a2[6];
|
||||
wire s2_w6 = s2_w4 & a2[7];
|
||||
assign c2 = s2_w5 & s2_w6;
|
||||
|
||||
assign y = c2;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
extract_reduce
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 1 t:$reduce_and
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Stress test reconvergence"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a0,
|
||||
input wire [7:0] a1,
|
||||
input wire [7:0] a2,
|
||||
output wire y
|
||||
);
|
||||
wire c0, c1, c2;
|
||||
|
||||
// Stage 0
|
||||
wire s0_w0 = a0[0] & a0[1];
|
||||
wire s0_w1 = a0[2] & a0[3];
|
||||
wire s0_w2 = s0_w0 & s0_w1;
|
||||
wire s0_w3 = s0_w2 & a0[4];
|
||||
wire s0_w4 = s0_w2 & a0[5];
|
||||
wire s0_w5 = s0_w3 & a0[6];
|
||||
wire s0_w6 = s0_w4 & a0[7];
|
||||
assign c0 = s0_w5 & s0_w6;
|
||||
|
||||
// Stage 1
|
||||
wire s1_w0 = a1[0] & a1[1];
|
||||
wire s1_w1 = a1[2] & a1[3];
|
||||
wire s1_w2 = s1_w0 & s1_w1;
|
||||
wire s1_w3 = s1_w2 & a1[4];
|
||||
wire s1_w4 = s1_w2 & a1[5];
|
||||
wire s1_w5 = s1_w3 & a1[6];
|
||||
wire s1_w6 = s1_w4 & c0;
|
||||
assign c1 = s1_w5 & s1_w6;
|
||||
|
||||
// Stage 2
|
||||
wire s2_w0 = a2[0] & a2[1];
|
||||
wire s2_w1 = a2[2] & a2[3];
|
||||
wire s2_w2 = s2_w0 & s2_w1;
|
||||
wire s2_w3 = s2_w2 & a2[4];
|
||||
wire s2_w4 = s2_w2 & a2[5];
|
||||
wire s2_w5 = s2_w3 & a2[6];
|
||||
wire s2_w6 = s2_w4 & c1;
|
||||
assign c2 = s2_w5 & s2_w6;
|
||||
|
||||
assign y = c2;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check final design has correct number of gates and inputs
|
||||
select -assert-count 0 t:$and
|
||||
select -assert-count 4 t:$reduce_and
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
|
@ -0,0 +1,584 @@
|
|||
log -header "Simple MUX chain to PMUX"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [2:0] sel,
|
||||
input wire [3:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1;
|
||||
|
||||
assign w0 = sel[0] ? a[1] : a[0];
|
||||
assign w1 = sel[1] ? a[2] : w0;
|
||||
assign x = sel[2] ? a[3] : w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check we got a single pmux with the correct input number
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 1 t:$pmux
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=4 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "MUX chain with constants"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [2:0] sel,
|
||||
input wire [2:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1;
|
||||
|
||||
assign w0 = sel[0] ? a[1] : a[0];
|
||||
assign w1 = sel[1] ? a[2] : w0;
|
||||
assign x = sel[2] ? 1'b1 : w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check we got a single pmux with the correct input number
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 1 t:$pmux
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=4 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "MUX chain with multiple branches"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [2:0] sel,
|
||||
input wire [3:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1;
|
||||
|
||||
assign w0 = sel[0] ? a[1] : a[0];
|
||||
assign w1 = sel[1] ? a[2] : a[3];
|
||||
assign x = sel[2] ? w0 : w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check we got a single pmux with the correct input number
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 1 t:$pmux
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=4 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "MUX chain with multiple uneven branches"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [5:0] sel,
|
||||
input wire [6:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1, w2, w3, w4;
|
||||
|
||||
assign w0 = sel[0] ? a[1] : a[0];
|
||||
assign w1 = sel[1] ? a[2] : w0;
|
||||
assign w2 = sel[2] ? a[3] : w1;
|
||||
assign w3 = sel[3] ? w2 : w4;
|
||||
assign w4 = sel[5] ? a[4] : a[5];
|
||||
assign x = sel[4] ? w3 : a[6];
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check we got a single pmux with the correct input number
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 1 t:$pmux
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=7 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "No off-chain MUX chain"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [3:0] sel,
|
||||
input wire [4:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0, w1, w2;
|
||||
|
||||
assign w0 = sel[0] ? a[1] : a[0];
|
||||
assign w1 = sel[1] ? a[2] : w0;
|
||||
assign w2 = sel[2] ? a[3] : w1;
|
||||
assign x = sel[3] ? a[4] : w2;
|
||||
|
||||
// Off-chain use of intermediate wire
|
||||
assign y = w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check we got two pmuxes
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 2 t:$pmux
|
||||
|
||||
# Check that both pmuxes have input width of 3
|
||||
select -assert-none t:$pmux r:S_WIDTH!=3 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
|
||||
log -header "Allow off-chain MUX chain"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [3:0] sel,
|
||||
input wire [4:0] a,
|
||||
output wire x,
|
||||
output wire y
|
||||
);
|
||||
wire w0, w1, w2;
|
||||
|
||||
assign w0 = sel[0] ? a[1] : a[0];
|
||||
assign w1 = sel[1] ? a[2] : w0;
|
||||
assign w2 = sel[2] ? a[3] : w1;
|
||||
assign x = sel[3] ? a[4] : w2;
|
||||
|
||||
assign y = w1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce -allow-off-chain
|
||||
|
||||
# Load design and run opt_clean to remove unnecessary wires
|
||||
design -load postopt
|
||||
opt_clean
|
||||
|
||||
# Check we got two pmux
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 2 t:$pmux
|
||||
|
||||
# Check that one pmux has an input width of 3
|
||||
# and the other has an input width of 5
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=3 %i
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=5 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Reconverging tree; no off-chain"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] sel,
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1, w2, w3, w4, w5, w6;
|
||||
|
||||
assign w0 = sel[0] ? a[1] : a[0];
|
||||
assign w1 = sel[1] ? a[2] : w0;
|
||||
assign w2 = sel[2] ? w4 : w1;
|
||||
assign w3 = sel[3] ? w2 : w5;
|
||||
assign w4 = sel[6] ? a[3] : w6;
|
||||
assign w5 = sel[5] ? a[5] : w4;
|
||||
assign w6 = sel[7] ? a[7] : a[4];
|
||||
assign x = sel[4] ? a[6] : w3;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean and opt_reduce to remove unnecessary cells
|
||||
design -load postopt
|
||||
opt_clean
|
||||
opt_reduce
|
||||
|
||||
# Check we got one pmux with correct number of inputs
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 2 t:$pmux
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=3 %i
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Reconverging tree; yes off-chain"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] sel,
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1, w2, w3, w4, w5, w6;
|
||||
|
||||
assign w0 = sel[0] ? a[1] : a[0];
|
||||
assign w1 = sel[1] ? a[2] : w0;
|
||||
assign w2 = sel[2] ? w4 : w1;
|
||||
assign w3 = sel[3] ? w2 : w5;
|
||||
assign w4 = sel[6] ? a[3] : w6;
|
||||
assign w5 = sel[5] ? a[5] : w4;
|
||||
assign w6 = sel[7] ? a[7] : a[4];
|
||||
assign x = sel[4] ? a[6] : w3;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce -allow-off-chain
|
||||
|
||||
# Load design and run opt_clean and opt_reduce to remove unnecessary cells
|
||||
design -load postopt
|
||||
opt_clean
|
||||
opt_reduce
|
||||
|
||||
# Check we got one pmux with correct number of inputs
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 1 t:$pmux
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=8 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Reusing select inputs"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [5:0] sel,
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1, w2, w3, w4, w5, w6;
|
||||
|
||||
assign w0 = sel[0] ? a[1] : a[0];
|
||||
assign w1 = sel[1] ? a[2] : w0;
|
||||
assign w2 = sel[2] ? w4 : w1;
|
||||
assign w3 = sel[3] ? w2 : w5;
|
||||
assign w4 = sel[2] ? a[3] : w6;
|
||||
assign w5 = sel[5] ? a[5] : w4;
|
||||
assign w6 = sel[4] & sel[1] ? a[7] : a[4];
|
||||
assign x = sel[4] ? a[6] : w3;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean and opt_reduce to remove unnecessary cells
|
||||
design -load postopt
|
||||
opt_clean
|
||||
opt_reduce
|
||||
|
||||
# Check we got one pmux with correct number of inputs
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 2 t:$pmux
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=3 %i
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Using outputs as select inputs"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [5:0] sel,
|
||||
input wire [7:0] a,
|
||||
output wire x
|
||||
);
|
||||
wire w0, w1, w2, w3, w4, w5, w6;
|
||||
|
||||
assign w0 = sel[0] ? a[1] : a[0];
|
||||
assign w1 = sel[1] ? a[2] : w0;
|
||||
assign w2 = sel[2] ? w4 : w1;
|
||||
assign w3 = sel[3] ? w2 : w5;
|
||||
assign w4 = sel[2] ? a[3] : w6;
|
||||
assign w5 = sel[5] ? a[5] : w4;
|
||||
assign w6 = w[2] ? a[7] : a[4];
|
||||
assign x = sel[4] ? a[6] : w3;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean and opt_reduce to remove unnecessary cells
|
||||
design -load postopt
|
||||
opt_clean
|
||||
opt_reduce
|
||||
|
||||
# Check we got one pmux with correct number of inputs
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 2 t:$pmux
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=3 %i
|
||||
select -assert-count 1 t:$pmux r:S_WIDTH=6 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Normal stress test"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [5:0] sel0,
|
||||
input wire [5:0] sel1,
|
||||
input wire [5:0] sel2,
|
||||
input wire [6:0] a0,
|
||||
input wire [6:0] a1,
|
||||
input wire [6:0] a2,
|
||||
output wire x
|
||||
);
|
||||
wire x0, x1;
|
||||
|
||||
// Stage 0
|
||||
wire s0_w0 = sel0[0] ? a0[1] : a0[0];
|
||||
wire s0_w1 = sel0[1] ? a0[2] : s0_w0;
|
||||
wire s0_w2 = sel0[2] ? a0[3] : s0_w1;
|
||||
wire s0_w4 = sel0[5] ? a0[4] : a0[5];
|
||||
wire s0_w3 = sel0[3] ? s0_w2 : s0_w4;
|
||||
assign x0 = sel0[4] ? s0_w3 : a0[6];
|
||||
|
||||
// Stage 1
|
||||
wire s1_w0 = sel1[0] ? a1[1] : a1[0];
|
||||
wire s1_w1 = sel1[1] ? a1[2] : s1_w0;
|
||||
wire s1_w2 = sel1[2] ? a1[3] : s1_w1;
|
||||
wire s1_w4 = sel1[5] ? a1[4] : a1[5];
|
||||
wire s1_w3 = sel1[3] ? s1_w2 : s1_w4;
|
||||
assign x1 = sel1[4] ? s1_w3 : x0;
|
||||
|
||||
// Stage 2
|
||||
wire s2_w0 = sel2[0] ? a2[1] : a2[0];
|
||||
wire s2_w1 = sel2[1] ? a2[2] : s2_w0;
|
||||
wire s2_w2 = sel2[2] ? a2[3] : s2_w1;
|
||||
wire s2_w4 = sel2[5] ? a2[4] : a2[5];
|
||||
wire s2_w3 = sel2[3] ? s2_w2 : s2_w4;
|
||||
assign x = sel2[4] ? s2_w3 : x1;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean and opt_reduce to remove unnecessary cells
|
||||
design -load postopt
|
||||
opt_clean
|
||||
opt_reduce
|
||||
|
||||
# Check we got one pmux with correct number of inputs
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 1 t:$pmux
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Stress test with reconverging tree and no off chain"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] sel0,
|
||||
input wire [7:0] sel1,
|
||||
input wire [7:0] sel2,
|
||||
input wire [7:0] a0,
|
||||
input wire [7:0] a1,
|
||||
input wire [7:0] a2,
|
||||
output wire x
|
||||
);
|
||||
wire x0, x1;
|
||||
|
||||
// Stage 0
|
||||
wire s0_w6 = sel0[7] ? a0[7] : a0[4];
|
||||
wire s0_w4 = sel0[6] ? a0[3] : s0_w6;
|
||||
wire s0_w5 = sel0[5] ? a0[5] : s0_w4;
|
||||
wire s0_w0 = sel0[0] ? a0[1] : a0[0];
|
||||
wire s0_w1 = sel0[1] ? a0[2] : s0_w0;
|
||||
wire s0_w2 = sel0[2] ? s0_w4 : s0_w1;
|
||||
wire s0_w3 = sel0[3] ? s0_w2 : s0_w5;
|
||||
assign x0 = sel0[4] ? a0[6] : s0_w3;
|
||||
|
||||
// Stage 1
|
||||
wire s1_w6 = sel1[7] ? a1[7] : a1[4];
|
||||
wire s1_w4 = sel1[6] ? a1[3] : s1_w6;
|
||||
wire s1_w5 = sel1[5] ? a1[5] : s1_w4;
|
||||
wire s1_w0 = sel1[0] ? a1[1] : x0;
|
||||
wire s1_w1 = sel1[1] ? a1[2] : s1_w0;
|
||||
wire s1_w2 = sel1[2] ? s1_w4 : s1_w1;
|
||||
wire s1_w3 = sel1[3] ? s1_w2 : s1_w5;
|
||||
assign x1 = sel1[4] ? a1[6] : s1_w3;
|
||||
|
||||
// Stage 2
|
||||
wire s2_w6 = sel2[7] ? a2[7] : a2[4];
|
||||
wire s2_w4 = sel2[6] ? a2[3] : s2_w6;
|
||||
wire s2_w5 = sel2[5] ? a2[5] : s2_w4;
|
||||
wire s2_w0 = sel2[0] ? a2[1] : x1;
|
||||
wire s2_w1 = sel2[1] ? a2[2] : s2_w0;
|
||||
wire s2_w2 = sel2[2] ? s2_w4 : s2_w1;
|
||||
wire s2_w3 = sel2[3] ? s2_w2 : s2_w5;
|
||||
assign x = sel2[4] ? a2[6] : s2_w3;
|
||||
endmodule
|
||||
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce
|
||||
|
||||
# Load design and run opt_clean and opt_reduce to remove unnecessary cells
|
||||
design -load postopt
|
||||
opt_clean
|
||||
opt_reduce
|
||||
|
||||
# Check we got one pmux with correct number of inputs
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 4 t:$pmux
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
|
||||
log -header "Stress test with reconverging tree and yes off chain"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] sel0,
|
||||
input wire [7:0] sel1,
|
||||
input wire [7:0] sel2,
|
||||
input wire [7:0] a0,
|
||||
input wire [7:0] a1,
|
||||
input wire [7:0] a2,
|
||||
output wire x
|
||||
);
|
||||
wire x0, x1;
|
||||
|
||||
// Stage 0
|
||||
wire s0_w6 = sel0[7] ? a0[7] : a0[4];
|
||||
wire s0_w4 = sel0[6] ? a0[3] : s0_w6;
|
||||
wire s0_w5 = sel0[5] ? a0[5] : s0_w4;
|
||||
wire s0_w0 = sel0[0] ? a0[1] : a0[0];
|
||||
wire s0_w1 = sel0[1] ? a0[2] : s0_w0;
|
||||
wire s0_w2 = sel0[2] ? s0_w4 : s0_w1;
|
||||
wire s0_w3 = sel0[3] ? s0_w2 : s0_w5;
|
||||
assign x0 = sel0[4] ? a0[6] : s0_w3;
|
||||
|
||||
// Stage 1
|
||||
wire s1_w6 = sel1[7] ? a1[7] : a1[4];
|
||||
wire s1_w4 = sel1[6] ? a1[3] : s1_w6;
|
||||
wire s1_w5 = sel1[5] ? a1[5] : s1_w4;
|
||||
wire s1_w0 = sel1[0] ? a1[1] : x0;
|
||||
wire s1_w1 = sel1[1] ? a1[2] : s1_w0;
|
||||
wire s1_w2 = sel1[2] ? s1_w4 : s1_w1;
|
||||
wire s1_w3 = sel1[3] ? s1_w2 : s1_w5;
|
||||
assign x1 = sel1[4] ? a1[6] : s1_w3;
|
||||
|
||||
// Stage 2
|
||||
wire s2_w6 = sel2[7] ? a2[7] : a2[4];
|
||||
wire s2_w4 = sel2[6] ? a2[3] : s2_w6;
|
||||
wire s2_w5 = sel2[5] ? a2[5] : s2_w4;
|
||||
wire s2_w0 = sel2[0] ? a2[1] : x1;
|
||||
wire s2_w1 = sel2[1] ? a2[2] : s2_w0;
|
||||
wire s2_w2 = sel2[2] ? s2_w4 : s2_w1;
|
||||
wire s2_w3 = sel2[3] ? s2_w2 : s2_w5;
|
||||
assign x = sel2[4] ? a2[6] : s2_w3;
|
||||
endmodule
|
||||
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
# Check equivalence after extract_reduce
|
||||
equiv_opt -assert extract_reduce -allow-off-chain
|
||||
|
||||
# Load design and run opt_clean and opt_reduce to remove unnecessary cells
|
||||
design -load postopt
|
||||
opt_clean
|
||||
opt_reduce
|
||||
|
||||
# Check we got one pmux with correct number of inputs
|
||||
select -assert-count 0 t:$mux
|
||||
select -assert-count 1 t:$pmux
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
Loading…
Reference in New Issue