summaryrefslogtreecommitdiff
path: root/passes/pmgen/ice40_dsp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'passes/pmgen/ice40_dsp.cc')
-rw-r--r--passes/pmgen/ice40_dsp.cc117
1 files changed, 60 insertions, 57 deletions
diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc
index 3a054a46..39d033a0 100644
--- a/passes/pmgen/ice40_dsp.cc
+++ b/passes/pmgen/ice40_dsp.cc
@@ -19,47 +19,50 @@
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
-#include "passes/pmgen/ice40_dsp_pm.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
+#include "passes/pmgen/ice40_dsp_pm.h"
+
void create_ice40_dsp(ice40_dsp_pm &pm)
{
+ auto &st = pm.st_ice40_dsp;
+
#if 0
log("\n");
- log("ffA: %s\n", log_id(pm.st.ffA, "--"));
- log("ffB: %s\n", log_id(pm.st.ffB, "--"));
- log("mul: %s\n", log_id(pm.st.mul, "--"));
- log("ffY: %s\n", log_id(pm.st.ffY, "--"));
- log("addAB: %s\n", log_id(pm.st.addAB, "--"));
- log("muxAB: %s\n", log_id(pm.st.muxAB, "--"));
- log("ffS: %s\n", log_id(pm.st.ffS, "--"));
+ log("ffA: %s\n", log_id(st.ffA, "--"));
+ log("ffB: %s\n", log_id(st.ffB, "--"));
+ log("mul: %s\n", log_id(st.mul, "--"));
+ log("ffY: %s\n", log_id(st.ffY, "--"));
+ log("addAB: %s\n", log_id(st.addAB, "--"));
+ log("muxAB: %s\n", log_id(st.muxAB, "--"));
+ log("ffS: %s\n", log_id(st.ffS, "--"));
#endif
- log("Checking %s.%s for iCE40 DSP inference.\n", log_id(pm.module), log_id(pm.st.mul));
+ log("Checking %s.%s for iCE40 DSP inference.\n", log_id(pm.module), log_id(st.mul));
- if (GetSize(pm.st.sigA) > 16) {
- log(" input A (%s) is too large (%d > 16).\n", log_signal(pm.st.sigA), GetSize(pm.st.sigA));
+ if (GetSize(st.sigA) > 16) {
+ log(" input A (%s) is too large (%d > 16).\n", log_signal(st.sigA), GetSize(st.sigA));
return;
}
- if (GetSize(pm.st.sigB) > 16) {
- log(" input B (%s) is too large (%d > 16).\n", log_signal(pm.st.sigB), GetSize(pm.st.sigB));
+ if (GetSize(st.sigB) > 16) {
+ log(" input B (%s) is too large (%d > 16).\n", log_signal(st.sigB), GetSize(st.sigB));
return;
}
- if (GetSize(pm.st.sigS) > 32) {
- log(" accumulator (%s) is too large (%d > 32).\n", log_signal(pm.st.sigS), GetSize(pm.st.sigS));
+ if (GetSize(st.sigS) > 32) {
+ log(" accumulator (%s) is too large (%d > 32).\n", log_signal(st.sigS), GetSize(st.sigS));
return;
}
- if (GetSize(pm.st.sigY) > 32) {
- log(" output (%s) is too large (%d > 32).\n", log_signal(pm.st.sigY), GetSize(pm.st.sigY));
+ if (GetSize(st.sigY) > 32) {
+ log(" output (%s) is too large (%d > 32).\n", log_signal(st.sigY), GetSize(st.sigY));
return;
}
- bool mul_signed = pm.st.mul->getParam("\\A_SIGNED").as_bool();
+ bool mul_signed = st.mul->getParam("\\A_SIGNED").as_bool();
if (mul_signed) {
log(" inference of signed iCE40 DSP arithmetic is currently not supported.\n");
@@ -69,21 +72,21 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
log(" replacing $mul with SB_MAC16 cell.\n");
Cell *cell = pm.module->addCell(NEW_ID, "\\SB_MAC16");
- pm.module->swap_names(cell, pm.st.mul);
+ pm.module->swap_names(cell, st.mul);
// SB_MAC16 Input Interface
- SigSpec A = pm.st.sigA;
+ SigSpec A = st.sigA;
A.extend_u0(16, mul_signed);
- SigSpec B = pm.st.sigB;
+ SigSpec B = st.sigB;
B.extend_u0(16, mul_signed);
SigSpec CD;
- if (pm.st.muxA)
- CD = pm.st.muxA->getPort("\\B");
- if (pm.st.muxB)
- CD = pm.st.muxB->getPort("\\A");
+ if (st.muxA)
+ CD = st.muxA->getPort("\\B");
+ if (st.muxB)
+ CD = st.muxB->getPort("\\A");
CD.extend_u0(32, mul_signed);
cell->setPort("\\A", A);
@@ -91,8 +94,8 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
cell->setPort("\\C", CD.extract(0, 16));
cell->setPort("\\D", CD.extract(16, 16));
- cell->setParam("\\A_REG", pm.st.ffA ? State::S1 : State::S0);
- cell->setParam("\\B_REG", pm.st.ffB ? State::S1 : State::S0);
+ cell->setParam("\\A_REG", st.ffA ? State::S1 : State::S0);
+ cell->setParam("\\B_REG", st.ffB ? State::S1 : State::S0);
cell->setPort("\\AHOLD", State::S0);
cell->setPort("\\BHOLD", State::S0);
@@ -102,25 +105,25 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
cell->setPort("\\IRSTTOP", State::S0);
cell->setPort("\\IRSTBOT", State::S0);
- if (pm.st.clock_vld)
+ if (st.clock_vld)
{
- cell->setPort("\\CLK", pm.st.clock);
+ cell->setPort("\\CLK", st.clock);
cell->setPort("\\CE", State::S1);
- cell->setParam("\\NEG_TRIGGER", pm.st.clock_pol ? State::S0 : State::S1);
+ cell->setParam("\\NEG_TRIGGER", st.clock_pol ? State::S0 : State::S1);
- log(" clock: %s (%s)", log_signal(pm.st.clock), pm.st.clock_pol ? "posedge" : "negedge");
+ log(" clock: %s (%s)", log_signal(st.clock), st.clock_pol ? "posedge" : "negedge");
- if (pm.st.ffA)
- log(" ffA:%s", log_id(pm.st.ffA));
+ if (st.ffA)
+ log(" ffA:%s", log_id(st.ffA));
- if (pm.st.ffB)
- log(" ffB:%s", log_id(pm.st.ffB));
+ if (st.ffB)
+ log(" ffB:%s", log_id(st.ffB));
- if (pm.st.ffY)
- log(" ffY:%s", log_id(pm.st.ffY));
+ if (st.ffY)
+ log(" ffY:%s", log_id(st.ffY));
- if (pm.st.ffS)
- log(" ffS:%s", log_id(pm.st.ffS));
+ if (st.ffS)
+ log(" ffS:%s", log_id(st.ffS));
log("\n");
}
@@ -144,16 +147,16 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
// SB_MAC16 Output Interface
- SigSpec O = pm.st.ffS ? pm.st.sigS : pm.st.sigY;
+ SigSpec O = st.ffS ? st.sigS : st.sigY;
if (GetSize(O) < 32)
O.append(pm.module->addWire(NEW_ID, 32-GetSize(O)));
cell->setPort("\\O", O);
- if (pm.st.addAB) {
- log(" accumulator %s (%s)\n", log_id(pm.st.addAB), log_id(pm.st.addAB->type));
- cell->setPort("\\ADDSUBTOP", pm.st.addAB->type == "$add" ? State::S0 : State::S1);
- cell->setPort("\\ADDSUBBOT", pm.st.addAB->type == "$add" ? State::S0 : State::S1);
+ if (st.addAB) {
+ log(" accumulator %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type));
+ cell->setPort("\\ADDSUBTOP", st.addAB->type == "$add" ? State::S0 : State::S1);
+ cell->setPort("\\ADDSUBBOT", st.addAB->type == "$add" ? State::S0 : State::S1);
} else {
cell->setPort("\\ADDSUBTOP", State::S0);
cell->setPort("\\ADDSUBBOT", State::S0);
@@ -166,10 +169,10 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
cell->setPort("\\OHOLDBOT", State::S0);
SigSpec acc_reset = State::S0;
- if (pm.st.muxA)
- acc_reset = pm.st.muxA->getPort("\\S");
- if (pm.st.muxB)
- acc_reset = pm.module->Not(NEW_ID, pm.st.muxB->getPort("\\S"));
+ if (st.muxA)
+ acc_reset = st.muxA->getPort("\\S");
+ if (st.muxB)
+ acc_reset = pm.module->Not(NEW_ID, st.muxB->getPort("\\S"));
cell->setPort("\\OLOADTOP", acc_reset);
cell->setPort("\\OLOADBOT", acc_reset);
@@ -179,17 +182,17 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
cell->setParam("\\C_REG", State::S0);
cell->setParam("\\D_REG", State::S0);
- cell->setParam("\\TOP_8x8_MULT_REG", pm.st.ffY ? State::S1 : State::S0);
- cell->setParam("\\BOT_8x8_MULT_REG", pm.st.ffY ? State::S1 : State::S0);
- cell->setParam("\\PIPELINE_16x16_MULT_REG1", pm.st.ffY ? State::S1 : State::S0);
+ cell->setParam("\\TOP_8x8_MULT_REG", st.ffY ? State::S1 : State::S0);
+ cell->setParam("\\BOT_8x8_MULT_REG", st.ffY ? State::S1 : State::S0);
+ cell->setParam("\\PIPELINE_16x16_MULT_REG1", st.ffY ? State::S1 : State::S0);
cell->setParam("\\PIPELINE_16x16_MULT_REG2", State::S0);
- cell->setParam("\\TOPOUTPUT_SELECT", Const(pm.st.ffS ? 1 : 3, 2));
+ cell->setParam("\\TOPOUTPUT_SELECT", Const(st.ffS ? 1 : 3, 2));
cell->setParam("\\TOPADDSUB_LOWERINPUT", Const(2, 2));
cell->setParam("\\TOPADDSUB_UPPERINPUT", State::S0);
cell->setParam("\\TOPADDSUB_CARRYSELECT", Const(3, 2));
- cell->setParam("\\BOTOUTPUT_SELECT", Const(pm.st.ffS ? 1 : 3, 2));
+ cell->setParam("\\BOTOUTPUT_SELECT", Const(st.ffS ? 1 : 3, 2));
cell->setParam("\\BOTADDSUB_LOWERINPUT", Const(2, 2));
cell->setParam("\\BOTADDSUB_UPPERINPUT", State::S0);
cell->setParam("\\BOTADDSUB_CARRYSELECT", Const(0, 2));
@@ -198,9 +201,9 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
cell->setParam("\\A_SIGNED", mul_signed ? State::S1 : State::S0);
cell->setParam("\\B_SIGNED", mul_signed ? State::S1 : State::S0);
- pm.autoremove(pm.st.mul);
- pm.autoremove(pm.st.ffY);
- pm.autoremove(pm.st.ffS);
+ pm.autoremove(st.mul);
+ pm.autoremove(st.ffY);
+ pm.autoremove(st.ffS);
}
struct Ice40DspPass : public Pass {
@@ -230,7 +233,7 @@ struct Ice40DspPass : public Pass {
extra_args(args, argidx, design);
for (auto module : design->selected_modules())
- ice40_dsp_pm(module, module->selected_cells()).run(create_ice40_dsp);
+ ice40_dsp_pm(module, module->selected_cells()).run_ice40_dsp(create_ice40_dsp);
}
} Ice40DspPass;