ecp5: Add support for pin name constraints using 'LOC' attributes

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-07-18 16:01:53 +02:00
parent 5393841c66
commit c80934f953
5 changed files with 64 additions and 15 deletions

View File

@ -118,6 +118,16 @@ Arch::Arch(ArchArgs args) : args(args)
log_error("Unsupported ECP5 chip type.\n"); log_error("Unsupported ECP5 chip type.\n");
} }
#endif #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_trellis_slice = id("TRELLIS_SLICE");
id_clk = id("CLK"); 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 void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const

View File

@ -363,6 +363,7 @@ struct ArchArgs
struct Arch : BaseCtx struct Arch : BaseCtx
{ {
const ChipInfoPOD *chip_info; const ChipInfoPOD *chip_info;
const PackageInfoPOD *package_info;
mutable std::unordered_map<IdString, BelId> bel_by_name; mutable std::unordered_map<IdString, BelId> bel_by_name;
mutable std::unordered_map<IdString, WireId> wire_by_name; mutable std::unordered_map<IdString, WireId> wire_by_name;

View File

@ -68,6 +68,8 @@ int main(int argc, char *argv[])
options.add_options()("45k", "set device type to LFE5U-45F"); options.add_options()("45k", "set device type to LFE5U-45F");
options.add_options()("85k", "set device type to LFE5U-85F"); 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()("json", po::value<std::string>(), "JSON design file to ingest");
options.add_options()("seed", po::value<int>(), "seed value for random number generator"); 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; args.type = ArchArgs::LFE5U_45F;
if (vm.count("85k")) if (vm.count("85k"))
args.type = ArchArgs::LFE5U_85F; args.type = ArchArgs::LFE5U_85F;
if (vm.count("package"))
args.package = "CABGA381"; args.package = vm["package"].as<std::string>();
else
args.package = "CABGA381";
args.speed = 6; args.speed = 6;
std::unique_ptr<Context> ctx = std::unique_ptr<Context>(new Context(args)); std::unique_ptr<Context> ctx = std::unique_ptr<Context>(new Context(args));

View File

@ -232,8 +232,23 @@ class Ecp5Packer
} else { } else {
log_error("TRELLIS_IO required on all top level IOs...\n"); log_error("TRELLIS_IO required on all top level IOs...\n");
} }
packed_cells.insert(ci->name); packed_cells.insert(ci->name);
std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(trio->attrs, trio->attrs.begin())); 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(); flush_cells();

View File

@ -5,32 +5,32 @@ module top(input clk_pin, input btn_pin, output [7:0] led_pin, output gpio0_pin)
wire btn; wire btn;
wire gpio0; 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)); 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)); 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])); 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])); 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])); 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])); 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])); 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])); 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])); 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])); 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)); TRELLIS_IO #(.DIR("OUTPUT")) gpio0_buf (.B(gpio0_pin), .I(gpio0));
localparam ctr_width = 24; localparam ctr_width = 24;