Initial (random) placer capability

This commit also includes changes to jsonparse to allow it to
1) recognize ports with no connection, and set their net pointers to NULL
2) recognize designs with a ports node rather than a ports_direction

The rule checker has also been modified to accommodate possible NULL netlists

The ice40 chip now also has iterator operations ++bi and bi++.
This commit is contained in:
ZipCPU 2018-06-07 09:38:14 -04:00
parent 0dbfa4662f
commit f32b9622d5
4 changed files with 123 additions and 7 deletions

82
common/place.cc Normal file
View File

@ -0,0 +1,82 @@
/*
* nextpnr -- Next Generation Place and Route
*
* Copyright (C) 2018 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include <iostream>
#include <ostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <vector>
#include <list>
#include <map>
#include <set>
#include "log.h"
#include "design.h"
namespace Placer {
};
void place_design(Design *design) {
std::set<IdString> types_used;
std::set<IdString>::iterator not_found, element;
std::set<BelType> used_bels;
for(auto cell_entry : design->cells) {
CellInfo *cell = cell_entry.second;
BelType bel_type;
element = types_used.find(cell->type);
if (element != types_used.end()) {
continue;
}
bel_type = belTypeFromId(cell->type);
if (bel_type == TYPE_NIL) {
log_error("No Bel of type \'%s\' defined for "
"this chip\n", cell->type.c_str());
}
types_used.insert(cell->type);
std::cout << cell->type << std::endl;
}
for(auto bel_type_name : types_used) {
BelRange blist = design->chip.getBels();
BelType bel_type = belTypeFromId(bel_type_name);
BelIterator bi = blist.begin();
for(auto cell_entry : design->cells) {
CellInfo *cell = cell_entry.second;
// 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))
bi++;
if (bi == blist.end())
log_error("Too many \'%s\' used in design\n",
cell->type.c_str());
cell->bel = *bi++;
}
}
}

View File

@ -21,12 +21,17 @@ bool check_all_nets_driven(Design *design) {
port_entry.first.c_str(),
port.name.c_str());
assert(port.name.compare(port_entry.first)==0);
assert(port.net);
assert(port.name.size() > 0);
if (debug) log_info(" Checking for a net named \'%s\'\n",
port.net->name.c_str());
assert(design->nets.count(port.net->name)>0);
// assert(design->nets[port.net->name]->driver.cell);
if (port.net == NULL) {
if (debug) log_warning(" Port \'%s\' in cell \'%s\' is unconnected\n",
port.name.c_str(), cell->name.c_str());
} else {
assert(port.net);
if (debug) log_info(" Checking for a net named \'%s\'\n",
port.net->name.c_str());
assert(design->nets.count(port.net->name)>0);
}
}
}

View File

@ -413,7 +413,25 @@ void json_import_cell_ports(Design *design, string &modname, CellInfo *cell,
is_bus = (wire_group_node->data_array.size()>1);
// Now loop through all of the connections to this port.
for(int index=0; index < wire_group_node->data_array.size(); index++) {
if (wire_group_node->data_array.size() == 0) {
//
// There is/are no connections to this port.
//
// Create the port, but leave the net NULL
PortInfo this_port;
//
this_port.name = port_info.name;
this_port.type = port_info.type;
this_port.net = NULL;
cell->ports[this_port.name] = this_port;
if (json_debug) log_info(" Port \'%s\' has no connection in \'%s\'\n",
this_port.name.c_str(), cell->name.c_str());
} else for(int index=0; index < wire_group_node->data_array.size();
index++) {
//
JsonNode *wire_node;
PortInfo this_port;

View File

@ -276,12 +276,23 @@ struct BelIterator
{
int cursor;
void operator++() { cursor++; }
BelIterator operator++() { cursor++; return *this; }
BelIterator operator++(int) {
BelIterator prior(*this);
cursor++;
return prior;
}
bool operator!=(const BelIterator &other) const
{
return cursor != other.cursor;
}
bool operator==(const BelIterator &other) const
{
return cursor == other.cursor;
}
BelId operator*() const
{
BelId ret;