aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-07-18 16:01:53 +0200
committerDavid Shah <davey1576@gmail.com>2018-07-18 16:01:53 +0200
commitc80934f953a9aa185aec0f3e9b9a23296c6e682b (patch)
tree5a7db31881695904f512caeec6b8fbf861f32e55
parent5393841c669775eab5a5e5fde9be2bab3ec67879 (diff)
downloadnextpnr-c80934f953a9aa185aec0f3e9b9a23296c6e682b.tar.gz
nextpnr-c80934f953a9aa185aec0f3e9b9a23296c6e682b.tar.bz2
nextpnr-c80934f953a9aa185aec0f3e9b9a23296c6e682b.zip
ecp5: Add support for pin name constraints using 'LOC' attributes
Signed-off-by: David Shah <davey1576@gmail.com>
-rw-r--r--ecp5/arch.cc33
-rw-r--r--ecp5/arch.h1
-rw-r--r--ecp5/main.cc8
-rw-r--r--ecp5/pack.cc15
-rw-r--r--ecp5/synth/blinky.v22
5 files changed, 64 insertions, 15 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index 0ffede3b..1510a27f 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -118,6 +118,16 @@ Arch::Arch(ArchArgs args) : args(args)
log_error("Unsupported ECP5 chip type.\n");
}
#endif
+ package_info = nullptr;
+ for (int i = 0; i < chip_info->num_packages; i++) {
+ if (args.package == chip_info->package_info[i].name.get()) {
+ package_info = &(chip_info->package_info[i]);
+ break;
+ }
+ }
+
+ if (!package_info)
+ log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str());
id_trellis_slice = id("TRELLIS_SLICE");
id_clk = id("CLK");
@@ -282,9 +292,28 @@ IdString Arch::getPipName(PipId pip) const
// -----------------------------------------------------------------------
-BelId Arch::getPackagePinBel(const std::string &pin) const { return BelId(); }
+BelId Arch::getPackagePinBel(const std::string &pin) const
+{
+ for (int i = 0; i < package_info->num_pins; i++) {
+ if (package_info->pin_data[i].name.get() == pin) {
+ BelId bel;
+ bel.location = package_info->pin_data[i].abs_loc;
+ bel.index = package_info->pin_data[i].bel_index;
+ return bel;
+ }
+ }
+ return BelId();
+}
-std::string Arch::getBelPackagePin(BelId bel) const { return ""; }
+std::string Arch::getBelPackagePin(BelId bel) const
+{
+ for (int i = 0; i < package_info->num_pins; i++) {
+ if (package_info->pin_data[i].abs_loc == bel.location && package_info->pin_data[i].bel_index == bel.index) {
+ return package_info->pin_data[i].name.get();
+ }
+ }
+ return "";
+}
// -----------------------------------------------------------------------
void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const
diff --git a/ecp5/arch.h b/ecp5/arch.h
index 5158fe5c..944aedea 100644
--- a/ecp5/arch.h
+++ b/ecp5/arch.h
@@ -363,6 +363,7 @@ struct ArchArgs
struct Arch : BaseCtx
{
const ChipInfoPOD *chip_info;
+ const PackageInfoPOD *package_info;
mutable std::unordered_map<IdString, BelId> bel_by_name;
mutable std::unordered_map<IdString, WireId> wire_by_name;
diff --git a/ecp5/main.cc b/ecp5/main.cc
index 7521b88c..5a4a900a 100644
--- a/ecp5/main.cc
+++ b/ecp5/main.cc
@@ -68,6 +68,8 @@ int main(int argc, char *argv[])
options.add_options()("45k", "set device type to LFE5U-45F");
options.add_options()("85k", "set device type to LFE5U-85F");
+ options.add_options()("package", po::value<std::string>(), "select device package (defaults to CABGA381)");
+
options.add_options()("json", po::value<std::string>(), "JSON design file to ingest");
options.add_options()("seed", po::value<int>(), "seed value for random number generator");
@@ -123,8 +125,10 @@ int main(int argc, char *argv[])
args.type = ArchArgs::LFE5U_45F;
if (vm.count("85k"))
args.type = ArchArgs::LFE5U_85F;
-
- args.package = "CABGA381";
+ if (vm.count("package"))
+ args.package = vm["package"].as<std::string>();
+ else
+ args.package = "CABGA381";
args.speed = 6;
std::unique_ptr<Context> ctx = std::unique_ptr<Context>(new Context(args));
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index da5b3ec5..11cc2647 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -232,8 +232,23 @@ class Ecp5Packer
} else {
log_error("TRELLIS_IO required on all top level IOs...\n");
}
+
packed_cells.insert(ci->name);
std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(trio->attrs, trio->attrs.begin()));
+
+ auto loc_attr = trio->attrs.find(ctx->id("LOC"));
+ if (loc_attr != trio->attrs.end()) {
+ std::string pin = loc_attr->second;
+ BelId pinBel = ctx->getPackagePinBel(pin);
+ if (pinBel == BelId()) {
+ log_error("IO pin '%s' constrained to pin '%s', which does not exist for package '%s'.\n",
+ trio->name.c_str(ctx), pin.c_str(), ctx->args.package.c_str());
+ } else {
+ log_info("pin '%s' constrained to Bel '%s'.\n", trio->name.c_str(ctx),
+ ctx->getBelName(pinBel).c_str(ctx));
+ }
+ trio->attrs[ctx->id("BEL")] = ctx->getBelName(pinBel).str(ctx);
+ }
}
}
flush_cells();
diff --git a/ecp5/synth/blinky.v b/ecp5/synth/blinky.v
index a8f556b2..36ec7ae3 100644
--- a/ecp5/synth/blinky.v
+++ b/ecp5/synth/blinky.v
@@ -5,32 +5,32 @@ module top(input clk_pin, input btn_pin, output [7:0] led_pin, output gpio0_pin)
wire btn;
wire gpio0;
- (* BEL="X0/Y35/PIOA" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="G2" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("INPUT")) clk_buf (.B(clk_pin), .O(clk));
- (* BEL="X4/Y71/PIOA" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="R1" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("INPUT")) btn_buf (.B(btn_pin), .O(btn));
- (* BEL="X0/Y23/PIOC" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="B2" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("OUTPUT")) led_buf_0 (.B(led_pin[0]), .I(led[0]));
- (* BEL="X0/Y23/PIOD" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="C2" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("OUTPUT")) led_buf_1 (.B(led_pin[1]), .I(led[1]));
- (* BEL="X0/Y26/PIOA" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="C1" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("OUTPUT")) led_buf_2 (.B(led_pin[2]), .I(led[2]));
- (* BEL="X0/Y26/PIOC" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="D2" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("OUTPUT")) led_buf_3 (.B(led_pin[3]), .I(led[3]));
- (* BEL="X0/Y26/PIOB" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="D1" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("OUTPUT")) led_buf_4 (.B(led_pin[4]), .I(led[4]));
- (* BEL="X0/Y32/PIOD" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="E2" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("OUTPUT")) led_buf_5 (.B(led_pin[5]), .I(led[5]));
- (* BEL="X0/Y26/PIOD" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="E1" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("OUTPUT")) led_buf_6 (.B(led_pin[6]), .I(led[6]));
- (* BEL="X0/Y29/PIOD" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="H3" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("OUTPUT")) led_buf_7 (.B(led_pin[7]), .I(led[7]));
- (* BEL="X0/Y62/PIOD" *) (* IO_TYPE="LVCMOS33" *)
+ (* LOC="L2" *) (* IO_TYPE="LVCMOS33" *)
TRELLIS_IO #(.DIR("OUTPUT")) gpio0_buf (.B(gpio0_pin), .I(gpio0));
localparam ctr_width = 24;