mirror of
https://github.com/YosysHQ/yosys
synced 2025-05-14 11:14:44 +00:00
134 lines
3.7 KiB
C++
134 lines
3.7 KiB
C++
/*
|
|
* yosys -- Yosys Open SYnthesis Suite
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
*/
|
|
|
|
#include "kernel/rtlil.h"
|
|
#include "kernel/register.h"
|
|
#include "kernel/sigtools.h"
|
|
|
|
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);
|
|
|
|
auto uses_port = [&](IdString port_name) {
|
|
return cell->hasPort(port_name) && !cell->getPort(port_name).is_fully_undef();
|
|
};
|
|
|
|
if (uses_port(ID(a_cin_i)) || uses_port(ID(b_cin_i)) || uses_port(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;
|
|
}
|
|
|
|
bool did_something;
|
|
|
|
#include "ql_dsp_pm.h"
|
|
|
|
struct QlDspPass : Pass {
|
|
QlDspPass() : Pass("ql_dsp", "pack into QuickLogic DSPs") {}
|
|
|
|
void help() override
|
|
{
|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
|
log("\n");
|
|
log(" ql_dsp [selection]\n");
|
|
log("\n");
|
|
log("This pass packs input and output path registers into QuickLogic DSP blocks,\n");
|
|
log("additionally it supports Z path cascading and post-adder packing.\n");
|
|
log("\n");
|
|
log(" -nocascade\n");
|
|
log(" forbid cascading\n");
|
|
log("\n");
|
|
|
|
}
|
|
|
|
void execute(std::vector<std::string> args, RTLIL::Design *d) override
|
|
{
|
|
log_header(d, "Executing QL_DSP pass. (pack into QuickLogic DSPs)\n");
|
|
|
|
bool nocascade = false;
|
|
size_t argidx;
|
|
for (argidx = 1; argidx < args.size(); argidx++) {
|
|
if (args[argidx] == "-nocascade") {
|
|
nocascade = true;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
extra_args(args, argidx, d);
|
|
|
|
for (auto module : d->selected_modules()) {
|
|
did_something = true;
|
|
|
|
while (did_something)
|
|
{
|
|
// TODO: could be optimized by more reuse of the pmgen object
|
|
did_something = false;
|
|
{
|
|
ql_dsp_pm pm(module, module->selected_cells());
|
|
pm.run_ql_dsp_pack_regs();
|
|
}
|
|
if (!nocascade) {
|
|
ql_dsp_pm pm(module, module->selected_cells());
|
|
pm.run_ql_dsp_cascade();
|
|
}
|
|
{
|
|
ql_dsp_pm pm(module, module->selected_cells());
|
|
pm.run_ql_dsp_pack_regs();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} QlDspPass;
|
|
|
|
PRIVATE_NAMESPACE_END
|