3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-18 06:39:03 +00:00

ql_dsp_io_regs: Add DSPv2 support, adjust sim model

Add support for cell type dispatching of the new DSP block; adjust the
definition of MULT and MULTACC variants to support those instances
starting a cascading chain.
This commit is contained in:
Martin Povišer 2025-03-11 16:35:38 +01:00
parent 0180e8f30f
commit 0d484818a7
2 changed files with 185 additions and 17 deletions

View file

@ -44,20 +44,32 @@ struct QlDspIORegs : public Pass {
log("\n");
log("This pass looks for QL_DSP2 cells and changes their cell type depending on their\n");
log("configuration.\n");
log("\n");
log(" -dspv2\n");
log(" target DSPv2.\n");
log("\n");
}
void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override
{
log_header(a_Design, "Executing QL_DSP_IO_REGS pass.\n");
bool target_dspv2 = false;
size_t argidx;
for (argidx = 1; argidx < a_Args.size(); argidx++) {
if (a_Args[argidx] == "-dspv2") {
target_dspv2 = true;
continue;
}
break;
}
extra_args(a_Args, argidx, a_Design);
for (auto module : a_Design->selected_modules()) {
ql_dsp_io_regs_pass(module);
if (target_dspv2)
ql_dsp_io_regs_pass_v2(module);
else
ql_dsp_io_regs_pass(module);
}
}
@ -153,6 +165,146 @@ struct QlDspIORegs : public Pass {
}
}
}
void ql_dsp_io_regs_pass_v2(Module *module)
{
sigmap.set(module);
for (auto cell : module->cells()) {
if (cell->type != ID(QL_DSPV2))
continue;
// If the cell does not have the "is_inferred" attribute set
// then don't touch it.
if (!cell->get_bool_attribute(ID(is_inferred)))
continue;
if (!cell->hasPort(ID(output_select)) ||
!sigmap(cell->getPort(ID(output_select))).is_fully_def() ||
!cell->hasParam(ID(MODE_BITS)) ||
cell->getParam(ID(MODE_BITS)).size() != 72) {
log_error("Missing configuration tie-offs or parameters on DSP cell %s\n",
log_id(cell));
}
int out_sel_i = sigmap(cell->getPort(ID(output_select))).as_int();
Const mode = cell->getParam(ID(MODE_BITS));
// Get the feedback port
if (!cell->hasPort(ID(feedback)))
log_error("Missing 'feedback' port on %s", log_id(cell));
SigSpec feedback = sigmap(cell->getPort(ID(feedback)));
bool a_reg = mode[61] != RTLIL::S0;
bool b_reg = mode[63] != RTLIL::S0;
// Build new type name
std::string new_type = "\\QL_DSPV2_MULT";
// Decide if we should be deleting the clock port
bool del_clk = true;
if (a_reg != b_reg) {
// no specialized type for mixed scenario
continue;
}
enum {
MULT,
MULTADD,
MULTACC,
Unrecognized
} base_function = Unrecognized;
switch (out_sel_i) {
case 0:
case 4:
base_function = MULT;
break;
case 1:
case 5:
case 2:
case 3:
case 6:
case 7:
if (feedback.is_fully_def() && (feedback.as_int() == 2 || feedback.as_int() == 3)) {
del_clk = false;
new_type += "ADD";
base_function = MULTADD;
break;
} else if (feedback.extract(1, 2).is_fully_zero()) {
del_clk = false;
new_type += "ACC";
base_function = MULTACC;
break;
} else {
base_function = Unrecognized;
}
break;
default:
break;
}
if (base_function == Unrecognized) {
continue;
}
if (a_reg && b_reg) {
del_clk = false;
new_type += "_REGIN";
}
if (out_sel_i > 3) {
del_clk = false;
new_type += "_REGOUT";
}
// Set new type name
log_debug("Converted %s to %s\n", log_id(cell->type), new_type.c_str());
cell->type = RTLIL::IdString(new_type);
std::vector<std::string> ports2del;
if (del_clk) {
cell->unsetPort(ID(clk));
cell->unsetPort(ID(reset));
}
switch (base_function) {
case MULTACC: {
static const std::vector<IdString> to_del = {
ID(c), ID(a_cin), ID(b_cin), ID(z_cin),
ID(a_cout), ID(b_cout)
};
for (auto port : to_del)
cell->unsetPort(port);
break;
}
case MULTADD: {
static const std::vector<IdString> to_del = {
ID(c), ID(a_cin), ID(b_cin), ID(a_cout), ID(b_cout)
};
for (auto port : to_del)
cell->unsetPort(port);
break;
}
case MULT: {
static const std::vector<IdString> to_del = {
ID(c), ID(load_acc), ID(acc_reset),
ID(a_cin), ID(b_cin), ID(z_cin), ID(a_cout), ID(b_cout)
};
for (auto port : to_del)
cell->unsetPort(port);
break;
}
default:
;
}
}
}
} QlDspIORegs;
PRIVATE_NAMESPACE_END

