Working FF example now that constant merging is done.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
2fc353d559
commit
5574455d2a
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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]
|
||||
|
@ -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()) {
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user