From 72f5e640af8bdccb641bb561757021c0a3d83edb Mon Sep 17 00:00:00 2001 From: David Shah Date: Sat, 9 Jun 2018 19:38:37 +0200 Subject: Adding basic placement constraints Specify the attribute (* LOC="bel_name" *) on any cell to constrain its placement to that bel. Signed-off-by: David Shah --- common/place.cc | 40 +++++++++++++++++++++++++- common/route.cc | 2 +- ice40/blinky.v | 80 +++++++++++++++++++++++++++++++++++++++++++++++++-- python/dump_design.py | 2 +- 4 files changed, 118 insertions(+), 6 deletions(-) diff --git a/common/place.cc b/common/place.cc index 42e366c6..8f174478 100644 --- a/common/place.cc +++ b/common/place.cc @@ -38,8 +38,38 @@ void place_design(Design *design) std::set::iterator not_found, element; std::set used_bels; + // Initial constraints placer for (auto cell_entry : design->cells) { CellInfo *cell = cell_entry.second; + auto loc = cell->attrs.find("LOC"); + if (loc != cell->attrs.end()) { + std::string loc_name = loc->second; + BelId bel = design->chip.getBelByName(IdString(loc_name)); + if (bel == BelId()) { + log_error("No Bel named \'%s\' located for " + "this chip (processing LOC on \'%s\')\n", + loc_name.c_str(), cell->name.c_str()); + } + + BelType bel_type = design->chip.getBelType(bel); + if (bel_type != belTypeFromId(cell->type)) { + log_error("Bel \'%s\' of type \'%s\' does not match cell " + "\'%s\' of type \'%s\'", + loc_name.c_str(), belTypeToId(bel_type).c_str(), + cell->name.c_str(), cell->type.c_str()); + } + + cell->bel = bel; + design->chip.bindBel(bel, cell->name); + } + } + + for (auto cell_entry : design->cells) { + CellInfo *cell = cell_entry.second; + // Ignore already placed cells + if (cell->bel != BelId()) + continue; + BelType bel_type; element = types_used.find(cell->type); @@ -64,17 +94,25 @@ void place_design(Design *design) for (auto cell_entry : design->cells) { CellInfo *cell = cell_entry.second; + // Ignore already placed cells + if (cell->bel != BelId()) + continue; // Only place one type of Bel at a time if (cell->type.compare(bel_type_name) != 0) continue; while ((bi != blist.end()) && - (design->chip.getBelType(*bi) != bel_type)) + ((design->chip.getBelType(*bi) != bel_type || + !design->chip.checkBelAvail(*bi)))) bi++; if (bi == blist.end()) log_error("Too many \'%s\' used in design\n", cell->type.c_str()); cell->bel = *bi++; + design->chip.bindBel(cell->bel, cell->name); + + // Back annotate location + cell->attrs["LOC"] = design->chip.getBelName(cell->bel); } } } diff --git a/common/route.cc b/common/route.cc index 28a51bc6..b57bc29f 100644 --- a/common/route.cc +++ b/common/route.cc @@ -37,7 +37,7 @@ template <> struct greater return lhs.delay.avgDelay() > rhs.delay.avgDelay(); } }; -} +} // namespace std void route_design(Design *design) { diff --git a/ice40/blinky.v b/ice40/blinky.v index 6b97c5a9..80f92b06 100644 --- a/ice40/blinky.v +++ b/ice40/blinky.v @@ -7,24 +7,98 @@ module blinky ( output led5_pin ); wire clk, led1, led2, led3, led4, led5; + + (* LOC="0_3_lc0" *) + SB_IO #( + .PIN_TYPE(6'b 0110_01), + .PULLUP(1'b0), + .NEG_TRIGGER(1'b0) + ) led1_iob ( + .PACKAGE_PIN(led1_pin), + .LATCH_INPUT_VALUE(), + .CLOCK_ENABLE(), + .INPUT_CLK(), + .OUTPUT_CLK(), + .OUTPUT_ENABLE(), + .D_OUT_0(led1), + .D_OUT_1(), + .D_IN_0(), + .D_IN_1() + ); + + (* LOC="0_3_lc1" *) + SB_IO #( + .PIN_TYPE(6'b 0110_01), + .PULLUP(1'b0), + .NEG_TRIGGER(1'b0) + ) led2_iob ( + .PACKAGE_PIN(led2_pin), + .LATCH_INPUT_VALUE(), + .CLOCK_ENABLE(), + .INPUT_CLK(), + .OUTPUT_CLK(), + .OUTPUT_ENABLE(), + .D_OUT_0(led2), + .D_OUT_1(), + .D_IN_0(), + .D_IN_1() + ); + + (* LOC="5_17_lc1" *) + SB_IO #( + .PIN_TYPE(6'b 0110_01), + .PULLUP(1'b0), + .NEG_TRIGGER(1'b0) + ) led3_iob ( + .PACKAGE_PIN(led3_pin), + .LATCH_INPUT_VALUE(), + .CLOCK_ENABLE(), + .INPUT_CLK(), + .OUTPUT_CLK(), + .OUTPUT_ENABLE(), + .D_OUT_0(led3), + .D_OUT_1(), + .D_IN_0(), + .D_IN_1() + ); + + (* LOC="10_0_lc1" *) + SB_IO #( + .PIN_TYPE(6'b 0110_01), + .PULLUP(1'b0), + .NEG_TRIGGER(1'b0) + ) led4_iob ( + .PACKAGE_PIN(led4_pin), + .LATCH_INPUT_VALUE(), + .CLOCK_ENABLE(), + .INPUT_CLK(), + .OUTPUT_CLK(), + .OUTPUT_ENABLE(), + .D_OUT_0(led4), + .D_OUT_1(), + .D_IN_0(), + .D_IN_1() + ); + (* LOC="12_17_lc0" *) SB_IO #( .PIN_TYPE(6'b 0110_01), .PULLUP(1'b0), .NEG_TRIGGER(1'b0) - ) led_iob [4:0] ( - .PACKAGE_PIN({led1_pin, led2_pin, led3_pin, led4_pin, led5_pin}), + ) led5_iob ( + .PACKAGE_PIN(led5_pin), .LATCH_INPUT_VALUE(), .CLOCK_ENABLE(), .INPUT_CLK(), .OUTPUT_CLK(), .OUTPUT_ENABLE(), - .D_OUT_0({led1, led2, led3, led4, led5}), + .D_OUT_0(led5), .D_OUT_1(), .D_IN_0(), .D_IN_1() ); + (* LOC="0_6_lc0" *) SB_IO #( .PIN_TYPE(6'b 0000_01), .PULLUP(1'b0), diff --git a/python/dump_design.py b/python/dump_design.py index d95f041b..3972f4dc 100644 --- a/python/dump_design.py +++ b/python/dump_design.py @@ -20,6 +20,6 @@ for cell, cinfo in sorted(design.cells, key=lambda x: x.first): val = "{}'b{}".format(len(val), val) print("\t\t{}: {}".format(param, val)) - if not cinfo.bel.nil(): + if cinfo.bel != -1: print("\tBel: {}".format(chip.getBelName(cinfo.bel))) print() -- cgit v1.2.3