Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into rapidwright-rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
gatecat committed Aug 14, 2019
2 parents bfb2383 + 3f26cf5 commit ab8dd99
Show file tree
Hide file tree
Showing 83 changed files with 1,938 additions and 1,689 deletions.
5 changes: 3 additions & 2 deletions .cirrus/Dockerfile.ubuntu16.04
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ RUN set -e -x ;\
apt-get -y install \
build-essential autoconf cmake clang bison wget flex gperf \
libreadline-dev gawk tcl-dev libffi-dev graphviz xdot python3-dev \
libboost-all-dev qt5-default git libftdi-dev pkg-config libeigen3-dev
libboost-all-dev qt5-default git libftdi-dev pkg-config libeigen3-dev \
zlib1g-dev

RUN set -e -x ;\
mkdir -p /usr/local/src ;\
Expand Down Expand Up @@ -36,7 +37,7 @@ RUN set -e -x ;\
cd /usr/local/src ;\
git clone --recursive https://github.com/YosysHQ/yosys.git ;\
cd yosys ;\
git reset --hard ea8ac0aaad3a1f89ead8eb44b2fef5927f29a099 ;\
git reset --hard 292f03355a425ede48051c79d5bf619591531080 ;\
make -j $(nproc) ;\
make install ;\
rm -rf /usr/local/src/yosys
Expand Down
9 changes: 5 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ option(USE_OPENMP "Use OpenMP to accelerate analytic placer" ON)
option(COVERAGE "Add code coverage info" OFF)
option(STATIC_BUILD "Create static build" OFF)
option(EXTERNAL_CHIPDB "Create build with pre-built chipdb binaries" OFF)
option(SERIALIZE_CHIPDB "Never build chipdb in parallel to reduce peak memory use" ON)

set(link_param "")
if (STATIC_BUILD)
Expand Down Expand Up @@ -209,7 +210,7 @@ include(bba/bba.cmake)
foreach (family ${ARCH})
message(STATUS "Configuring architecture : ${family}")
string(TOUPPER ${family} ufamily)
aux_source_directory(${family}/ ${ufamily}_FILES)
aux_source_directory(${family}/ ${ufamily}_FILES)

if (BUILD_GUI)
add_subdirectory(gui ${CMAKE_CURRENT_BINARY_DIR}/generated/gui/${family} EXCLUDE_FROM_ALL)
Expand All @@ -219,14 +220,14 @@ foreach (family ${ARCH})
add_executable(nextpnr-${family} ${COMMON_FILES} ${${ufamily}_FILES})
install(TARGETS nextpnr-${family} RUNTIME DESTINATION bin)
target_compile_definitions(nextpnr-${family} PRIVATE MAIN_EXECUTABLE)

# Add any new per-architecture targets here
if (BUILD_TESTS)
if (COVERAGE)
APPEND_COVERAGE_COMPILER_FLAGS()
set(COVERAGE_LCOV_EXCLUDES '/usr/include/*' '3rdparty/*' 'generated/*' 'bba/*' 'tests/*')
SETUP_TARGET_FOR_COVERAGE_LCOV(
NAME ${family}-coverage
NAME ${family}-coverage
EXECUTABLE nextpnr-${family}-test
DEPENDENCIES nextpnr-${family}-test
)
Expand All @@ -247,7 +248,7 @@ foreach (family ${ARCH})

# Set ${family_targets} to the list of targets being build for this family
set(family_targets nextpnr-${family})

if (BUILD_TESTS)
set(family_targets ${family_targets} nextpnr-${family}-test)
endif()
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ checking.
## Prerequisites

