From 59a790cd00421d14120927fbb1718da8cd77e3c4 Mon Sep 17 00:00:00 2001 From: Serge Bazanski Date: Sat, 14 Jul 2018 20:24:20 +0100 Subject: Refactor IdString functionality into IdStringDB This lets us more precisely control the lifetime of IdString databases in contexts/arches. --- common/nextpnr.h | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 50465869..87c50fe3 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -2,6 +2,7 @@ * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Clifford Wolf + * Copyright (C) 2018 Serge Bazanski * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -88,28 +89,28 @@ inline void assert_false_impl(std::string message, std::string filename, int lin #define NPNR_ASSERT_MSG(cond, msg) except_assert_impl((cond), msg, #cond, __FILE__, __LINE__) #define NPNR_ASSERT_FALSE(msg) assert_false_impl(msg, __FILE__, __LINE__) -struct BaseCtx; +struct IdStringDB; struct Context; struct IdString { int index = 0; - static void initialize_arch(const BaseCtx *ctx); + static void initialize_arch(const IdStringDB *ctx); - static void initialize_add(const BaseCtx *ctx, const char *s, int idx); + static void initialize_add(const IdStringDB *ctx, const char *s, int idx); IdString() {} - void set(const BaseCtx *ctx, const std::string &s); + void set(const IdStringDB *ctx, const std::string &s); - IdString(const BaseCtx *ctx, const std::string &s) { set(ctx, s); } + IdString(const IdStringDB *ctx, const std::string &s) { set(ctx, s); } - IdString(const BaseCtx *ctx, const char *s) { set(ctx, s); } + IdString(const IdStringDB *ctx, const char *s) { set(ctx, s); } - const std::string &str(const BaseCtx *ctx) const; + const std::string &str(const IdStringDB *ctx) const; - const char *c_str(const BaseCtx *ctx) const; + const char *c_str(const IdStringDB *ctx) const; bool operator<(const IdString &other) const { return index < other.index; } @@ -238,23 +239,18 @@ struct CellInfo std::unordered_map pins; }; -struct BaseCtx +class IdStringDB { - // -------------------------------------------------------------- - + friend class IdString; + private: mutable std::unordered_map *idstring_str_to_idx; mutable std::vector *idstring_idx_to_str; - + + public: IdString id(const std::string &s) const { return IdString(this, s); } - IdString id(const char *s) const { return IdString(this, s); } - // -------------------------------------------------------------- - - std::unordered_map> nets; - std::unordered_map> cells; - - BaseCtx() + IdStringDB() { idstring_str_to_idx = new std::unordered_map; idstring_idx_to_str = new std::vector; @@ -262,11 +258,21 @@ struct BaseCtx IdString::initialize_arch(this); } - ~BaseCtx() + ~IdStringDB() { delete idstring_str_to_idx; delete idstring_idx_to_str; } +}; + +class BaseCtx : public IdStringDB +{ + public: + std::unordered_map> nets; + std::unordered_map> cells; + + BaseCtx() {} + ~BaseCtx() {} Context *getCtx() { return reinterpret_cast(this); } -- cgit v1.2.3 From 91db413c60c965b6b7cc095f53c8d03a1658566e Mon Sep 17 00:00:00 2001 From: Serge Bazanski Date: Sat, 14 Jul 2018 20:33:32 +0100 Subject: Refactor RNG out to separate DeterministicRNG class This well also allow for better lifecycle control over the state of the RNG in the future. --- common/nextpnr.h | 124 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 57 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 87c50fe3..e53e4d01 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -265,65 +265,15 @@ class IdStringDB } }; -class BaseCtx : public IdStringDB +class DeterministicRNG { - public: - std::unordered_map> nets; - std::unordered_map> cells; - - BaseCtx() {} - ~BaseCtx() {} - - Context *getCtx() { return reinterpret_cast(this); } - - const Context *getCtx() const { return reinterpret_cast(this); } - - // -------------------------------------------------------------- - - bool allUiReload = false; - bool frameUiReload = false; - std::unordered_set belUiReload; - std::unordered_set wireUiReload; - std::unordered_set pipUiReload; - std::unordered_set groupUiReload; - - void refreshUi() { allUiReload = true; } - - void refreshUiFrame() { frameUiReload = true; } - - void refreshUiBel(BelId bel) { belUiReload.insert(bel); } - - void refreshUiWire(WireId wire) { wireUiReload.insert(wire); } - - void refreshUiPip(PipId pip) { pipUiReload.insert(pip); } - - void refreshUiGroup(GroupId group) { groupUiReload.insert(group); } -}; - -NEXTPNR_NAMESPACE_END - -#include "arch.h" - -NEXTPNR_NAMESPACE_BEGIN - -struct Context : Arch -{ - bool verbose = false; - bool debug = false; - bool force = false; - bool timing_driven = true; - float target_freq = 12e6; - - Context(ArchArgs args) : Arch(args) {} - - // -------------------------------------------------------------- - - // provided by router1.cc - bool getActualRouteDelay(WireId src_wire, WireId dst_wire, delay_t &delay); - - // -------------------------------------------------------------- + private: + uint64_t rngstate; - uint64_t rngstate = 0x3141592653589793; + public: + DeterministicRNG() : rngstate(0x3141592653589793) + { + } uint64_t rng64() { @@ -383,6 +333,66 @@ struct Context : Arch shuffle(a); } +}; + +class BaseCtx : public IdStringDB, public DeterministicRNG +{ + public: + std::unordered_map> nets; + std::unordered_map> cells; + + BaseCtx() {} + ~BaseCtx() {} + + Context *getCtx() { return reinterpret_cast(this); } + + const Context *getCtx() const { return reinterpret_cast(this); } + + // -------------------------------------------------------------- + + bool allUiReload = false; + bool frameUiReload = false; + std::unordered_set belUiReload; + std::unordered_set wireUiReload; + std::unordered_set pipUiReload; + std::unordered_set groupUiReload; + + void refreshUi() { allUiReload = true; } + + void refreshUiFrame() { frameUiReload = true; } + + void refreshUiBel(BelId bel) { belUiReload.insert(bel); } + + void refreshUiWire(WireId wire) { wireUiReload.insert(wire); } + + void refreshUiPip(PipId pip) { pipUiReload.insert(pip); } + + void refreshUiGroup(GroupId group) { groupUiReload.insert(group); } +}; + +NEXTPNR_NAMESPACE_END + +#include "arch.h" + +NEXTPNR_NAMESPACE_BEGIN + +struct Context : Arch +{ + bool verbose = false; + bool debug = false; + bool force = false; + bool timing_driven = true; + float target_freq = 12e6; + + Context(ArchArgs args) : Arch(args) {} + + // -------------------------------------------------------------- + + // provided by router1.cc + bool getActualRouteDelay(WireId src_wire, WireId dst_wire, delay_t &delay); + + // -------------------------------------------------------------- + uint32_t checksum() const; void check() const; -- cgit v1.2.3 From 2f5b94fe309619c221c3e1ea5aa48a4523bd3156 Mon Sep 17 00:00:00 2001 From: Serge Bazanski Date: Tue, 17 Jul 2018 16:27:50 +0100 Subject: Add basic external locking, lock from P&R --- common/nextpnr.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index e53e4d01..7aa5b100 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -337,6 +339,11 @@ class DeterministicRNG class BaseCtx : public IdStringDB, public DeterministicRNG { + private: + std::mutex mutex; + bool mutex_owned; + pthread_t mutex_owner; + public: std::unordered_map> nets; std::unordered_map> cells; @@ -344,6 +351,18 @@ class BaseCtx : public IdStringDB, public DeterministicRNG BaseCtx() {} ~BaseCtx() {} + void lock(void) + { + mutex.lock(); + mutex_owner = pthread_self(); + } + + void unlock(void) + { + NPNR_ASSERT(pthread_equal(pthread_self(), mutex_owner) != 0); + mutex.unlock(); + } + Context *getCtx() { return reinterpret_cast(this); } const Context *getCtx() const { return reinterpret_cast(this); } -- cgit v1.2.3 From 03508faabfc2f5b76039cfd13d02a341baa848a4 Mon Sep 17 00:00:00 2001 From: Serge Bazanski Date: Tue, 17 Jul 2018 19:16:26 +0100 Subject: WIP. --- common/nextpnr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 7aa5b100..fb5e042b 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -369,7 +369,7 @@ class BaseCtx : public IdStringDB, public DeterministicRNG // -------------------------------------------------------------- - bool allUiReload = false; + bool allUiReload = true; bool frameUiReload = false; std::unordered_set belUiReload; std::unordered_set wireUiReload; -- cgit v1.2.3 From b84a446eeff080715ba0b4b98c14822f0e3f8530 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 20 Jul 2018 11:04:54 +0100 Subject: Mix-in Deterministic RNG at Context instead of BaseCtx --- common/nextpnr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 2a416a05..1f75434d 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -342,7 +342,7 @@ class DeterministicRNG }; -class BaseCtx : public IdStringDB, public DeterministicRNG +class BaseCtx : public IdStringDB { private: std::mutex mutex; @@ -400,7 +400,7 @@ NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_BEGIN -struct Context : Arch +struct Context : Arch, DeterministicRNG { bool verbose = false; bool debug = false; -- cgit v1.2.3 From b4b111a053a5e2aacd036508899277022914ae8f Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 20 Jul 2018 13:15:22 +0100 Subject: Move pthread yield hack into BaseCtx --- common/nextpnr.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 1f75434d..e9cda565 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -346,8 +347,9 @@ class BaseCtx : public IdStringDB { private: std::mutex mutex; - bool mutex_owned; pthread_t mutex_owner; + + std::mutex generation_mutex; public: std::unordered_map> nets; @@ -360,6 +362,7 @@ class BaseCtx : public IdStringDB { mutex.lock(); mutex_owner = pthread_self(); + } void unlock(void) @@ -368,6 +371,14 @@ class BaseCtx : public IdStringDB mutex.unlock(); } + // TODO(q3k): get rid of this hack + void yield(void) + { + for (int i = 0; i < 10; i++) { + pthread_yield(); + } + } + Context *getCtx() { return reinterpret_cast(this); } const Context *getCtx() const { return reinterpret_cast(this); } -- cgit v1.2.3 From 19f4b68f07edcbcb24282f5d3941d5d4a97afa03 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 20 Jul 2018 13:19:45 +0100 Subject: clang-format and uncomment debug --- common/nextpnr.h | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index e9cda565..09174320 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -250,10 +250,11 @@ struct CellInfo : ArchCellInfo class IdStringDB { friend class IdString; + private: mutable std::unordered_map *idstring_str_to_idx; mutable std::vector *idstring_idx_to_str; - + public: IdString id(const std::string &s) const { return IdString(this, s); } IdString id(const char *s) const { return IdString(this, s); } @@ -279,9 +280,7 @@ class DeterministicRNG uint64_t rngstate; public: - DeterministicRNG() : rngstate(0x3141592653589793) - { - } + DeterministicRNG() : rngstate(0x3141592653589793) {} uint64_t rng64() { @@ -340,7 +339,6 @@ class DeterministicRNG std::sort(a.begin(), a.end()); shuffle(a); } - }; class BaseCtx : public IdStringDB @@ -348,7 +346,7 @@ class BaseCtx : public IdStringDB private: std::mutex mutex; pthread_t mutex_owner; - + std::mutex generation_mutex; public: @@ -362,7 +360,6 @@ class BaseCtx : public IdStringDB { mutex.lock(); mutex_owner = pthread_self(); - } void unlock(void) -- cgit v1.2.3 From b5b956bd214742892cd242ec38e4cc64c213e59e Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 20 Jul 2018 17:57:16 +0100 Subject: Remove dead code. --- common/nextpnr.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 09174320..2baedef4 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -347,8 +347,6 @@ class BaseCtx : public IdStringDB std::mutex mutex; pthread_t mutex_owner; - std::mutex generation_mutex; - public: std::unordered_map> nets; std::unordered_map> cells; -- cgit v1.2.3 From 76e5236fb3c161a860b2c494fe44fde3011670af Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 20 Jul 2018 18:24:16 +0100 Subject: Nuke IdStringDB --- common/nextpnr.h | 77 +++++++++++++++++++++++++------------------------------- 1 file changed, 34 insertions(+), 43 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 2baedef4..d42d3446 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -93,28 +93,28 @@ inline bool assert_fail_impl_str(std::string message, const char *expr_str, cons #define NPNR_ASSERT_FALSE(msg) (assert_fail_impl(msg, "false", __FILE__, __LINE__)) #define NPNR_ASSERT_FALSE_STR(msg) (assert_fail_impl_str(msg, "false", __FILE__, __LINE__)) -struct IdStringDB; +struct BaseCtx; struct Context; struct IdString { int index = 0; - static void initialize_arch(const IdStringDB *ctx); + static void initialize_arch(const BaseCtx *ctx); - static void initialize_add(const IdStringDB *ctx, const char *s, int idx); + static void initialize_add(const BaseCtx *ctx, const char *s, int idx); IdString() {} - void set(const IdStringDB *ctx, const std::string &s); + void set(const BaseCtx *ctx, const std::string &s); - IdString(const IdStringDB *ctx, const std::string &s) { set(ctx, s); } + IdString(const BaseCtx *ctx, const std::string &s) { set(ctx, s); } - IdString(const IdStringDB *ctx, const char *s) { set(ctx, s); } + IdString(const BaseCtx *ctx, const char *s) { set(ctx, s); } - const std::string &str(const IdStringDB *ctx) const; + const std::string &str(const BaseCtx *ctx) const; - const char *c_str(const IdStringDB *ctx) const; + const char *c_str(const BaseCtx *ctx) const; bool operator<(const IdString &other) const { return index < other.index; } @@ -247,39 +247,10 @@ struct CellInfo : ArchCellInfo std::unordered_map pins; }; -class IdStringDB +struct DeterministicRNG { - friend class IdString; - - private: - mutable std::unordered_map *idstring_str_to_idx; - mutable std::vector *idstring_idx_to_str; - - public: - IdString id(const std::string &s) const { return IdString(this, s); } - IdString id(const char *s) const { return IdString(this, s); } - - IdStringDB() - { - idstring_str_to_idx = new std::unordered_map; - idstring_idx_to_str = new std::vector; - IdString::initialize_add(this, "", 0); - IdString::initialize_arch(this); - } - - ~IdStringDB() - { - delete idstring_str_to_idx; - delete idstring_idx_to_str; - } -}; - -class DeterministicRNG -{ - private: uint64_t rngstate; - public: DeterministicRNG() : rngstate(0x3141592653589793) {} uint64_t rng64() @@ -341,19 +312,35 @@ class DeterministicRNG } }; -class BaseCtx : public IdStringDB +struct BaseCtx { - private: + // Lock to perform mutating actions on the Context. std::mutex mutex; pthread_t mutex_owner; - public: + // ID String database. + mutable std::unordered_map *idstring_str_to_idx; + mutable std::vector *idstring_idx_to_str; + + // Placed nets and cells. std::unordered_map> nets; std::unordered_map> cells; - BaseCtx() {} - ~BaseCtx() {} + BaseCtx() + { + idstring_str_to_idx = new std::unordered_map; + idstring_idx_to_str = new std::vector; + IdString::initialize_add(this, "", 0); + IdString::initialize_arch(this); + } + + ~BaseCtx() + { + delete idstring_str_to_idx; + delete idstring_idx_to_str; + } + // Must be called before performing any mutating changes on the Ctx/Arch. void lock(void) { mutex.lock(); @@ -374,6 +361,10 @@ class BaseCtx : public IdStringDB } } + IdString id(const std::string &s) const { return IdString(this, s); } + + IdString id(const char *s) const { return IdString(this, s); } + Context *getCtx() { return reinterpret_cast(this); } const Context *getCtx() const { return reinterpret_cast(this); } -- cgit v1.2.3 From 0311a27a53922783363ab607ca8f3832980990c6 Mon Sep 17 00:00:00 2001 From: Sergiusz Bazanski Date: Fri, 20 Jul 2018 18:34:59 +0100 Subject: Use UI lock for yielding --- common/nextpnr.h | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index d42d3446..8b8299bc 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -318,6 +318,11 @@ struct BaseCtx std::mutex mutex; pthread_t mutex_owner; + // Lock to be taken by UI when wanting to access context - the yield() + // method will lock/unlock it when its' released the main mutex to make + // sure the UI is not starved. + std::mutex ui_mutex; + // ID String database. mutable std::unordered_map *idstring_str_to_idx; mutable std::vector *idstring_idx_to_str; @@ -353,12 +358,31 @@ struct BaseCtx mutex.unlock(); } - // TODO(q3k): get rid of this hack + // Must be called by the UI before rendering data. This lock will be + // prioritized when processing code calls yield(). + void lock_ui(void) + { + ui_mutex.lock(); + mutex.lock(); + } + + void unlock_ui(void) + { + mutex.unlock(); + ui_mutex.unlock(); + } + + // Yield to UI by unlocking the main mutex, flashing the UI mutex and + // relocking the main mutex. Call this when you're performing a + // long-standing action while holding a lock to let the UI show + // visualization updates. + // Must be called with the main lock taken. void yield(void) { - for (int i = 0; i < 10; i++) { - pthread_yield(); - } + unlock(); + ui_mutex.lock(); + ui_mutex.unlock(); + lock(); } IdString id(const std::string &s) const { return IdString(this, s); } -- cgit v1.2.3 From 30e2f0e1e8cfdb24abe6c3a8013691497c706975 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 21 Jul 2018 21:40:06 +0200 Subject: Add Loc constructors Signed-off-by: Clifford Wolf --- common/nextpnr.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index 40fd3d13..c8915c19 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -164,6 +164,9 @@ struct Loc { int x = -1, y = -1, z = -1; + Loc() {} + Loc(int x, int y, int z) : x(x), y(y), z(z) {} + bool operator==(const Loc &other) const { return (x == other.x) && (y == other.y) && (z == other.z); } bool operator!=(const Loc &other) const { return (x != other.x) || (y != other.y) || (z == other.z); } }; -- cgit v1.2.3 From c6e4ad322745b478f0f289f4cc5f3668e05700ac Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 22 Jul 2018 02:16:03 +0200 Subject: Move common patterns from router1 to Context API Signed-off-by: Clifford Wolf --- common/nextpnr.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index d89eb15b..bb40e1b6 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -460,6 +460,10 @@ struct Context : Arch, DeterministicRNG // -------------------------------------------------------------- + WireId getNetinfoSourceWire(NetInfo *net_info) const; + WireId getNetinfoSinkWire(NetInfo *net_info, int user_idx) const; + delay_t getNetinfoRouteDelay(NetInfo *net_info, int user_idx) const; + // provided by router1.cc bool getActualRouteDelay(WireId src_wire, WireId dst_wire, delay_t &delay); -- cgit v1.2.3 From e647604e2a584917ad2fc9acfe838a1395c613c2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 23 Jul 2018 14:03:23 +0200 Subject: Add Context::archcheck() and "nextpnr-ice40 --test" Signed-off-by: Clifford Wolf --- common/nextpnr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'common/nextpnr.h') diff --git a/common/nextpnr.h b/common/nextpnr.h index bb40e1b6..021772fe 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -472,6 +472,7 @@ struct Context : Arch, DeterministicRNG uint32_t checksum() const; void check() const; + void archcheck() const; }; NEXTPNR_NAMESPACE_END -- cgit v1.2.3