aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5/pack.cc
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-10-24 10:27:15 +0100
committerGitHub <noreply@github.com>2018-10-24 10:27:15 +0100
commitf0e51790037625eabfa6d7aeefd37ff06277dbd0 (patch)
tree6eb4c5f0adba5b6a1cd083c80040a0c31c1d0a58 /ecp5/pack.cc
parentb5faa7ad102b8308eeb0c73a3849909bf4b1b635 (diff)
parent0ac48c6a08ff1ed50fbd6edf4f2351a70695530c (diff)
downloadnextpnr-f0e51790037625eabfa6d7aeefd37ff06277dbd0.tar.gz
nextpnr-f0e51790037625eabfa6d7aeefd37ff06277dbd0.tar.bz2
nextpnr-f0e51790037625eabfa6d7aeefd37ff06277dbd0.zip
Merge pull request #94 from daveshah1/ecp5_dsp
Adding basic multiplier support for ECP5
Diffstat (limited to 'ecp5/pack.cc')
-rw-r--r--ecp5/pack.cc55
1 files changed, 54 insertions, 1 deletions
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index ef65fd27..18debb74 100644
--- a/ecp5/pack.cc
+++ b/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();