Read settings and check validity
diff --git a/common/project.cc b/common/project.cc
index 8ee78c4..b0ebe96 100644
--- a/common/project.cc
+++ b/common/project.cc
@@ -70,8 +70,7 @@
         root.put("project.params.freq", int(ctx->target_freq / 1e6));
         root.put("project.params.seed", ctx->rngstate);
         saveArch(ctx, root, proj.parent_path().string());
-        for(auto const &item : ctx->settings)
-        {
+        for (auto const &item : ctx->settings) {
             std::string path = "project.settings.";
             path += item.first.c_str(ctx);
             std::replace(path.begin(), path.end(), '/', '.');
@@ -83,6 +82,19 @@
     }
 }
 
+void addSettings(Context *ctx, std::string path, pt::ptree sub)
+{
+    for (pt::ptree::value_type &v : sub) {
+        const std::string &key = v.first;
+        const boost::property_tree::ptree &subtree = v.second;
+        if (subtree.empty()) {
+            ctx->settings.emplace(ctx->id(path + key), subtree.get_value<std::string>().c_str());
+        } else {
+            addSettings(ctx, path + key + "/", subtree);
+        }
+    }
+}
+
 std::unique_ptr<Context> ProjectHandler::load(std::string filename)
 {
     std::unique_ptr<Context> ctx;
@@ -118,6 +130,10 @@
             if (params.count("seed"))
                 ctx->rngseed(params.get<uint64_t>("seed"));
         }
+        if (project.count("settings")) {
+            addSettings(ctx.get(), "", project.get_child("settings"));
+        }
+
         loadArch(ctx.get(), root, proj.parent_path().string());
     } catch (...) {
         log_error("Error loading project file.\n");
diff --git a/common/settings.h b/common/settings.h
index c7ef201..8ced656 100644
--- a/common/settings.h
+++ b/common/settings.h
@@ -20,6 +20,7 @@
 #define SETTINGS_H
 
 #include <boost/lexical_cast.hpp>
+#include "log.h"
 #include "nextpnr.h"
 
 NEXTPNR_NAMESPACE_BEGIN
@@ -31,10 +32,15 @@
 
     template <typename T> T get(const char *name, T defaultValue)
     {
-        IdString id = ctx->id(name);
-        if (ctx->settings.find(id) != ctx->settings.end())
-            return boost::lexical_cast<T>(ctx->settings[id]);
-        ctx->settings.emplace(id, std::to_string(defaultValue));
+        try {
+            IdString id = ctx->id(name);
+            if (ctx->settings.find(id) != ctx->settings.end()) {
+                return boost::lexical_cast<T>(ctx->settings[id]);
+            }
+            ctx->settings.emplace(id, std::to_string(defaultValue));
+        } catch (boost::bad_lexical_cast &) {
+            log_error("Problem reading setting %s, using default value\n", name);
+        }
         return defaultValue;
     }