diff options
| author | Keith Rothman <537074+litghost@users.noreply.github.com> | 2021-02-19 17:28:25 -0800 | 
|---|---|---|
| committer | Keith Rothman <537074+litghost@users.noreply.github.com> | 2021-02-23 14:09:28 -0800 | 
| commit | 5574455d2a20d3bb950e5dd907ef193d049a2a26 (patch) | |
| tree | 575a82d63b89f61f0a6d96afd33f3bd804dcfad8 /fpga_interchange | |
| parent | 2fc353d5592b0bf9ed8428545bbd6a64312cc16e (diff) | |
| download | nextpnr-5574455d2a20d3bb950e5dd907ef193d049a2a26.tar.gz nextpnr-5574455d2a20d3bb950e5dd907ef193d049a2a26.tar.bz2 nextpnr-5574455d2a20d3bb950e5dd907ef193d049a2a26.zip | |
Working FF example now that constant merging is done.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
Diffstat (limited to 'fpga_interchange')
| -rw-r--r-- | fpga_interchange/arch.cc | 187 | ||||
| -rw-r--r-- | fpga_interchange/arch.h | 4 | ||||
| -rw-r--r-- | fpga_interchange/archdefs.h | 1 | ||||
| -rw-r--r-- | fpga_interchange/examples/template.mk | 18 | ||||
| -rw-r--r-- | fpga_interchange/examples/wire/wire.xdc | 3 | ||||
| -rw-r--r-- | fpga_interchange/fpga_interchange.cpp | 13 | 
6 files changed, 218 insertions, 8 deletions
| diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc index 0955c376..966d74f3 100644 --- a/fpga_interchange/arch.cc +++ b/fpga_interchange/arch.cc @@ -606,6 +606,7 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay  bool Arch::pack()  { +    merge_constant_nets();      pack_ports();      return true;  } @@ -754,7 +755,7 @@ const std::vector<std::string> Arch::availablePlacers = {"sa",  const std::string Arch::defaultRouter = "router2";  const std::vector<std::string> Arch::availableRouters = {"router1", "router2"}; -void Arch::map_cell_pins(CellInfo *cell, int32_t mapping) const +void Arch::map_cell_pins(CellInfo *cell, int32_t mapping)  {      cell->cell_mapping = mapping;      cell->cell_bel_pins.clear(); @@ -766,11 +767,32 @@ void Arch::map_cell_pins(CellInfo *cell, int32_t mapping) const          IdString bel_pin(pin_map.bel_pin);          if (cell_pin.str(this) == "GND") { -            // FIXME: Tie this pin to the GND net +            PortInfo port_info; +            port_info.name = bel_pin; +            port_info.type = PORT_IN; +            port_info.net = nullptr; + +            auto result = cell->ports.emplace(bel_pin, port_info); +            NPNR_ASSERT(result.second); + +            cell->cell_bel_pins[bel_pin].push_back(bel_pin); + +            connectPort(IdString(chip_info->constants->gnd_net_name), cell->name, bel_pin);              continue;          } +          if (cell_pin.str(this) == "VCC") { -            // FIXME: Tie this pin to the VCC net +            PortInfo port_info; +            port_info.name = bel_pin; +            port_info.type = PORT_IN; +            port_info.net = nullptr; + +            auto result = cell->ports.emplace(bel_pin, port_info); +            NPNR_ASSERT(result.second); + +            cell->cell_bel_pins[bel_pin].push_back(bel_pin); + +            connectPort(IdString(chip_info->constants->vcc_net_name), cell->name, bel_pin);              continue;          } @@ -795,11 +817,30 @@ void Arch::map_cell_pins(CellInfo *cell, int32_t mapping) const              IdString bel_pin(pin_map.bel_pin);              if (cell_pin.str(this) == "GND") { -                // FIXME: Tie this pin to the GND net +                PortInfo port_info; +                port_info.name = bel_pin; +                port_info.type = PORT_IN; + +                auto result = cell->ports.emplace(bel_pin, port_info); +                NPNR_ASSERT(result.second); + +                cell->cell_bel_pins[bel_pin].push_back(bel_pin); + +                connectPort(IdString(chip_info->constants->gnd_net_name), cell->name, bel_pin);                  continue;              } +              if (cell_pin.str(this) == "VCC") { -                // FIXME: Tie this pin to the VCC net +                PortInfo port_info; +                port_info.name = bel_pin; +                port_info.type = PORT_IN; + +                auto result = cell->ports.emplace(bel_pin, port_info); +                NPNR_ASSERT(result.second); + +                cell->cell_bel_pins[bel_pin].push_back(bel_pin); + +                connectPort(IdString(chip_info->constants->vcc_net_name), cell->name, bel_pin);                  continue;              } @@ -858,6 +899,142 @@ size_t Arch::get_cell_type_index(IdString cell_type) const      return cell_offset;  } +void Arch::merge_constant_nets() { +    NetInfo* gnd_net = nullptr; +    NetInfo* vcc_net = nullptr; + +    bool need_gnd_source = false; +    bool need_vcc_source = false; + +    IdString gnd_net_name(chip_info->constants->gnd_net_name); +    IdString gnd_cell_type(chip_info->constants->gnd_cell_name); +    IdString gnd_cell_port(chip_info->constants->gnd_cell_port); + +    auto gnd_iter = nets.find(gnd_net_name); +    if(gnd_iter != nets.end()) { +        NPNR_ASSERT(gnd_iter->second->driver.cell != nullptr); +        NPNR_ASSERT(gnd_iter->second->driver.cell->type == gnd_cell_type); +        NPNR_ASSERT(gnd_iter->second->driver.port == gnd_cell_port); + +        gnd_net = gnd_iter->second.get(); +    } else { +        gnd_net = createNet(gnd_net_name); +        need_gnd_source = true; +    } + +    IdString vcc_net_name(chip_info->constants->vcc_net_name); +    IdString vcc_cell_type(chip_info->constants->vcc_cell_name); +    IdString vcc_cell_port(chip_info->constants->vcc_cell_port); + +    auto vcc_iter = nets.find(vcc_net_name); +    if(vcc_iter != nets.end()) { +        NPNR_ASSERT(vcc_iter->second->driver.cell != nullptr); +        NPNR_ASSERT(vcc_iter->second->driver.cell->type == vcc_cell_type); +        NPNR_ASSERT(vcc_iter->second->driver.port == vcc_cell_port); + +        vcc_net = vcc_iter->second.get(); +    } else { +        vcc_net = createNet(vcc_net_name); +        need_vcc_source = true; +    } + +    std::vector<IdString> other_gnd_nets; +    std::vector<IdString> other_vcc_nets; + +    for(auto & net_pair : nets) { +        if(net_pair.first == gnd_net_name) { +            NPNR_ASSERT(net_pair.second.get() == gnd_net); +            continue; +        } + +        if(net_pair.first == vcc_net_name) { +            NPNR_ASSERT(net_pair.second.get() == vcc_net); +            continue; +        } + +        NetInfo *net = net_pair.second.get(); +        if(net->driver.cell == nullptr) { +            continue; +        } + +        if(net->driver.cell->type == gnd_cell_type) { +            NPNR_ASSERT(net->driver.port == gnd_cell_port); + +            other_gnd_nets.push_back(net_pair.first); + +            if(need_gnd_source) { +                IdString driver_cell = net->driver.cell->name; +                disconnectPort(driver_cell, gnd_cell_port); +                connectPort(gnd_net_name, driver_cell, gnd_cell_port); +                need_gnd_source = false; +            } + +            NPNR_ASSERT(net->driver.port == gnd_cell_port); +            std::vector<PortRef> users_copy = net->users; +            for(const PortRef & port_ref : users_copy) { +                IdString cell = port_ref.cell->name; +                disconnectPort(cell, port_ref.port); +                connectPort(gnd_net_name, cell, port_ref.port); +            } +        } + +        if(net->driver.cell->type == vcc_cell_type) { +            NPNR_ASSERT(net->driver.port == vcc_cell_port); + +            other_vcc_nets.push_back(net_pair.first); + +            if(need_vcc_source) { +                IdString driver_cell = net->driver.cell->name; +                disconnectPort(driver_cell, vcc_cell_port); +                connectPort(vcc_net_name, driver_cell, vcc_cell_port); +                need_vcc_source = false; +            } + +            NPNR_ASSERT(net->driver.port == vcc_cell_port); +            std::vector<PortRef> users_copy = net->users; +            for(const PortRef & port_ref : users_copy) { +                IdString cell = port_ref.cell->name; +                disconnectPort(cell, port_ref.port); +                connectPort(vcc_net_name, cell, port_ref.port); +            } +        } +    } + +    for(IdString other_gnd_net : other_gnd_nets) { +        NetInfo * net = getNetByAlias(other_gnd_net); +        NPNR_ASSERT(net->users.empty()); +    } + +    for(IdString other_vcc_net : other_vcc_nets) { +        NetInfo * net = getNetByAlias(other_vcc_net); +        NPNR_ASSERT(net->users.empty()); +    } + +    for(IdString other_gnd_net : other_gnd_nets) { +        NPNR_ASSERT(nets.erase(other_gnd_net)); +        gnd_net->aliases.push_back(other_gnd_net); +        net_aliases[other_gnd_net] = gnd_net_name; +    } + +    for(IdString other_vcc_net : other_vcc_nets) { +        NPNR_ASSERT(nets.erase(other_vcc_net)); +        vcc_net->aliases.push_back(other_vcc_net); +        net_aliases[other_vcc_net] = vcc_net_name; +    } + +    if(need_gnd_source) { +        CellInfo * gnd_cell = createCell(gnd_cell_type, gnd_cell_type); +        gnd_cell->addOutput(gnd_cell_port); +        connectPort(gnd_net_name, gnd_cell_type, gnd_cell_port); +    } + +    if(need_vcc_source) { +        CellInfo * vcc_cell = createCell(vcc_cell_type, vcc_cell_type); +        vcc_cell->addOutput(vcc_cell_port); +        connectPort(vcc_net_name, vcc_cell_type, vcc_cell_port); +    } +} +  // Instance constraint templates.  template void Arch::ArchConstraints::bindBel(Arch::ArchConstraints::TagState *, const Arch::ConstraintRange);  template void Arch::ArchConstraints::unbindBel(Arch::ArchConstraints::TagState *, const Arch::ConstraintRange); diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h index 780382ec..c713ddb9 100644 --- a/fpga_interchange/arch.h +++ b/fpga_interchange/arch.h @@ -871,7 +871,7 @@ struct Arch : ArchAPI<ArchRanges>      uint32_t getBelChecksum(BelId bel) const override { return bel.index; } -    void map_cell_pins(CellInfo *cell, int32_t mapping) const; +    void map_cell_pins(CellInfo *cell, int32_t mapping);      void map_port_pins(BelId bel, CellInfo *cell) const;      TileStatus &get_tile_status(int32_t tile) @@ -1716,6 +1716,8 @@ struct Arch : ArchAPI<ArchRanges>              return is_bel_synthetic(bel);          }      } + +    void merge_constant_nets();  };  NEXTPNR_NAMESPACE_END diff --git a/fpga_interchange/archdefs.h b/fpga_interchange/archdefs.h index 75af6974..33d999bb 100644 --- a/fpga_interchange/archdefs.h +++ b/fpga_interchange/archdefs.h @@ -106,6 +106,7 @@ struct ArchCellInfo      int32_t cell_mapping;      std::unordered_map<IdString, std::vector<IdString>> cell_bel_pins; +    std::unordered_set<IdString> const_ports;  };  NEXTPNR_NAMESPACE_END diff --git a/fpga_interchange/examples/template.mk b/fpga_interchange/examples/template.mk index d12a4e11..c795544e 100644 --- a/fpga_interchange/examples/template.mk +++ b/fpga_interchange/examples/template.mk @@ -55,6 +55,15 @@ verbose: build/$(DESIGN).netlist  		--package $(PACKAGE) \  		--verbose +verbose2: build/$(DESIGN).netlist +	$(NEXTPNR_BIN) \ +		--chipdb $(BBA_PATH) \ +		--xdc $(DESIGN).xdc \ +		--netlist build/$(DESIGN).netlist \ +		--phys build/$(DESIGN).phys \ +		--package $(PACKAGE) \ +		--debug +  debug: build/$(DESIGN).netlist  	gdb --args $(NEXTPNR_BIN) \  		--chipdb $(BBA_PATH) \ @@ -63,6 +72,15 @@ debug: build/$(DESIGN).netlist  		--phys build/$(DESIGN).phys \  		--package $(PACKAGE) +debug_verbose: build/$(DESIGN).netlist +	gdb --args $(NEXTPNR_BIN) \ +		--chipdb $(BBA_PATH) \ +		--xdc $(DESIGN).xdc \ +		--netlist build/$(DESIGN).netlist \ +		--phys build/$(DESIGN).phys \ +		--package $(PACKAGE) \ +		--verbose +  build/$(DESIGN).dcp: build/$(DESIGN).netlist build/$(DESIGN).phys $(DESIGN).xdc  	RAPIDWRIGHT_PATH=$(RAPIDWRIGHT_PATH) \  		$(RAPIDWRIGHT_PATH)/scripts/invoke_rapidwright.sh \ diff --git a/fpga_interchange/examples/wire/wire.xdc b/fpga_interchange/examples/wire/wire.xdc index e1fce5f0..c923f0fc 100644 --- a/fpga_interchange/examples/wire/wire.xdc +++ b/fpga_interchange/examples/wire/wire.xdc @@ -1,2 +1,5 @@  set_property PACKAGE_PIN N16 [get_ports i]  set_property PACKAGE_PIN N15 [get_ports o] + +set_property IOSTANDARD LVCMOS33 [get_ports i] +set_property IOSTANDARD LVCMOS33 [get_ports o] diff --git a/fpga_interchange/fpga_interchange.cpp b/fpga_interchange/fpga_interchange.cpp index fd57e09c..027513c8 100644 --- a/fpga_interchange/fpga_interchange.cpp +++ b/fpga_interchange/fpga_interchange.cpp @@ -269,8 +269,10 @@ static void find_non_synthetic_edges(const Context * ctx, WireId root_wire,          auto downhill_iter = pip_downhill.find(wire);          if(downhill_iter == pip_downhill.end()) { -            log_warning("Wire %s never entered the real fabric?\n", -                    ctx->nameOfWire(wire)); +            if(root_wire != wire) { +                log_warning("Wire %s never entered the real fabric?\n", +                        ctx->nameOfWire(wire)); +            }              continue;          } @@ -365,6 +367,9 @@ void FpgaInterchange::write_physical_netlist(const Context * ctx, const std::str              // Don't emit pin map for ports.              size_t pin_count = 0;              for(const auto & pin : cell.cell_bel_pins) { +                if(cell.const_ports.count(pin.first)) { +                    continue; +                }                  pin_count += pin.second.size();              } @@ -372,6 +377,10 @@ void FpgaInterchange::write_physical_netlist(const Context * ctx, const std::str              auto pin_iter = pins.begin();              for(const auto & cell_to_bel_pins : cell.cell_bel_pins) { +                if(cell.const_ports.count(cell_to_bel_pins.first)) { +                    continue; +                } +                  std::string cell_pin = cell_to_bel_pins.first.str(ctx);                  size_t cell_pin_index = strings.get_index(cell_pin); | 
