From 109287ee90cf5d7a7858d04dbc0fea595981538f Mon Sep 17 00:00:00 2001 From: ZipCPU Date: Wed, 6 Jun 2018 17:17:44 -0400 Subject: [PATCH 1/5] Removed unused set of warnings from log.cc --- common/log.cc | 2 -- common/log.h | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/common/log.cc b/common/log.cc index 84150a15..00e1765f 100644 --- a/common/log.cc +++ b/common/log.cc @@ -31,8 +31,6 @@ std::vector log_files; std::vector log_streams; -std::map> log_hdump; -bool log_hdump_all = false; FILE *log_errfile = NULL; bool log_error_stderr = false; diff --git a/common/log.h b/common/log.h index 259a30a1..2bf1604a 100644 --- a/common/log.h +++ b/common/log.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -38,9 +39,6 @@ struct log_cmd_error_exception { }; extern std::vector log_files; extern std::vector log_streams; -extern std::set log_warnings; -extern int log_warnings_count; -extern bool log_hdump_all; extern FILE *log_errfile; extern bool log_quiet_warnings; @@ -54,6 +52,7 @@ void logv_warning_noprefix(const char *format, va_list ap); NXP_NORETURN void logv_error(const char *format, va_list ap) NXP_ATTRIBUTE(noreturn); +extern std::ostream clog; void log(const char *format, ...); void log_header(const char *format, ...); void log_info(const char *format, ...); From d7bb30cc66f2ba39c77a979b809a6e6bdfcb5097 Mon Sep 17 00:00:00 2001 From: ZipCPU Date: Thu, 7 Jun 2018 07:38:35 -0400 Subject: [PATCH 2/5] added ports (not ports_directions) to jsonparse.cc --- frontend/json/jsonparse.cc | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/frontend/json/jsonparse.cc b/frontend/json/jsonparse.cc index 25b01e44..41ecebd4 100644 --- a/frontend/json/jsonparse.cc +++ b/frontend/json/jsonparse.cc @@ -34,7 +34,7 @@ extern bool check_all_nets_driven(Design *design); namespace JsonParser { - const bool json_debug = false; + const bool json_debug = true; typedef std::string string; @@ -566,13 +566,24 @@ void json_import_cell(Design *design, string modname, JsonNode *cell_node, // Both should contain dictionaries having the same keys. // - JsonNode *pdir_node - = cell_node->data_dict.at("port_directions"); - if (pdir_node->type != 'D') - log_error("JSON port_directions node of \'%s\' " - "in module \'%s\' is not a " - "dictionary\n", cell->name.c_str(), - modname.c_str()); + JsonNode *pdir_node = NULL; + if (cell_node->data_dict.count("port_directions") > 0) { + + pdir_node = cell_node->data_dict.at("port_directions"); + if (pdir_node->type != 'D') + log_error("JSON port_directions node of \'%s\' " + "in module \'%s\' is not a " + "dictionary\n", cell->name.c_str(), + modname.c_str()); + + } else if (cell_node->data_dict.count("ports") > 0) { + pdir_node = cell_node->data_dict.at("ports"); + if (pdir_node->type != 'D') + log_error("JSON ports node of \'%s\' " + "in module \'%s\' is not a " + "dictionary\n", cell->name.c_str(), + modname.c_str()); + } JsonNode *connections = cell_node->data_dict.at("connections"); From 0dbfa4662f74b89c5f3f8c4fa5ebbef6a89d532b Mon Sep 17 00:00:00 2001 From: ZipCPU Date: Thu, 7 Jun 2018 07:52:05 -0400 Subject: [PATCH 3/5] Preliminary placer changes to main --- CMakeLists.txt | 1 + ice40/main.cc | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index dfc33e90..02e67e87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,7 @@ include_directories(common/ gui/ frontend/json ${Boost_INCLUDE_DIRS} ${PYTHON_IN aux_source_directory(common/ COMMON_SRC_FILES) aux_source_directory(frontend/json/ JSON_PARSER_FILES) set(COMMON_FILES ${COMMON_SRC_FILES} ${JSON_PARSER_FILES}) +set(CMAKE_BUILD_TYPE Debug) foreach (family ${FAMILIES}) string(TOUPPER ${family} ufamily) diff --git a/ice40/main.cc b/ice40/main.cc index d47076fd..b723c1fd 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -25,6 +25,7 @@ #include "mainwindow.h" #include "pybindings.h" #include "version.h" +#include "log.h" void svg_dump_el(const GraphicElement &el) { @@ -52,6 +53,8 @@ int main(int argc, char *argv[]) int rc = 0; std::string str; + log_files.push_back(stdout); + po::options_description options("Allowed options"); options.add_options()("help,h", "show help"); options.add_options()("test", "just a check"); @@ -247,6 +250,10 @@ int main(int argc, char *argv[]) execute_python_file(filename.c_str()); } + extern void place_design(Design *d); + place_design(&design); + + if (vm.count("gui")) { QApplication a(argc, argv); MainWindow w; From f32b9622d5c61610f6027f6544ab9683cd57282b Mon Sep 17 00:00:00 2001 From: ZipCPU Date: Thu, 7 Jun 2018 09:38:14 -0400 Subject: [PATCH 4/5] 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++. --- common/place.cc | 82 ++++++++++++++++++++++++++++++++++++++ common/rulecheck.cc | 15 ++++--- frontend/json/jsonparse.cc | 20 +++++++++- ice40/chip.h | 13 +++++- 4 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 common/place.cc diff --git a/common/place.cc b/common/place.cc new file mode 100644 index 00000000..d3348820 --- /dev/null +++ b/common/place.cc @@ -0,0 +1,82 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "design.h" + +namespace Placer { +}; + +void place_design(Design *design) { + std::set types_used; + std::set::iterator not_found, element; + std::set 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++; + } + } +} + diff --git a/common/rulecheck.cc b/common/rulecheck.cc index 28d4b6b7..11e57b8b 100644 --- a/common/rulecheck.cc +++ b/common/rulecheck.cc @@ -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); + } } } diff --git a/frontend/json/jsonparse.cc b/frontend/json/jsonparse.cc index 41ecebd4..3d7c52ea 100644 --- a/frontend/json/jsonparse.cc +++ b/frontend/json/jsonparse.cc @@ -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; diff --git a/ice40/chip.h b/ice40/chip.h index 695eea48..dd00c7c8 100644 --- a/ice40/chip.h +++ b/ice40/chip.h @@ -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; From c352f6536b8f9eb4ad8d108e692a149348284723 Mon Sep 17 00:00:00 2001 From: ZipCPU Date: Thu, 7 Jun 2018 09:49:21 -0400 Subject: [PATCH 5/5] Moved placer definitions to place.h, main automatically runs placer now --- common/place.cc | 4 +--- common/place.h | 26 ++++++++++++++++++++++++++ ice40/main.cc | 5 ++--- 3 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 common/place.h diff --git a/common/place.cc b/common/place.cc index d3348820..e27a46be 100644 --- a/common/place.cc +++ b/common/place.cc @@ -30,9 +30,7 @@ #include "log.h" #include "design.h" - -namespace Placer { -}; +#include "place.h" void place_design(Design *design) { std::set types_used; diff --git a/common/place.h b/common/place.h new file mode 100644 index 00000000..483f11f3 --- /dev/null +++ b/common/place.h @@ -0,0 +1,26 @@ +/* + * nextpnr -- Next Generation Place and Route + * + * Copyright (C) 2018 Clifford Wolf + * + * 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. + * + */ +#ifndef PLACE_H +#define PLACE_H + +#include "design.h" + +extern void place_design(Design *design); + +#endif // PLACE_H diff --git a/ice40/main.cc b/ice40/main.cc index b723c1fd..24897164 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -26,6 +26,7 @@ #include "pybindings.h" #include "version.h" #include "log.h" +#include "place.h" void svg_dump_el(const GraphicElement &el) { @@ -241,6 +242,7 @@ int main(int argc, char *argv[]) std::istream *f = new std::ifstream(filename); parse_json_file(f, filename, &design); + place_design(&design); } if (vm.count("run")) { @@ -250,9 +252,6 @@ int main(int argc, char *argv[]) execute_python_file(filename.c_str()); } - extern void place_design(Design *d); - place_design(&design); - if (vm.count("gui")) { QApplication a(argc, argv);