3
0
Fork 0
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:
Martin Povišer 2025-03-10 16:28:16 +01:00
parent c439f8c770
commit 947ca842f9
2 changed files with 51 additions and 3 deletions

View file

@ -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 {

View file

@ -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);