mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #1317 from YosysHQ/eddie/opt_expr_shiftx
opt_expr to trim A port of $shiftx/$shift
This commit is contained in:
commit
b800059fc1
|
@ -369,7 +369,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||||
for (auto cell : module->cells())
|
for (auto cell : module->cells())
|
||||||
if (design->selected(module, cell) && cell->type[0] == '$') {
|
if (design->selected(module, cell) && cell->type[0] == '$') {
|
||||||
if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) &&
|
if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) &&
|
||||||
cell->getPort(ID::A).size() == 1 && cell->getPort(ID::Y).size() == 1)
|
GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1)
|
||||||
invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A));
|
invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A));
|
||||||
if (cell->type.in(ID($mux), ID($_MUX_)) &&
|
if (cell->type.in(ID($mux), ID($_MUX_)) &&
|
||||||
cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0))
|
cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0))
|
||||||
|
@ -740,12 +740,34 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||||
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($lt), ID($le), ID($ge), ID($gt)))
|
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($lt), ID($le), ID($ge), ID($gt)))
|
||||||
replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::State::Sx);
|
replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::State::Sx);
|
||||||
else
|
else
|
||||||
replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort(ID::Y).size()));
|
replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, GetSize(cell->getPort(ID::Y))));
|
||||||
goto next_cell;
|
goto next_cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 &&
|
if (cell->type.in(ID($shiftx), ID($shift))) {
|
||||||
|
SigSpec sig_a = assign_map(cell->getPort(ID::A));
|
||||||
|
int width;
|
||||||
|
bool trim_x = cell->type == ID($shiftx) || !keepdc;
|
||||||
|
bool trim_0 = cell->type == ID($shift);
|
||||||
|
for (width = GetSize(sig_a); width > 1; width--) {
|
||||||
|
if ((trim_x && sig_a[width-1] == State::Sx) ||
|
||||||
|
(trim_0 && sig_a[width-1] == State::S0))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width < GetSize(sig_a)) {
|
||||||
|
cover_list("opt.opt_expr.trim", "$shiftx", "$shift", cell->type.str());
|
||||||
|
sig_a.remove(width, GetSize(sig_a)-width);
|
||||||
|
cell->setPort(ID::A, sig_a);
|
||||||
|
cell->setParam(ID(A_WIDTH), width);
|
||||||
|
did_something = true;
|
||||||
|
goto next_cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && GetSize(cell->getPort(ID::Y)) == 1 &&
|
||||||
invert_map.count(assign_map(cell->getPort(ID::A))) != 0) {
|
invert_map.count(assign_map(cell->getPort(ID::A))) != 0) {
|
||||||
cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str());
|
cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str());
|
||||||
replace_cell(assign_map, module, cell, "double_invert", ID::Y, invert_map.at(assign_map(cell->getPort(ID::A))));
|
replace_cell(assign_map, module, cell, "double_invert", ID::Y, invert_map.at(assign_map(cell->getPort(ID::A))));
|
||||||
|
@ -1142,7 +1164,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||||
|
|
||||||
if (mux_undef && cell->type.in(ID($mux), ID($pmux))) {
|
if (mux_undef && cell->type.in(ID($mux), ID($pmux))) {
|
||||||
RTLIL::SigSpec new_a, new_b, new_s;
|
RTLIL::SigSpec new_a, new_b, new_s;
|
||||||
int width = cell->getPort(ID::A).size();
|
int width = GetSize(cell->getPort(ID::A));
|
||||||
if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) ||
|
if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) ||
|
||||||
cell->getPort(ID(S)).is_fully_undef()) {
|
cell->getPort(ID(S)).is_fully_undef()) {
|
||||||
cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str());
|
cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str());
|
||||||
|
|
|
@ -221,3 +221,73 @@ check
|
||||||
equiv_opt opt_expr -fine
|
equiv_opt opt_expr -fine
|
||||||
design -load postopt
|
design -load postopt
|
||||||
select -assert-count 1 t:$alu r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i
|
select -assert-count 1 t:$alu r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i
|
||||||
|
|
||||||
|
###########
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog -icells <<EOT
|
||||||
|
module opt_expr_shiftx_1bit(input [2:0] a, input [1:0] b, output y);
|
||||||
|
\$shiftx #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(2), .Y_WIDTH(1)) shiftx (.A({1'bx,a}), .B(b), .Y(y));
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
check
|
||||||
|
|
||||||
|
equiv_opt opt_expr
|
||||||
|
design -load postopt
|
||||||
|
select -assert-count 1 t:$shiftx r:A_WIDTH=3 %i
|
||||||
|
|
||||||
|
###########
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog -icells <<EOT
|
||||||
|
module opt_expr_shiftx_3bit(input [9:0] a, input [3:0] b, output [2:0] y);
|
||||||
|
\$shiftx #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(14), .B_WIDTH(4), .Y_WIDTH(3)) shiftx (.A({4'bxx00,a}), .B(b), .Y(y));
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
check
|
||||||
|
|
||||||
|
equiv_opt opt_expr
|
||||||
|
design -load postopt
|
||||||
|
select -assert-count 1 t:$shiftx r:A_WIDTH=12 %i
|
||||||
|
|
||||||
|
###########
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog -icells <<EOT
|
||||||
|
module opt_expr_shift_1bit(input [2:0] a, input [1:0] b, output y);
|
||||||
|
\$shift #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(2), .Y_WIDTH(1)) shift (.A({1'b0,a}), .B(b), .Y(y));
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
check
|
||||||
|
|
||||||
|
equiv_opt opt_expr
|
||||||
|
design -load postopt
|
||||||
|
select -assert-count 1 t:$shift r:A_WIDTH=3 %i
|
||||||
|
|
||||||
|
###########
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog -icells <<EOT
|
||||||
|
module opt_expr_shift_3bit(input [9:0] a, input [3:0] b, output [2:0] y);
|
||||||
|
\$shift #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(14), .B_WIDTH(4), .Y_WIDTH(3)) shift (.A({4'b0x0x,a}), .B(b), .Y(y));
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
check
|
||||||
|
|
||||||
|
equiv_opt opt_expr
|
||||||
|
design -load postopt
|
||||||
|
select -assert-count 1 t:$shift r:A_WIDTH=10 %i
|
||||||
|
|
||||||
|
###########
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog -icells <<EOT
|
||||||
|
module opt_expr_shift_3bit_keepdc(input [9:0] a, input [3:0] b, output [2:0] y);
|
||||||
|
\$shift #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(14), .B_WIDTH(4), .Y_WIDTH(3)) shift (.A({4'b0x0x,a}), .B(b), .Y(y));
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
check
|
||||||
|
|
||||||
|
equiv_opt opt_expr -keepdc
|
||||||
|
design -load postopt
|
||||||
|
select -assert-count 1 t:$shift r:A_WIDTH=13 %i
|
||||||
|
|
Loading…
Reference in New Issue