Merge pull request #94 from daveshah1/ecp5_dsp
Adding basic multiplier support for ECP5
This commit is contained in:
commit
f0e5179003
@ -647,6 +647,10 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
|
||||
return (cell->ports.at(port).type == PORT_OUT) ? TMG_REGISTER_OUTPUT : TMG_REGISTER_INPUT;
|
||||
}
|
||||
NPNR_ASSERT_FALSE_STR("no timing type for RAM port '" + port.str(this) + "'");
|
||||
} else if (cell->type == id_MULT18X18D) {
|
||||
return TMG_IGNORE; // FIXME
|
||||
} else if (cell->type == id_ALU54B) {
|
||||
return TMG_IGNORE; // FIXME
|
||||
} else {
|
||||
NPNR_ASSERT_FALSE_STR("no timing data for cell type '" + cell->type.str(this) + "'");
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <queue>
|
||||
#include <regex>
|
||||
#include <streambuf>
|
||||
|
||||
@ -81,17 +82,20 @@ static std::vector<bool> str_to_bitvector(std::string str, int size)
|
||||
static void tie_cib_signal(Context *ctx, ChipConfig &cc, WireId wire, bool value)
|
||||
{
|
||||
static const std::regex cib_re("J([A-D]|CE|LSR|CLK)[0-7]");
|
||||
WireId cibsig = wire;
|
||||
std::string basename = ctx->getWireBasename(wire).str(ctx);
|
||||
|
||||
while (!std::regex_match(basename, cib_re)) {
|
||||
auto uphill = ctx->getPipsUphill(cibsig);
|
||||
NPNR_ASSERT(uphill.begin() != uphill.end()); // At least one uphill pip
|
||||
auto iter = uphill.begin();
|
||||
cibsig = ctx->getPipSrcWire(*iter);
|
||||
std::queue<WireId> signals;
|
||||
signals.push(wire);
|
||||
WireId cibsig;
|
||||
std::string basename;
|
||||
while (true) {
|
||||
NPNR_ASSERT(!signals.empty());
|
||||
NPNR_ASSERT(signals.size() < 100);
|
||||
cibsig = signals.front();
|
||||
basename = ctx->getWireBasename(cibsig).str(ctx);
|
||||
++iter;
|
||||
NPNR_ASSERT(!(iter != uphill.end())); // Exactly one uphill pip
|
||||
signals.pop();
|
||||
if (std::regex_match(basename, cib_re))
|
||||
break;
|
||||
for (auto pip : ctx->getPipsUphill(cibsig))
|
||||
signals.push(ctx->getPipSrcWire(pip));
|
||||
}
|
||||
|
||||
bool out_value = value;
|
||||
@ -132,9 +136,12 @@ std::vector<bool> parse_init_str(const std::string &str, int length)
|
||||
char c = str.at((str.size() - i) - 1);
|
||||
int nibble = chtohex(c);
|
||||
result.at(i * 4) = nibble & 0x1;
|
||||
result.at(i * 4 + 1) = nibble & 0x2;
|
||||
result.at(i * 4 + 2) = nibble & 0x4;
|
||||
result.at(i * 4 + 3) = nibble & 0x8;
|
||||
if (i * 4 + 1 < length)
|
||||
result.at(i * 4 + 1) = nibble & 0x2;
|
||||
if (i * 4 + 2 < length)
|
||||
result.at(i * 4 + 2) = nibble & 0x4;
|
||||
if (i * 4 + 3 < length)
|
||||
result.at(i * 4 + 3) = nibble & 0x8;
|
||||
}
|
||||
} else {
|
||||
// Yosys style binary string
|
||||
@ -279,6 +286,98 @@ std::vector<std::string> get_bram_tiles(Context *ctx, BelId bel)
|
||||
return tiles;
|
||||
}
|
||||
|
||||
// Get the list of tiles corresponding to a DSP
|
||||
std::vector<std::string> get_dsp_tiles(Context *ctx, BelId bel)
|
||||
{
|
||||
std::vector<std::string> tiles;
|
||||
Loc loc = ctx->getBelLocation(bel);
|
||||
|
||||
static const std::set<std::string> dsp8 = {"MIB_DSP8", "DSP_SPINE_UL0", "DSP_SPINE_UR0", "DSP_SPINE_UR1"};
|
||||
if (ctx->getBelType(bel) == id_MULT18X18D) {
|
||||
switch (loc.z) {
|
||||
case 0:
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB_DSP0"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB2_DSP0"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB_DSP1"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB2_DSP1"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 2, "MIB_DSP2"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 2, "MIB2_DSP2"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 3, "MIB_DSP3"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 3, "MIB2_DSP3"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 4, "MIB_DSP4"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 4, "MIB2_DSP4"));
|
||||
break;
|
||||
case 1:
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 1, "MIB_DSP0"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 1, "MIB2_DSP0"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB_DSP1"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB2_DSP1"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB_DSP2"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB2_DSP2"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 2, "MIB_DSP3"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 2, "MIB2_DSP3"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 3, "MIB_DSP4"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 3, "MIB2_DSP4"));
|
||||
break;
|
||||
case 4:
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB_DSP4"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB2_DSP4"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB_DSP5"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB2_DSP5"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 2, "MIB_DSP6"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 2, "MIB2_DSP6"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 3, "MIB_DSP7"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 3, "MIB2_DSP7"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 4, dsp8));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 4, "MIB2_DSP8"));
|
||||
break;
|
||||
case 5:
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 1, "MIB_DSP4"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 1, "MIB2_DSP4"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB_DSP5"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB2_DSP5"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB_DSP6"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB2_DSP6"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 2, "MIB_DSP7"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 2, "MIB2_DSP7"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 3, dsp8));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 3, "MIB2_DSP8"));
|
||||
break;
|
||||
default:
|
||||
NPNR_ASSERT_FALSE("bad MULT z loc");
|
||||
}
|
||||
} else if (ctx->getBelType(bel) == id_ALU54B) {
|
||||
switch (loc.z) {
|
||||
case 3:
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 3, "MIB_DSP0"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 3, "MIB2_DSP0"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 2, "MIB_DSP1"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 2, "MIB2_DSP1"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 1, "MIB_DSP2"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 1, "MIB2_DSP2"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB_DSP3"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB2_DSP3"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB_DSP4"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB2_DSP4"));
|
||||
break;
|
||||
case 7:
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 3, "MIB_DSP4"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 3, "MIB2_DSP4"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 2, "MIB_DSP5"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 2, "MIB2_DSP5"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 1, "MIB_DSP6"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x - 1, "MIB2_DSP6"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB_DSP7"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x, "MIB2_DSP7"));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, dsp8));
|
||||
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + 1, "MIB2_DSP8"));
|
||||
break;
|
||||
default:
|
||||
NPNR_ASSERT_FALSE("bad ALU z loc");
|
||||
}
|
||||
}
|
||||
return tiles;
|
||||
}
|
||||
void fix_tile_names(Context *ctx, ChipConfig &cc)
|
||||
{
|
||||
// Remove the V prefix/suffix on certain tiles if device is a SERDES variant
|
||||
@ -312,6 +411,24 @@ void fix_tile_names(Context *ctx, ChipConfig &cc)
|
||||
}
|
||||
}
|
||||
|
||||
void tieoff_dsp_ports(Context *ctx, ChipConfig &cc, CellInfo *ci)
|
||||
{
|
||||
for (auto port : ci->ports) {
|
||||
if (port.second.net == nullptr && port.second.type == PORT_IN) {
|
||||
if (port.first.str(ctx).substr(0, 3) == "CLK" || port.first.str(ctx).substr(0, 2) == "CE" ||
|
||||
port.first.str(ctx).substr(0, 3) == "RST" || port.first.str(ctx).substr(0, 3) == "SRO" ||
|
||||
port.first.str(ctx).substr(0, 3) == "SRI" || port.first.str(ctx).substr(0, 2) == "RO" ||
|
||||
port.first.str(ctx).substr(0, 2) == "MA" || port.first.str(ctx).substr(0, 2) == "MB" ||
|
||||
port.first.str(ctx).substr(0, 3) == "CFB" || port.first.str(ctx).substr(0, 3) == "CIN" ||
|
||||
port.first.str(ctx).substr(0, 6) == "SOURCE" || port.first.str(ctx).substr(0, 6) == "SIGNED" ||
|
||||
port.first.str(ctx).substr(0, 2) == "OP")
|
||||
continue;
|
||||
bool value = bool_or_default(ci->params, ctx->id(port.first.str(ctx) + "MUX"), false);
|
||||
tie_cib_signal(ctx, cc, ctx->getBelPinWire(ci->bel, port.first), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write_bitstream(Context *ctx, std::string base_config_file, std::string text_config_file)
|
||||
{
|
||||
ChipConfig cc;
|
||||
@ -617,10 +734,145 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
|
||||
NPNR_ASSERT(!cc.bram_data.count(wid));
|
||||
cc.bram_data[wid] = init_data;
|
||||
cc.tilegroups.push_back(tg);
|
||||
} else if (ci->type == id_MULT18X18D) {
|
||||
TileGroup tg;
|
||||
Loc loc = ctx->getBelLocation(ci->bel);
|
||||
tg.tiles = get_dsp_tiles(ctx, ci->bel);
|
||||
std::string dsp = "MULT18_" + std::to_string(loc.z);
|
||||
tg.config.add_enum(dsp + ".REG_INPUTA_CLK", str_or_default(ci->params, ctx->id("REG_INPUTA_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_INPUTA_CE", str_or_default(ci->params, ctx->id("REG_INPUTA_CE"), "CE0"));
|
||||
tg.config.add_enum(dsp + ".REG_INPUTA_RST", str_or_default(ci->params, ctx->id("REG_INPUTA_RST"), "RST0"));
|
||||
tg.config.add_enum(dsp + ".REG_INPUTB_CLK", str_or_default(ci->params, ctx->id("REG_INPUTB_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_INPUTB_CE", str_or_default(ci->params, ctx->id("REG_INPUTB_CE"), "CE0"));
|
||||
tg.config.add_enum(dsp + ".REG_INPUTB_RST", str_or_default(ci->params, ctx->id("REG_INPUTB_RST"), "RST0"));
|
||||
tg.config.add_enum(dsp + ".REG_INPUTC_CLK", str_or_default(ci->params, ctx->id("REG_INPUTC_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_PIPELINE_CLK",
|
||||
str_or_default(ci->params, ctx->id("REG_PIPELINE_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_PIPELINE_CE", str_or_default(ci->params, ctx->id("REG_PIPELINE_CE"), "CE0"));
|
||||
tg.config.add_enum(dsp + ".REG_PIPELINE_RST",
|
||||
str_or_default(ci->params, ctx->id("REG_PIPELINE_RST"), "RST0"));
|
||||
tg.config.add_enum(dsp + ".REG_OUTPUT_CLK", str_or_default(ci->params, ctx->id("REG_OUTPUT_CLK"), "NONE"));
|
||||
if (dsp == "MULT18_0" || dsp == "MULT18_4")
|
||||
tg.config.add_enum(dsp + ".REG_OUTPUT_RST",
|
||||
str_or_default(ci->params, ctx->id("REG_OUTPUT_RST"), "RST0"));
|
||||
|
||||
tg.config.add_enum(dsp + ".CLK0_DIV", str_or_default(ci->params, ctx->id("CLK0_DIV"), "ENABLED"));
|
||||
tg.config.add_enum(dsp + ".CLK1_DIV", str_or_default(ci->params, ctx->id("CLK1_DIV"), "ENABLED"));
|
||||
tg.config.add_enum(dsp + ".CLK2_DIV", str_or_default(ci->params, ctx->id("CLK2_DIV"), "ENABLED"));
|
||||
tg.config.add_enum(dsp + ".CLK3_DIV", str_or_default(ci->params, ctx->id("CLK3_DIV"), "ENABLED"));
|
||||
tg.config.add_enum(dsp + ".GSR", str_or_default(ci->params, ctx->id("GSR"), "ENABLED"));
|
||||
tg.config.add_enum(dsp + ".SOURCEB_MODE", str_or_default(ci->params, ctx->id("SOURCEB_MODE"), "B_SHIFT"));
|
||||
tg.config.add_enum(dsp + ".RESETMODE", str_or_default(ci->params, ctx->id("RESETMODE"), "SYNC"));
|
||||
|
||||
tg.config.add_enum(dsp + ".MODE", "MULT18X18D");
|
||||
if (str_or_default(ci->params, ctx->id("REG_OUTPUT_CLK"), "NONE") == "NONE")
|
||||
tg.config.add_enum(dsp + ".CIBOUT_BYP", "ON");
|
||||
|
||||
if (loc.z < 4)
|
||||
tg.config.add_enum("DSP_LEFT.CIBOUT", "ON");
|
||||
else
|
||||
tg.config.add_enum("DSP_RIGHT.CIBOUT", "ON");
|
||||
|
||||
// Some muxes default to INV, make all pass-thru
|
||||
for (auto port : {"CLK", "CE", "RST"}) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
std::string sig = port + std::to_string(i);
|
||||
tg.config.add_enum(dsp + "." + sig + "MUX", sig);
|
||||
}
|
||||
}
|
||||
|
||||
tieoff_dsp_ports(ctx, cc, ci);
|
||||
cc.tilegroups.push_back(tg);
|
||||
|
||||
} else if (ci->type == id_ALU54B) {
|
||||
TileGroup tg;
|
||||
Loc loc = ctx->getBelLocation(ci->bel);
|
||||
tg.tiles = get_dsp_tiles(ctx, ci->bel);
|
||||
std::string dsp = "ALU54_" + std::to_string(loc.z);
|
||||
tg.config.add_enum(dsp + ".REG_INPUTC0_CLK",
|
||||
str_or_default(ci->params, ctx->id("REG_INPUTC0_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_INPUTC1_CLK",
|
||||
str_or_default(ci->params, ctx->id("REG_INPUTC1_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEOP0_0_CLK",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEOP0_0_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEOP0_0_CE",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEOP0_0_CE"), "CE0"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEOP0_0_RST",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEOP0_0_RST"), "RST0"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEOP1_0_CLK",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEOP1_0_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEOP0_1_CLK",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEOP0_1_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEOP0_1_CE",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEOP0_1_CE"), "CE0"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEOP0_1_RST",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEOP0_1_RST"), "RST0"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEIN_0_CLK",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEIN_0_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEIN_0_CE",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEIN_0_CE"), "CE0"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEIN_0_RST",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEIN_0_RST"), "RST0"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEIN_1_CLK",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEIN_1_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEIN_1_CE",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEIN_1_CE"), "CE0"));
|
||||
tg.config.add_enum(dsp + ".REG_OPCODEIN_1_RST",
|
||||
str_or_default(ci->params, ctx->id("REG_OPCODEIN_1_RST"), "RST0"));
|
||||
tg.config.add_enum(dsp + ".REG_OUTPUT0_CLK",
|
||||
str_or_default(ci->params, ctx->id("REG_OUTPUT0_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_OUTPUT1_CLK",
|
||||
str_or_default(ci->params, ctx->id("REG_OUTPUT1_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".REG_FLAG_CLK", str_or_default(ci->params, ctx->id("REG_FLAG_CLK"), "NONE"));
|
||||
tg.config.add_enum(dsp + ".MCPAT_SOURCE", str_or_default(ci->params, ctx->id("MCPAT_SOURCE"), "STATIC"));
|
||||
tg.config.add_enum(dsp + ".MASKPAT_SOURCE",
|
||||
str_or_default(ci->params, ctx->id("MASKPAT_SOURCE"), "STATIC"));
|
||||
tg.config.add_word(dsp + ".MASK01",
|
||||
parse_init_str(str_or_default(ci->params, ctx->id("MASK01"), "0x00000000000000"), 56));
|
||||
tg.config.add_enum(dsp + ".CLK0_DIV", str_or_default(ci->params, ctx->id("CLK0_DIV"), "ENABLED"));
|
||||
tg.config.add_enum(dsp + ".CLK1_DIV", str_or_default(ci->params, ctx->id("CLK1_DIV"), "ENABLED"));
|
||||
tg.config.add_enum(dsp + ".CLK2_DIV", str_or_default(ci->params, ctx->id("CLK2_DIV"), "ENABLED"));
|
||||
tg.config.add_enum(dsp + ".CLK3_DIV", str_or_default(ci->params, ctx->id("CLK3_DIV"), "ENABLED"));
|
||||
tg.config.add_word(dsp + ".MCPAT",
|
||||
parse_init_str(str_or_default(ci->params, ctx->id("MCPAT"), "0x00000000000000"), 56));
|
||||
tg.config.add_word(dsp + ".MASKPAT",
|
||||
parse_init_str(str_or_default(ci->params, ctx->id("MASKPAT"), "0x00000000000000"), 56));
|
||||
tg.config.add_word(dsp + ".RNDPAT",
|
||||
parse_init_str(str_or_default(ci->params, ctx->id("RNDPAT"), "0x00000000000000"), 56));
|
||||
tg.config.add_enum(dsp + ".GSR", str_or_default(ci->params, ctx->id("GSR"), "ENABLED"));
|
||||
tg.config.add_enum(dsp + ".RESETMODE", str_or_default(ci->params, ctx->id("RESETMODE"), "SYNC"));
|
||||
tg.config.add_enum(dsp + ".FORCE_ZERO_BARREL_SHIFT",
|
||||
str_or_default(ci->params, ctx->id("FORCE_ZERO_BARREL_SHIFT"), "DISABLED"));
|
||||
tg.config.add_enum(dsp + ".LEGACY", str_or_default(ci->params, ctx->id("LEGACY"), "DISABLED"));
|
||||
|
||||
tg.config.add_enum(dsp + ".MODE", "ALU54B");
|
||||
|
||||
if (loc.z < 4)
|
||||
tg.config.add_enum("DSP_LEFT.CIBOUT", "ON");
|
||||
else
|
||||
tg.config.add_enum("DSP_RIGHT.CIBOUT", "ON");
|
||||
if (str_or_default(ci->params, ctx->id("REG_FLAG_CLK"), "NONE") == "NONE") {
|
||||
if (dsp == "ALU54_7") {
|
||||
tg.config.add_enum("MULT18_5.CIBOUT_BYP", "ON");
|
||||
} else if (dsp == "ALU54_3") {
|
||||
tg.config.add_enum("MULT18_5.CIBOUT_BYP", "ON");
|
||||
}
|
||||
}
|
||||
if (str_or_default(ci->params, ctx->id("REG_OUTPUT0_CLK"), "NONE") == "NONE") {
|
||||
if (dsp == "ALU54_7") {
|
||||
tg.config.add_enum("MULT18_4.CIBOUT_BYP", "ON");
|
||||
} else if (dsp == "ALU54_3") {
|
||||
tg.config.add_enum("MULT18_0.CIBOUT_BYP", "ON");
|
||||
}
|
||||
}
|
||||
tieoff_dsp_ports(ctx, cc, ci);
|
||||
cc.tilegroups.push_back(tg);
|
||||
|
||||
} else {
|
||||
NPNR_ASSERT_FALSE("unsupported cell type");
|
||||
}
|
||||
}
|
||||
|
||||
// Fixup tile names
|
||||
fix_tile_names(ctx, cc);
|
||||
// Configure chip
|
||||
|
@ -171,4 +171,619 @@ X(DOB13)
|
||||
X(DOB14)
|
||||
X(DOB15)
|
||||
X(DOB16)
|
||||
X(DOB17)
|
||||
X(DOB17)
|
||||
|
||||
|
||||
X(MULT18X18D)
|
||||
X(A2)
|
||||
X(A3)
|
||||
X(A4)
|
||||
X(A5)
|
||||
X(A6)
|
||||
X(A7)
|
||||
X(A8)
|
||||
X(A9)
|
||||
X(A10)
|
||||
X(A11)
|
||||
X(A12)
|
||||
X(A13)
|
||||
X(A14)
|
||||
X(A15)
|
||||
X(A16)
|
||||
X(A17)
|
||||
X(B2)
|
||||
X(B3)
|
||||
X(B4)
|
||||
X(B5)
|
||||
X(B6)
|
||||
X(B7)
|
||||
X(B8)
|
||||
X(B9)
|
||||
X(B10)
|
||||
X(B11)
|
||||
X(B12)
|
||||
X(B13)
|
||||
X(B14)
|
||||
X(B15)
|
||||
X(B16)
|
||||
X(B17)
|
||||
X(C2)
|
||||
X(C3)
|
||||
X(C4)
|
||||
X(C5)
|
||||
X(C6)
|
||||
X(C7)
|
||||
X(C8)
|
||||
X(C9)
|
||||
X(C10)
|
||||
X(C11)
|
||||
X(C12)
|
||||
X(C13)
|
||||
X(C14)
|
||||
X(C15)
|
||||
X(C16)
|
||||
X(C17)
|
||||
X(SIGNEDA)
|
||||
X(SIGNEDB)
|
||||
X(SOURCEA)
|
||||
X(SOURCEB)
|
||||
X(CLK0)
|
||||
X(CLK1)
|
||||
X(CLK2)
|
||||
X(CLK3)
|
||||
X(CE0)
|
||||
X(CE1)
|
||||
X(CE2)
|
||||
X(CE3)
|
||||
X(RST0)
|
||||
X(RST1)
|
||||
X(RST2)
|
||||
X(RST3)
|
||||
X(SRIA0)
|
||||
X(SRIA1)
|
||||
X(SRIA2)
|
||||
X(SRIA3)
|
||||
X(SRIA4)
|
||||
X(SRIA5)
|
||||
X(SRIA6)
|
||||
X(SRIA7)
|
||||
X(SRIA8)
|
||||
X(SRIA9)
|
||||
X(SRIA10)
|
||||
X(SRIA11)
|
||||
X(SRIA12)
|
||||
X(SRIA13)
|
||||
X(SRIA14)
|
||||
X(SRIA15)
|
||||
X(SRIA16)
|
||||
X(SRIA17)
|
||||
X(SRIB0)
|
||||
X(SRIB1)
|
||||
X(SRIB2)
|
||||
X(SRIB3)
|
||||
X(SRIB4)
|
||||
X(SRIB5)
|
||||
X(SRIB6)
|
||||
X(SRIB7)
|
||||
X(SRIB8)
|
||||
X(SRIB9)
|
||||
X(SRIB10)
|
||||
X(SRIB11)
|
||||
X(SRIB12)
|
||||
X(SRIB13)
|
||||
X(SRIB14)
|
||||
X(SRIB15)
|
||||
X(SRIB16)
|
||||
X(SRIB17)
|
||||
X(SROA0)
|
||||
X(SROA1)
|
||||
X(SROA2)
|
||||
X(SROA3)
|
||||
X(SROA4)
|
||||
X(SROA5)
|
||||
X(SROA6)
|
||||
X(SROA7)
|
||||
X(SROA8)
|
||||
X(SROA9)
|
||||
X(SROA10)
|
||||
X(SROA11)
|
||||
X(SROA12)
|
||||
X(SROA13)
|
||||
X(SROA14)
|
||||
X(SROA15)
|
||||
X(SROA16)
|
||||
X(SROA17)
|
||||
X(SROB0)
|
||||
X(SROB1)
|
||||
X(SROB2)
|
||||
X(SROB3)
|
||||
X(SROB4)
|
||||
X(SROB5)
|
||||
X(SROB6)
|
||||
X(SROB7)
|
||||
X(SROB8)
|
||||
X(SROB9)
|
||||
X(SROB10)
|
||||
X(SROB11)
|
||||
X(SROB12)
|
||||
X(SROB13)
|
||||
X(SROB14)
|
||||
X(SROB15)
|
||||
X(SROB16)
|
||||
X(SROB17)
|
||||
X(ROA0)
|
||||
X(ROA1)
|
||||
X(ROA2)
|
||||
X(ROA3)
|
||||
X(ROA4)
|
||||
X(ROA5)
|
||||
X(ROA6)
|
||||
X(ROA7)
|
||||
X(ROA8)
|
||||
X(ROA9)
|
||||
X(ROA10)
|
||||
X(ROA11)
|
||||
X(ROA12)
|
||||
X(ROA13)
|
||||
X(ROA14)
|
||||
X(ROA15)
|
||||
X(ROA16)
|
||||
X(ROA17)
|
||||
X(ROB0)
|
||||
X(ROB1)
|
||||
X(ROB2)
|
||||
X(ROB3)
|
||||
X(ROB4)
|
||||
X(ROB5)
|
||||
X(ROB6)
|
||||
X(ROB7)
|
||||
X(ROB8)
|
||||
X(ROB9)
|
||||
X(ROB10)
|
||||
X(ROB11)
|
||||
X(ROB12)
|
||||
X(ROB13)
|
||||
X(ROB14)
|
||||
X(ROB15)
|
||||
X(ROB16)
|
||||
X(ROB17)
|
||||
X(ROC0)
|
||||
X(ROC1)
|
||||
X(ROC2)
|
||||
X(ROC3)
|
||||
X(ROC4)
|
||||
X(ROC5)
|
||||
X(ROC6)
|
||||
X(ROC7)
|
||||
X(ROC8)
|
||||
X(ROC9)
|
||||
X(ROC10)
|
||||
X(ROC11)
|
||||
X(ROC12)
|
||||
X(ROC13)
|
||||
X(ROC14)
|
||||
X(ROC15)
|
||||
X(ROC16)
|
||||
X(ROC17)
|
||||
X(P0)
|
||||
X(P1)
|
||||
X(P2)
|
||||
X(P3)
|
||||
X(P4)
|
||||
X(P5)
|
||||
X(P6)
|
||||
X(P7)
|
||||
X(P8)
|
||||
X(P9)
|
||||
X(P10)
|
||||
X(P11)
|
||||
X(P12)
|
||||
X(P13)
|
||||
X(P14)
|
||||
X(P15)
|
||||
X(P16)
|
||||
X(P17)
|
||||
X(P18)
|
||||
X(P19)
|
||||
X(P20)
|
||||
X(P21)
|
||||
X(P22)
|
||||
X(P23)
|
||||
X(P24)
|
||||
X(P25)
|
||||
X(P26)
|
||||
X(P27)
|
||||
X(P28)
|
||||
X(P29)
|
||||
X(P30)
|
||||
X(P31)
|
||||
X(P32)
|
||||
X(P33)
|
||||
X(P34)
|
||||
X(P35)
|
||||
X(SIGNEDP)
|
||||
|
||||
X(ALU54B)
|
||||
X(SIGNEDIA)
|
||||
X(SIGNEDIB)
|
||||
X(SIGNEDCIN)
|
||||
X(A18)
|
||||
X(A19)
|
||||
X(A20)
|
||||
X(A21)
|
||||
X(A22)
|
||||
X(A23)
|
||||
X(A24)
|
||||
X(A25)
|
||||
X(A26)
|
||||
X(A27)
|
||||
X(A28)
|
||||
X(A29)
|
||||
X(A30)
|
||||
X(A31)
|
||||
X(A32)
|
||||
X(A33)
|
||||
X(A34)
|
||||
X(A35)
|
||||
X(B18)
|
||||
X(B19)
|
||||
X(B20)
|
||||
X(B21)
|
||||
X(B22)
|
||||
X(B23)
|
||||
X(B24)
|
||||
X(B25)
|
||||
X(B26)
|
||||
X(B27)
|
||||
X(B28)
|
||||
X(B29)
|
||||
X(B30)
|
||||
X(B31)
|
||||
X(B32)
|
||||
X(B33)
|
||||
X(B34)
|
||||
X(B35)
|
||||
X(C18)
|
||||
X(C19)
|
||||
X(C20)
|
||||
X(C21)
|
||||
X(C22)
|
||||
X(C23)
|
||||
X(C24)
|
||||
X(C25)
|
||||
X(C26)
|
||||
X(C27)
|
||||
X(C28)
|
||||
X(C29)
|
||||
X(C30)
|
||||
X(C31)
|
||||
X(C32)
|
||||
X(C33)
|
||||
X(C34)
|
||||
X(C35)
|
||||
X(C36)
|
||||
X(C37)
|
||||
X(C38)
|
||||
X(C39)
|
||||
X(C40)
|
||||
X(C41)
|
||||
X(C42)
|
||||
X(C43)
|
||||
X(C44)
|
||||
X(C45)
|
||||
X(C46)
|
||||
X(C47)
|
||||
X(C48)
|
||||
X(C49)
|
||||
X(C50)
|
||||
X(C51)
|
||||
X(C52)
|
||||
X(C53)
|
||||
X(CFB0)
|
||||
X(CFB1)
|
||||
X(CFB2)
|
||||
X(CFB3)
|
||||
X(CFB4)
|
||||
X(CFB5)
|
||||
X(CFB6)
|
||||
X(CFB7)
|
||||
X(CFB8)
|
||||
X(CFB9)
|
||||
X(CFB10)
|
||||
X(CFB11)
|
||||
X(CFB12)
|
||||
X(CFB13)
|
||||
X(CFB14)
|
||||
X(CFB15)
|
||||
X(CFB16)
|
||||
X(CFB17)
|
||||
X(CFB18)
|
||||
X(CFB19)
|
||||
X(CFB20)
|
||||
X(CFB21)
|
||||
X(CFB22)
|
||||
X(CFB23)
|
||||
X(CFB24)
|
||||
X(CFB25)
|
||||
X(CFB26)
|
||||
X(CFB27)
|
||||
X(CFB28)
|
||||
X(CFB29)
|
||||
X(CFB30)
|
||||
X(CFB31)
|
||||
X(CFB32)
|
||||
X(CFB33)
|
||||
X(CFB34)
|
||||
X(CFB35)
|
||||
X(CFB36)
|
||||
X(CFB37)
|
||||
X(CFB38)
|
||||
X(CFB39)
|
||||
X(CFB40)
|
||||
X(CFB41)
|
||||
X(CFB42)
|
||||
X(CFB43)
|
||||
X(CFB44)
|
||||
X(CFB45)
|
||||
X(CFB46)
|
||||
X(CFB47)
|
||||
X(CFB48)
|
||||
X(CFB49)
|
||||
X(CFB50)
|
||||
X(CFB51)
|
||||
X(CFB52)
|
||||
X(CFB53)
|
||||
X(MA0)
|
||||
X(MA1)
|
||||
X(MA2)
|
||||
X(MA3)
|
||||
X(MA4)
|
||||
X(MA5)
|
||||
X(MA6)
|
||||
X(MA7)
|
||||
X(MA8)
|
||||
X(MA9)
|
||||
X(MA10)
|
||||
X(MA11)
|
||||
X(MA12)
|
||||
X(MA13)
|
||||
X(MA14)
|
||||
X(MA15)
|
||||
X(MA16)
|
||||
X(MA17)
|
||||
X(MA18)
|
||||
X(MA19)
|
||||
X(MA20)
|
||||
X(MA21)
|
||||
X(MA22)
|
||||
X(MA23)
|
||||
X(MA24)
|
||||
X(MA25)
|
||||
X(MA26)
|
||||
X(MA27)
|
||||
X(MA28)
|
||||
X(MA29)
|
||||
X(MA30)
|
||||
X(MA31)
|
||||
X(MA32)
|
||||
X(MA33)
|
||||
X(MA34)
|
||||
X(MA35)
|
||||
X(MB0)
|
||||
X(MB1)
|
||||
X(MB2)
|
||||
X(MB3)
|
||||
X(MB4)
|
||||
X(MB5)
|
||||
X(MB6)
|
||||
X(MB7)
|
||||
X(MB8)
|
||||
X(MB9)
|
||||
X(MB10)
|
||||
X(MB11)
|
||||
X(MB12)
|
||||
X(MB13)
|
||||
X(MB14)
|
||||
X(MB15)
|
||||
X(MB16)
|
||||
X(MB17)
|
||||
X(MB18)
|
||||
X(MB19)
|
||||
X(MB20)
|
||||
X(MB21)
|
||||
X(MB22)
|
||||
X(MB23)
|
||||
X(MB24)
|
||||
X(MB25)
|
||||
X(MB26)
|
||||
X(MB27)
|
||||
X(MB28)
|
||||
X(MB29)
|
||||
X(MB30)
|
||||
X(MB31)
|
||||
X(MB32)
|
||||
X(MB33)
|
||||
X(MB34)
|
||||
X(MB35)
|
||||
X(CIN0)
|
||||
X(CIN1)
|
||||
X(CIN2)
|
||||
X(CIN3)
|
||||
X(CIN4)
|
||||
X(CIN5)
|
||||
X(CIN6)
|
||||
X(CIN7)
|
||||
X(CIN8)
|
||||
X(CIN9)
|
||||
X(CIN10)
|
||||
X(CIN11)
|
||||
X(CIN12)
|
||||
X(CIN13)
|
||||
X(CIN14)
|
||||
X(CIN15)
|
||||
X(CIN16)
|
||||
X(CIN17)
|
||||
X(CIN18)
|
||||
X(CIN19)
|
||||
X(CIN20)
|
||||
X(CIN21)
|
||||
X(CIN22)
|
||||
X(CIN23)
|
||||
X(CIN24)
|
||||
X(CIN25)
|
||||
X(CIN26)
|
||||
X(CIN27)
|
||||
X(CIN28)
|
||||
X(CIN29)
|
||||
X(CIN30)
|
||||
X(CIN31)
|
||||
X(CIN32)
|
||||
X(CIN33)
|
||||
X(CIN34)
|
||||
X(CIN35)
|
||||
X(CIN36)
|
||||
X(CIN37)
|
||||
X(CIN38)
|
||||
X(CIN39)
|
||||
X(CIN40)
|
||||
X(CIN41)
|
||||
X(CIN42)
|
||||
X(CIN43)
|
||||
X(CIN44)
|
||||
X(CIN45)
|
||||
X(CIN46)
|
||||
X(CIN47)
|
||||
X(CIN48)
|
||||
X(CIN49)
|
||||
X(CIN50)
|
||||
X(CIN51)
|
||||
X(CIN52)
|
||||
X(CIN53)
|
||||
X(OP0)
|
||||
X(OP1)
|
||||
X(OP2)
|
||||
X(OP3)
|
||||
X(OP4)
|
||||
X(OP5)
|
||||
X(OP6)
|
||||
X(OP7)
|
||||
X(OP8)
|
||||
X(OP9)
|
||||
X(OP10)
|
||||
X(R0)
|
||||
X(R1)
|
||||
X(R2)
|
||||
X(R3)
|
||||
X(R4)
|
||||
X(R5)
|
||||
X(R6)
|
||||
X(R7)
|
||||
X(R8)
|
||||
X(R9)
|
||||
X(R10)
|
||||
X(R11)
|
||||
X(R12)
|
||||
X(R13)
|
||||
X(R14)
|
||||
X(R15)
|
||||
X(R16)
|
||||
X(R17)
|
||||
X(R18)
|
||||
X(R19)
|
||||
X(R20)
|
||||
X(R21)
|
||||
X(R22)
|
||||
X(R23)
|
||||
X(R24)
|
||||
X(R25)
|
||||
X(R26)
|
||||
X(R27)
|
||||
X(R28)
|
||||
X(R29)
|
||||
X(R30)
|
||||
X(R31)
|
||||
X(R32)
|
||||
X(R33)
|
||||
X(R34)
|
||||
X(R35)
|
||||
X(R36)
|
||||
X(R37)
|
||||
X(R38)
|
||||
X(R39)
|
||||
X(R40)
|
||||
X(R41)
|
||||
X(R42)
|
||||
X(R43)
|
||||
X(R44)
|
||||
X(R45)
|
||||
X(R46)
|
||||
X(R47)
|
||||
X(R48)
|
||||
X(R49)
|
||||
X(R50)
|
||||
X(R51)
|
||||
X(R52)
|
||||
X(R53)
|
||||
X(CO0)
|
||||
X(CO1)
|
||||
X(CO2)
|
||||
X(CO3)
|
||||
X(CO4)
|
||||
X(CO5)
|
||||
X(CO6)
|
||||
X(CO7)
|
||||
X(CO8)
|
||||
X(CO9)
|
||||
X(CO10)
|
||||
X(CO11)
|
||||
X(CO12)
|
||||
X(CO13)
|
||||
X(CO14)
|
||||
X(CO15)
|
||||
X(CO16)
|
||||
X(CO17)
|
||||
X(CO18)
|
||||
X(CO19)
|
||||
X(CO20)
|
||||
X(CO21)
|
||||
X(CO22)
|
||||
X(CO23)
|
||||
X(CO24)
|
||||
X(CO25)
|
||||
X(CO26)
|
||||
X(CO27)
|
||||
X(CO28)
|
||||
X(CO29)
|
||||
X(CO30)
|
||||
X(CO31)
|
||||
X(CO32)
|
||||
X(CO33)
|
||||
X(CO34)
|
||||
X(CO35)
|
||||
X(CO36)
|
||||
X(CO37)
|
||||
X(CO38)
|
||||
X(CO39)
|
||||
X(CO40)
|
||||
X(CO41)
|
||||
X(CO42)
|
||||
X(CO43)
|
||||
X(CO44)
|
||||
X(CO45)
|
||||
X(CO46)
|
||||
X(CO47)
|
||||
X(CO48)
|
||||
X(CO49)
|
||||
X(CO50)
|
||||
X(CO51)
|
||||
X(CO52)
|
||||
X(CO53)
|
||||
X(EQZ)
|
||||
X(EQZM)
|
||||
X(EQOM)
|
||||
X(EQPAT)
|
||||
X(EQPATB)
|
||||
X(OVER)
|
||||
X(UNDER)
|
||||
X(OVERUNDER)
|
||||
X(SIGNEDR)
|
||||
|
55
ecp5/pack.cc
55
ecp5/pack.cc
@ -856,7 +856,21 @@ class Ecp5Packer
|
||||
uc->params[ctx->id(user.port.str(ctx) + "MUX")] = constval ? "1" : "0";
|
||||
}
|
||||
uc->ports[user.port].net = nullptr;
|
||||
|
||||
} else if (uc->type == id_ALU54B || uc->type == id_MULT18X18D) {
|
||||
if (user.port.str(ctx).substr(0, 3) == "CLK" || user.port.str(ctx).substr(0, 2) == "CE" ||
|
||||
user.port.str(ctx).substr(0, 3) == "RST" || user.port.str(ctx).substr(0, 3) == "SRO" ||
|
||||
user.port.str(ctx).substr(0, 3) == "SRI" || user.port.str(ctx).substr(0, 2) == "RO" ||
|
||||
user.port.str(ctx).substr(0, 2) == "MA" || user.port.str(ctx).substr(0, 2) == "MB" ||
|
||||
user.port.str(ctx).substr(0, 3) == "CFB" || user.port.str(ctx).substr(0, 3) == "CIN" ||
|
||||
user.port.str(ctx).substr(0, 6) == "SOURCE" || user.port.str(ctx).substr(0, 6) == "SIGNED" ||
|
||||
user.port.str(ctx).substr(0, 2) == "OP") {
|
||||
uc->ports[user.port].net = constnet;
|
||||
constnet->users.push_back(user);
|
||||
} else {
|
||||
// Connected to CIB ABCD. Default state is bitstream configurable
|
||||
uc->params[ctx->id(user.port.str(ctx) + "MUX")] = constval ? "1" : "0";
|
||||
uc->ports[user.port].net = nullptr;
|
||||
}
|
||||
} else {
|
||||
uc->ports[user.port].net = constnet;
|
||||
constnet->users.push_back(user);
|
||||
@ -974,11 +988,50 @@ class Ecp5Packer
|
||||
}
|
||||
}
|
||||
|
||||
// Pack DSPs
|
||||
void pack_dsps()
|
||||
{
|
||||
for (auto cell : sorted(ctx->cells)) {
|
||||
CellInfo *ci = cell.second;
|
||||
if (ci->type == id_MULT18X18D) {
|
||||
// Add ports, even if disconnected, to ensure correct tie-offs
|
||||
for (auto sig : {"CLK", "CE", "RST"})
|
||||
for (int i = 0; i < 4; i++)
|
||||
autocreate_empty_port(ci, ctx->id(sig + std::to_string(i)));
|
||||
for (auto sig : {"SIGNED", "SOURCE"})
|
||||
for (auto c : {"A", "B"})
|
||||
autocreate_empty_port(ci, ctx->id(sig + std::string(c)));
|
||||
for (auto port : {"A", "B", "C"})
|
||||
for (int i = 0; i < 18; i++)
|
||||
autocreate_empty_port(ci, ctx->id(port + std::to_string(i)));
|
||||
for (auto port : {"SRIA", "SRIB"})
|
||||
for (int i = 0; i < 18; i++)
|
||||
autocreate_empty_port(ci, ctx->id(port + std::to_string(i)));
|
||||
} else if (ci->type == id_ALU54B) {
|
||||
for (auto sig : {"CLK", "CE", "RST"})
|
||||
for (int i = 0; i < 4; i++)
|
||||
autocreate_empty_port(ci, ctx->id(sig + std::to_string(i)));
|
||||
autocreate_empty_port(ci, id_SIGNEDIA);
|
||||
autocreate_empty_port(ci, id_SIGNEDIB);
|
||||
autocreate_empty_port(ci, id_SIGNEDCIN);
|
||||
for (auto port : {"A", "B", "MA", "MB"})
|
||||
for (int i = 0; i < 36; i++)
|
||||
autocreate_empty_port(ci, ctx->id(port + std::to_string(i)));
|
||||
for (auto port : {"C", "CFB", "CIN"})
|
||||
for (int i = 0; i < 54; i++)
|
||||
autocreate_empty_port(ci, ctx->id(port + std::to_string(i)));
|
||||
for (int i = 0; i < 11; i++)
|
||||
autocreate_empty_port(ci, ctx->id("OP" + std::to_string(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void pack()
|
||||
{
|
||||
pack_io();
|
||||
pack_ebr();
|
||||
pack_dsps();
|
||||
pack_constants();
|
||||
pack_dram();
|
||||
pack_carries();
|
||||
|
Loading…
Reference in New Issue
Block a user