mirror of https://github.com/YosysHQ/yosys.git
opt_lut: eliminate LUTs evaluating to constants or inputs.
This commit is contained in:
parent
0a840dd883
commit
42c356c49c
|
@ -187,6 +187,87 @@ struct OptLutWorker
|
|||
}
|
||||
show_stats_by_arity();
|
||||
|
||||
log("\n");
|
||||
log("Eliminating LUTs.\n");
|
||||
for (auto lut : luts)
|
||||
{
|
||||
SigSpec lut_input = sigmap(lut->getPort("\\A"));
|
||||
pool<int> &lut_dlogic_inputs = luts_dlogic_inputs[lut];
|
||||
|
||||
vector<SigBit> lut_inputs;
|
||||
for (auto &bit : lut_input)
|
||||
{
|
||||
if (bit.wire)
|
||||
lut_inputs.push_back(sigmap(bit));
|
||||
}
|
||||
|
||||
bool const0_match = true;
|
||||
bool const1_match = true;
|
||||
vector<bool> input_matches;
|
||||
for (size_t i = 0; i < lut_inputs.size(); i++)
|
||||
input_matches.push_back(true);
|
||||
|
||||
for (int eval = 0; eval < 1 << lut_inputs.size(); eval++)
|
||||
{
|
||||
dict<SigBit, bool> eval_inputs;
|
||||
for (size_t i = 0; i < lut_inputs.size(); i++)
|
||||
eval_inputs[lut_inputs[i]] = (eval >> i) & 1;
|
||||
bool value = evaluate_lut(lut, eval_inputs);
|
||||
if (value != 0)
|
||||
const0_match = false;
|
||||
if (value != 1)
|
||||
const1_match = false;
|
||||
for (size_t i = 0; i < lut_inputs.size(); i++)
|
||||
{
|
||||
if (value != eval_inputs[lut_inputs[i]])
|
||||
input_matches[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
int input_match = -1;
|
||||
for (size_t i = 0; i < lut_inputs.size(); i++)
|
||||
if (input_matches[i])
|
||||
input_match = i;
|
||||
|
||||
if (const0_match || const1_match || input_match != -1)
|
||||
{
|
||||
log("Found redundant cell %s.%s.\n", log_id(module), log_id(lut));
|
||||
|
||||
SigBit value;
|
||||
if (const0_match)
|
||||
{
|
||||
log(" Cell evaluates constant 0.\n");
|
||||
value = State::S0;
|
||||
}
|
||||
if (const1_match)
|
||||
{
|
||||
log(" Cell evaluates constant 1.\n");
|
||||
value = State::S1;
|
||||
}
|
||||
if (input_match != -1) {
|
||||
log(" Cell evaluates signal %s.\n", log_signal(lut_inputs[input_match]));
|
||||
value = lut_inputs[input_match];
|
||||
}
|
||||
|
||||
if (lut_dlogic_inputs.size())
|
||||
{
|
||||
log(" Not eliminating cell (connected to dedicated logic).\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
SigSpec lut_output = lut->getPort("\\Y");
|
||||
module->connect(lut_output, value);
|
||||
|
||||
module->remove(lut);
|
||||
luts.erase(lut);
|
||||
luts_arity.erase(lut);
|
||||
luts_dlogics.erase(lut);
|
||||
luts_dlogic_inputs.erase(lut);
|
||||
}
|
||||
}
|
||||
}
|
||||
show_stats_by_arity();
|
||||
|
||||
log("\n");
|
||||
log("Combining LUTs.\n");
|
||||
pool<RTLIL::Cell*> worklist = luts;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
module \test
|
||||
wire input 1 \i
|
||||
|
||||
wire output 2 \o1
|
||||
cell $lut $1
|
||||
parameter \LUT 16'0110100110010110
|
||||
parameter \WIDTH 4
|
||||
connect \A { \i 3'000 }
|
||||
connect \Y \o1
|
||||
end
|
||||
|
||||
wire output 2 \o2
|
||||
cell $lut $2
|
||||
parameter \LUT 16'0110100010010110
|
||||
parameter \WIDTH 4
|
||||
connect \A { \i 3'000 }
|
||||
connect \Y \o2
|
||||
end
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
read_ilang opt_lut_elim.il
|
||||
opt_lut
|
||||
select -assert-count 0 t:$lut
|
|
@ -1,2 +1,3 @@
|
|||
read_ilang opt_lut_port.il
|
||||
opt_lut
|
||||
select -assert-count 2 t:$lut
|
||||
|
|
Loading…
Reference in New Issue