- Follow the [RapidWright manual install instructions](https://www.rapidwright.io/docs/Manual_Install.html)
- Make sure `$RAPIDWRIGHT_PATH` is set correctly for all further steps
- Make sure `$RAPIDWRIGHT_PATH` is set correctly for all further steps
- Download a JAR of recent [GSON](https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.5/)
- Use [this branch](https://github.com/daveshah1/yosys/tree/nextpnr_rw_usp) of Yosys

A brief (academic) paper describing the Yosys+nextpnr flow can be found
on [arXiv](https://arxiv.org/abs/1903.10407).

## Building

- Run `cmake -DARCH=rapidwright -DRAPIDWRIGHT_PATH=/path/to/rapidwright -DGSON_PATH=/path/to/gson-2.8.5.jar .`
Expand All @@ -30,9 +33,6 @@ checking.

- Run `./bbasm rapidwright/xczu2cg.bba rapidwright/xczu2cg.bin`
- This converts the text database from above to a binary database that nextpnr can _mmap_

## Running the flow

- See [rapidwright/examples](rapidwright/examples) for example scripts that run the Yosys/nextpnr/RapidWright flow,
then use Vivado to write a Verilog simulation netlist.

Expand Down
29 changes: 18 additions & 11 deletions bba/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,11 @@ int main(int argc, char **argv)
namespace po = boost::program_options;
po::positional_options_description pos;
po::options_description options("Allowed options");
options.add_options()("v", "verbose output");
options.add_options()("d", "debug output");
options.add_options()("b", "big endian");
options.add_options()("c", "write c strings");
options.add_options()("help,h", "verbose output");
options.add_options()("verbose,v", "verbose output");
options.add_options()("debug,d", "debug output");
options.add_options()("be,b", "big endian");
options.add_options()("c,c", "write c strings");
options.add_options()("files", po::value<std::vector<std::string>>(), "file parameters");
pos.add("files", -1);

Expand All @@ -97,11 +98,15 @@ int main(int argc, char **argv)
std::cout << e.what() << "\n";
return 1;
}
if (vm.count("v"))
if (vm.count("help")) {
std::cout << options;
return 0;
}
if (vm.count("verbose"))
verbose = true;
if (vm.count("d"))
if (vm.count("debug"))
debug = true;
if (vm.count("b"))
if (vm.count("be"))
bigEndian = true;
if (vm.count("c"))
writeC = true;
Expand Down Expand Up @@ -196,10 +201,12 @@ int main(int argc, char **argv)

if (cmd == "str") {
const char *value = skipWhitespace(strtok(nullptr, "\r\n"));
char terminator[2] = {*value, 0};
assert(terminator[0] != 0);
value = strtok((char *)value + 1, terminator);
const char *comment = skipWhitespace(strtok(nullptr, "\r\n"));
assert(*value != 0);
char *end = strchr((char *)value + 1, *value);
assert(end != nullptr);
*end = 0;
value += 1;
const char *comment = skipWhitespace(strtok(end + 1, "\r\n"));
std::string label = std::string("str:") + value;
Stream &s = streams.at(streamStack.back());
if (labelIndex.count(label) == 0) {
Expand Down
90 changes: 61 additions & 29 deletions common/command.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,14 @@ po::options_description CommandHandler::getGeneralOptions()
general.add_options()("freq", po::value<double>(), "set target frequency for design in MHz");
general.add_options()("timing-allow-fail", "allow timing to fail in design");
general.add_options()("no-tmdriv", "disable timing-driven placement");
general.add_options()("save", po::value<std::string>(), "project file to write");
general.add_options()("load", po::value<std::string>(), "project file to read");
return general;
}

void CommandHandler::setupContext(Context *ctx)
{
if (ctx->settings.find(ctx->id("seed")) != ctx->settings.end())
ctx->rngstate = ctx->setting<uint64_t>("seed");

if (vm.count("verbose")) {
ctx->verbose = true;
}
Expand Down Expand Up @@ -183,9 +184,9 @@ void CommandHandler::setupContext(Context *ctx)
}

if (vm.count("slack_redist_iter")) {
ctx->slack_redist_iter = vm["slack_redist_iter"].as<int>();
ctx->settings[ctx->id("slack_redist_iter")] = vm["slack_redist_iter"].as<int>();
if (vm.count("freq") && vm["freq"].as<double>() == 0) {
ctx->auto_freq = true;
ctx->settings[ctx->id("auto_freq")] = true;
#ifndef NO_GUI
if (!vm.count("gui"))
#endif
Expand All @@ -194,11 +195,11 @@ void CommandHandler::setupContext(Context *ctx)
}

if (vm.count("ignore-loops")) {
settings->set("timing/ignoreLoops", true);
ctx->settings[ctx->id("timing/ignoreLoops")] = true;
}

if (vm.count("timing-allow-fail")) {
settings->set("timing/allowFail", true);
ctx->settings[ctx->id("timing/allowFail")] = true;
}

if (vm.count("placer")) {
Expand All @@ -207,30 +208,43 @@ void CommandHandler::setupContext(Context *ctx)
Arch::availablePlacers.end())
log_error("Placer algorithm '%s' is not supported (available options: %s)\n", placer.c_str(),
boost::algorithm::join(Arch::availablePlacers, ", ").c_str());
settings->set("placer", placer);
} else {
settings->set("placer", Arch::defaultPlacer);
ctx->settings[ctx->id("placer")] = placer;
}

if (vm.count("cstrweight")) {
settings->set("placer1/constraintWeight", vm["cstrweight"].as<float>());
ctx->settings[ctx->id("placer1/constraintWeight")] = std::to_string(vm["cstrweight"].as<float>());
}
if (vm.count("starttemp")) {
settings->set("placer1/startTemp", vm["starttemp"].as<float>());
ctx->settings[ctx->id("placer1/startTemp")] = std::to_string(vm["starttemp"].as<float>());
}

if (vm.count("placer-budgets")) {
settings->set("placer1/budgetBased", true);
ctx->settings[ctx->id("placer1/budgetBased")] = true;
}
if (vm.count("freq")) {
auto freq = vm["freq"].as<double>();
if (freq > 0)
ctx->target_freq = freq * 1e6;
ctx->settings[ctx->id("target_freq")] = std::to_string(freq * 1e6);
}

ctx->timing_driven = true;
if (vm.count("no-tmdriv"))
ctx->timing_driven = false;
ctx->settings[ctx->id("timing_driven")] = false;

// Setting default values
if (ctx->settings.find(ctx->id("target_freq")) == ctx->settings.end())
ctx->settings[ctx->id("target_freq")] = std::to_string(12e6);
if (ctx->settings.find(ctx->id("timing_driven")) == ctx->settings.end())
ctx->settings[ctx->id("timing_driven")] = true;
if (ctx->settings.find(ctx->id("slack_redist_iter")) == ctx->settings.end())
ctx->settings[ctx->id("slack_redist_iter")] = 0;
if (ctx->settings.find(ctx->id("auto_freq")) == ctx->settings.end())
ctx->settings[ctx->id("auto_freq")] = false;
if (ctx->settings.find(ctx->id("placer")) == ctx->settings.end())
ctx->settings[ctx->id("placer")] = Arch::defaultPlacer;

ctx->settings[ctx->id("arch.name")] = std::string(ctx->archId().c_str(ctx));
ctx->settings[ctx->id("arch.type")] = std::string(ctx->archArgsToId(ctx->archArgs()).c_str(ctx));
ctx->settings[ctx->id("seed")] = ctx->rngstate;
}

int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
Expand All @@ -243,7 +257,7 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
#ifndef NO_GUI
if (vm.count("gui")) {
Application a(argc, argv, (vm.count("gui-no-aa") > 0));
MainWindow w(std::move(ctx), chipArgs);
MainWindow w(std::move(ctx), this);
try {
if (vm.count("json")) {
std::string filename = vm["json"].as<std::string>();
Expand All @@ -253,9 +267,7 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)

customAfterLoad(w.getContext());
w.notifyChangeContext();
w.updateLoaded();
} else if (vm.count("load")) {
w.projectLoad(vm["load"].as<std::string>());
w.updateActions();
} else
w.notifyChangeContext();
} catch (log_execution_error_exception) {
Expand Down Expand Up @@ -286,7 +298,8 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
execute_python_file(filename.c_str());
} else
#endif
if (vm.count("json") || vm.count("load")) {

if (vm.count("json")) {
bool do_pack = vm.count("pack-only") != 0 || vm.count("no-pack") == 0;
bool do_place = vm.count("pack-only") == 0 && vm.count("no-place") == 0;
bool do_route = vm.count("pack-only") == 0 && vm.count("no-route") == 0;
Expand Down Expand Up @@ -323,9 +336,6 @@ int CommandHandler::executeMain(std::unique_ptr<Context> ctx)
if (!write_json_file(f, filename, ctx.get()))
log_error("Saving design failed.\n");
}
if (vm.count("save")) {
project.save(ctx.get(), vm["save"].as<std::string>());
}

#ifndef NO_PYTHON
deinit_python();
Expand Down Expand Up @@ -361,13 +371,14 @@ int CommandHandler::exec()
if (executeBeforeContext())
return 0;

std::unique_ptr<Context> ctx;
if (vm.count("load") && vm.count("gui") == 0) {
ctx = project.load(vm["load"].as<std::string>());
} else {
ctx = createContext();
std::unordered_map<std::string, Property> values;
if (vm.count("json")) {
std::string filename = vm["json"].as<std::string>();
std::ifstream f(filename);
if (!load_json_settings(f, filename, values))
log_error("Loading design failed.\n");
}
settings = std::unique_ptr<Settings>(new Settings(ctx.get()));
std::unique_ptr<Context> ctx = createContext(values);
setupContext(ctx.get());
setupArchContext(ctx.get());
int rc = executeMain(std::move(ctx));
Expand All @@ -379,6 +390,27 @@ int CommandHandler::exec()
}
}

std::unique_ptr<Context> CommandHandler::load_json(std::string filename)
{
vm.clear();
std::unordered_map<std::string, Property> values;
{
std::ifstream f(filename);
if (!load_json_settings(f, filename, values))
log_error("Loading design failed.\n");
}
std::unique_ptr<Context> ctx = createContext(values);
setupContext(ctx.get());
setupArchContext(ctx.get());
{
std::ifstream f(filename);
if (!parse_json_file(f, filename, ctx.get()))
log_error("Loading design failed.\n");
}
customAfterLoad(ctx.get());
return ctx;
}

void CommandHandler::run_script_hook(const std::string &name)
{
#ifndef NO_PYTHON
Expand Down
10 changes: 4 additions & 6 deletions common/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
#define COMMAND_H

#include <boost/program_options.hpp>
#include <fstream>
#include "log.h"
#include "nextpnr.h"
#include "project.h"
#include "settings.h"

NEXTPNR_NAMESPACE_BEGIN

Expand All @@ -37,10 +37,11 @@ class CommandHandler
virtual ~CommandHandler(){};

int exec();
std::unique_ptr<Context> load_json(std::string filename);

protected:
virtual void setupArchContext(Context *ctx) = 0;
virtual std::unique_ptr<Context> createContext() = 0;
virtual std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) = 0;
virtual po::options_description getArchOptions() = 0;
virtual void validate(){};
virtual void customAfterLoad(Context *ctx){};
Expand All @@ -58,15 +59,12 @@ class CommandHandler

protected:
po::variables_map vm;
ArchArgs chipArgs;
std::unique_ptr<Settings> settings;

private:
po::options_description options;
po::positional_options_description pos;
int argc;
char **argv;
ProjectHandler project;
std::ofstream logfile;
};

Expand Down
Loading

0 comments on commit ab8dd99

Please sign in to comment.