mirror of https://github.com/YosysHQ/yosys.git
parent
a24906a7d2
commit
98003430d6
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/register.h"
|
#include "kernel/register.h"
|
||||||
|
#include "kernel/ffinit.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/log.h"
|
#include "kernel/log.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
|
@ -35,7 +36,7 @@ struct OptMergeWorker
|
||||||
RTLIL::Design *design;
|
RTLIL::Design *design;
|
||||||
RTLIL::Module *module;
|
RTLIL::Module *module;
|
||||||
SigMap assign_map;
|
SigMap assign_map;
|
||||||
SigMap dff_init_map;
|
FfInitVals initvals;
|
||||||
bool mode_share_all;
|
bool mode_share_all;
|
||||||
|
|
||||||
CellTypes ct;
|
CellTypes ct;
|
||||||
|
@ -121,8 +122,7 @@ struct OptMergeWorker
|
||||||
if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type)) {
|
if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type)) {
|
||||||
// For the 'Q' output of state elements,
|
// For the 'Q' output of state elements,
|
||||||
// use its (* init *) attribute value
|
// use its (* init *) attribute value
|
||||||
for (const auto &b : dff_init_map(it.second))
|
sig = initvals(it.second);
|
||||||
sig.append(b.wire ? State::Sx : b);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
@ -176,12 +176,8 @@ struct OptMergeWorker
|
||||||
if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell1->type)) {
|
if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell1->type)) {
|
||||||
// For the 'Q' output of state elements,
|
// For the 'Q' output of state elements,
|
||||||
// use the (* init *) attribute value
|
// use the (* init *) attribute value
|
||||||
auto &sig1 = conn1[it.first];
|
conn1[it.first] = initvals(it.second);
|
||||||
for (const auto &b : dff_init_map(it.second))
|
conn2[it.first] = initvals(cell2->getPort(it.first));
|
||||||
sig1.append(b.wire ? State::Sx : b);
|
|
||||||
auto &sig2 = conn2[it.first];
|
|
||||||
for (const auto &b : dff_init_map(cell2->getPort(it.first)))
|
|
||||||
sig2.append(b.wire ? State::Sx : b);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
conn1[it.first] = RTLIL::SigSpec();
|
conn1[it.first] = RTLIL::SigSpec();
|
||||||
|
@ -247,14 +243,7 @@ struct OptMergeWorker
|
||||||
log("Finding identical cells in module `%s'.\n", module->name.c_str());
|
log("Finding identical cells in module `%s'.\n", module->name.c_str());
|
||||||
assign_map.set(module);
|
assign_map.set(module);
|
||||||
|
|
||||||
dff_init_map.set(module);
|
initvals.set(&assign_map, module);
|
||||||
for (auto &it : module->wires_)
|
|
||||||
if (it.second->attributes.count(ID::init) != 0) {
|
|
||||||
Const initval = it.second->attributes.at(ID::init);
|
|
||||||
for (int i = 0; i < GetSize(initval) && i < GetSize(it.second); i++)
|
|
||||||
if (initval[i] == State::S0 || initval[i] == State::S1)
|
|
||||||
dff_init_map.add(SigBit(it.second, i), initval[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool did_something = true;
|
bool did_something = true;
|
||||||
while (did_something)
|
while (did_something)
|
||||||
|
@ -296,16 +285,8 @@ struct OptMergeWorker
|
||||||
module->connect(RTLIL::SigSig(it.second, other_sig));
|
module->connect(RTLIL::SigSig(it.second, other_sig));
|
||||||
assign_map.add(it.second, other_sig);
|
assign_map.add(it.second, other_sig);
|
||||||
|
|
||||||
if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type)) {
|
if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type))
|
||||||
for (auto c : it.second.chunks()) {
|
initvals.remove_init(it.second);
|
||||||
auto jt = c.wire->attributes.find(ID::init);
|
|
||||||
if (jt == c.wire->attributes.end())
|
|
||||||
continue;
|
|
||||||
for (int i = c.offset; i < c.offset + c.width; i++)
|
|
||||||
jt->second[i] = State::Sx;
|
|
||||||
}
|
|
||||||
dff_init_map.add(it.second, Const(State::Sx, GetSize(it.second)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str());
|
log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str());
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
read_ilang <<EOT
|
||||||
|
|
||||||
|
module \mod
|
||||||
|
wire input 1 \clk
|
||||||
|
attribute \init 2'00
|
||||||
|
wire width 2 $q1
|
||||||
|
attribute \init 2'00
|
||||||
|
wire width 2 $q2
|
||||||
|
wire output 2 width 4 \q
|
||||||
|
cell $dff $ff1
|
||||||
|
parameter \CLK_POLARITY 1'1
|
||||||
|
parameter \WIDTH 1
|
||||||
|
connect \CLK \clk
|
||||||
|
connect \D 1'0
|
||||||
|
connect \Q $q1 [0]
|
||||||
|
end
|
||||||
|
cell $dff $ff2
|
||||||
|
parameter \CLK_POLARITY 1'1
|
||||||
|
parameter \WIDTH 1
|
||||||
|
connect \CLK \clk
|
||||||
|
connect \D 1'0
|
||||||
|
connect \Q $q2 [0]
|
||||||
|
end
|
||||||
|
cell $dff $ff3
|
||||||
|
parameter \CLK_POLARITY 1'1
|
||||||
|
parameter \WIDTH 2
|
||||||
|
connect \CLK \clk
|
||||||
|
connect \D 2'00
|
||||||
|
connect \Q { $q1 [1] $q2 [1] }
|
||||||
|
end
|
||||||
|
connect \q [0] $q1 [0]
|
||||||
|
connect \q [1] $q2 [0]
|
||||||
|
connect \q [2] $q1 [1]
|
||||||
|
connect \q [3] $q2 [1]
|
||||||
|
end
|
||||||
|
|
||||||
|
EOT
|
||||||
|
|
||||||
|
opt_clean
|
||||||
|
opt_merge
|
||||||
|
opt_dff
|
||||||
|
opt_clean
|
|
@ -48,7 +48,7 @@ EOT
|
||||||
|
|
||||||
opt_merge
|
opt_merge
|
||||||
select -assert-count 1 t:$dff
|
select -assert-count 1 t:$dff
|
||||||
select -assert-count 1 a:init=2'bx1
|
select -assert-count 1 a:init=2'bx1 a:init=2'b1x
|
||||||
|
|
||||||
|
|
||||||
design -reset
|
design -reset
|
||||||
|
|
Loading…
Reference in New Issue