mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-18 06:39:03 +00:00
ql_dsp: Add promotion on cascading
This commit is contained in:
parent
c439f8c770
commit
947ca842f9
|
@ -22,6 +22,50 @@
|
|||
PRIVATE_NAMESPACE_BEGIN
|
||||
USING_YOSYS_NAMESPACE
|
||||
|
||||
// promote dspv2_16x9x32_cfg_ports to dspv2_32x18x64_cfg_ports if need be
|
||||
bool promote(Module *m, Cell *cell) {
|
||||
if (cell->type == ID(dspv2_32x18x64_cfg_ports)) {
|
||||
return false;
|
||||
} else {
|
||||
log_assert(cell->type == ID(dspv2_16x9x32_cfg_ports));
|
||||
}
|
||||
|
||||
auto widen_output = [&](IdString port_name, int new_width) {
|
||||
if (!cell->hasPort(port_name))
|
||||
return;
|
||||
SigSpec port = cell->getPort(port_name);
|
||||
if (port.size() < new_width) {
|
||||
port = {m->addWire(NEW_ID, new_width - port.size()), port};
|
||||
cell->setPort(port_name, port);
|
||||
}
|
||||
};
|
||||
|
||||
auto widen_input = [&](IdString port_name, int new_width) {
|
||||
if (!cell->hasPort(port_name))
|
||||
return;
|
||||
SigSpec port = cell->getPort(port_name);
|
||||
if (port.size() < new_width) {
|
||||
port.extend_u0(new_width, /* is_signed= */ true);
|
||||
cell->setPort(port_name, port);
|
||||
}
|
||||
};
|
||||
|
||||
widen_output(ID(z_o), 50);
|
||||
widen_output(ID(a_cout_o), 32);
|
||||
widen_output(ID(b_cout_o), 18);
|
||||
widen_output(ID(z_cout_o), 50);
|
||||
|
||||
if (cell->hasPort(ID(a_cin_i)) || cell->hasPort(ID(b_cin_i)) || cell->hasPort(ID(z_cin_i))) {
|
||||
log_error("Cannot promote %s (type %s) with cascading paths\n", log_id(cell), log_id(cell->type));
|
||||
}
|
||||
|
||||
widen_input(ID(a_i), 32);
|
||||
widen_input(ID(b_i), 18);
|
||||
widen_input(ID(c_i), 18);
|
||||
cell->type = ID(dspv2_32x18x64_cfg_ports);
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "ql_dsp_pm.h"
|
||||
|
||||
struct QlDspPass : Pass {
|
||||
|
|
|
@ -11,7 +11,7 @@ udata <SigBit> dffclock dffreset
|
|||
udata <Cell*> dff
|
||||
|
||||
match dsp
|
||||
select dsp->type == \dspv2_32x18x64_cfg_ports
|
||||
select dsp->type.in(\dspv2_32x18x64_cfg_ports, \dspv2_16x9x32_cfg_ports)
|
||||
endmatch
|
||||
|
||||
code clock_inferred clock reset
|
||||
|
@ -209,12 +209,12 @@ endcode
|
|||
pattern ql_dsp_cascade
|
||||
|
||||
match dsp1
|
||||
select dsp1->type == \dspv2_32x18x64_cfg_ports
|
||||
select dsp1->type.in(\dspv2_32x18x64_cfg_ports, \dspv2_16x9x32_cfg_ports)
|
||||
filter !dsp1->hasPort(\z_cout_o) || nusers(port(dsp1, \z_cout_o)) == 1
|
||||
endmatch
|
||||
|
||||
match dsp2
|
||||
select dsp2->type == \dspv2_32x18x64_cfg_ports
|
||||
select dsp2->type.in(\dspv2_32x18x64_cfg_ports, \dspv2_16x9x32_cfg_ports)
|
||||
filter port(dsp2, \output_select_i).is_fully_const()
|
||||
define <int> output_sel port(dsp2, \output_select_i).as_int()
|
||||
filter output_sel == 3 || (output_sel == 4 && !param(dsp2, \M_REG).as_bool())
|
||||
|
@ -243,6 +243,10 @@ code
|
|||
const int z_width = 50;
|
||||
|
||||
log("%s: inferring post-adder from %s (type %s)\n", log_id(dsp2), log_id(add), log_id(add->type));
|
||||
if (promote(module, dsp1))
|
||||
log(" - promoting %s to non-fractured DSP block\n", log_id(dsp1));
|
||||
if (promote(module, dsp2))
|
||||
log(" - promoting %s to non-fractured DSP block\n", log_id(dsp2));
|
||||
|
||||
// link up z_cout_o of dsp1 to z_cin_i of dsp2
|
||||
Wire *link = module->addWire(NEW_ID, z_width);
|
||||
|
|
Loading…
Reference in a new issue