View file

@ -214,7 +214,9 @@ module QL_DSPV2_MULT (
output wire [49:0] z,
input wire [2:0] feedback,
input wire [2:0] output_select
input wire [2:0] output_select,
output wire [49:0] z_cout
);
parameter [71:0] MODE_BITS = 72'h000000000000000000;
@ -257,7 +259,7 @@ module QL_DSPV2_MULT (
.b_cin(),
.z_cin(),
.z_cout(),
.z_cout(z_cout),
.a_cout(),
.b_cout()
);
@ -274,7 +276,9 @@ module QL_DSPV2_MULT_REGIN (
input wire reset,
input wire [2:0] feedback,
input wire [2:0] output_select
input wire [2:0] output_select,
output wire [49:0] z_cout
);
parameter [71:0] MODE_BITS = 72'h00A000000000000000;
@ -317,7 +321,7 @@ module QL_DSPV2_MULT_REGIN (
.b_cin(),
.z_cin(),
.z_cout(),
.z_cout(z_cout),
.a_cout(),
.b_cout()
);
@ -334,7 +338,9 @@ module QL_DSPV2_MULT_REGOUT (
input wire reset,
input wire [2:0] feedback,
input wire [2:0] output_select
input wire [2:0] output_select,
output wire [49:0] z_cout
);
parameter [71:0] MODE_BITS = 72'h000000000000000000;
@ -377,7 +383,7 @@ module QL_DSPV2_MULT_REGOUT (
.b_cin(),
.z_cin(),
.z_cout(),
.z_cout(z_cout),
.a_cout(),
.b_cout()
);
@ -394,7 +400,9 @@ module QL_DSPV2_MULT_REGIN_REGOUT (
input wire reset,
input wire [2:0] feedback,
input wire [2:0] output_select
input wire [2:0] output_select,
output wire [49:0] z_cout
);
parameter [71:0] MODE_BITS = 72'h00A000000000000000;
@ -437,7 +445,7 @@ module QL_DSPV2_MULT_REGIN_REGOUT (
.b_cin(),
.z_cin(),
.z_cout(),
.z_cout(z_cout),
.a_cout(),
.b_cout()
);
@ -715,7 +723,9 @@ module QL_DSPV2_MULTACC (
input wire acc_reset,
input wire load_acc,
input wire [ 2:0] feedback,
input wire [ 2:0] output_select
input wire [ 2:0] output_select,
output wire [49:0] z_cout
);
parameter [71:0] MODE_BITS = 72'h000000000000000000;
@ -758,7 +768,7 @@ module QL_DSPV2_MULTACC (
.b_cin(),
.z_cin(),
.z_cout(),
.z_cout(z_cout),
.a_cout(),
.b_cout()
);
@ -776,7 +786,9 @@ module QL_DSPV2_MULTACC_REGIN (
input wire acc_reset,
input wire load_acc,
input wire [ 2:0] feedback,
input wire [ 2:0] output_select
input wire [ 2:0] output_select,
output wire [49:0] z_cout
);
parameter [71:0] MODE_BITS = 72'h004000000000000000;
@ -819,7 +831,7 @@ module QL_DSPV2_MULTACC_REGIN (
.b_cin(),
.z_cin(),
.z_cout(),
.z_cout(z_cout),
.a_cout(),
.b_cout()
);
@ -837,7 +849,9 @@ module QL_DSPV2_MULTACC_REGOUT (
input wire acc_reset,
input wire load_acc,
input wire [ 2:0] feedback,
input wire [ 2:0] output_select
input wire [ 2:0] output_select,
output wire [49:0] z_cout
);
parameter [71:0] MODE_BITS = 72'h000000000000000000;
@ -880,7 +894,7 @@ module QL_DSPV2_MULTACC_REGOUT (
.b_cin(),
.z_cin(),
.z_cout(),
.z_cout(z_cout),
.a_cout(),
.b_cout()
);
@ -898,7 +912,9 @@ module QL_DSPV2_MULTACC_REGIN_REGOUT (
input wire acc_reset,
input wire load_acc,
input wire [ 2:0] feedback,
input wire [ 2:0] output_select
input wire [ 2:0] output_select,
output wire [49:0] z_cout
);
parameter [71:0] MODE_BITS = 72'h004000000000000000;
@ -941,7 +957,7 @@ module QL_DSPV2_MULTACC_REGIN_REGOUT (
.b_cin(),
.z_cin(),
.z_cout(),
.z_cout(z_cout),
.a_cout(),
.b_cout()
);