diff --git a/xc7/arch.cc b/xc7/arch.cc index ae138513..f9d56185 100644 --- a/xc7/arch.cc +++ b/xc7/arch.cc @@ -28,14 +28,30 @@ #include "router1.h" #include "util.h" +#include +#include +#include +#include +#include +struct nextpnr_binary_iarchive : public boost::archive::binary_iarchive { + nextpnr_binary_iarchive(std::ifstream &ifs, NEXTPNR_NAMESPACE::BaseCtx* ctx, const std::string& inDeviceName, const std::string& inPackageName) : boost::archive::binary_iarchive(ifs), ctx(ctx), inDeviceName(inDeviceName), inPackageName(inPackageName) {} + NEXTPNR_NAMESPACE::BaseCtx *ctx; + std::string inDeviceName, inPackageName; +}; +struct nextpnr_binary_oarchive : public boost::archive::binary_oarchive { + nextpnr_binary_oarchive(std::ofstream &ofs, NEXTPNR_NAMESPACE::BaseCtx* ctx) : boost::archive::binary_oarchive(ofs), ctx(ctx) {} + NEXTPNR_NAMESPACE::BaseCtx *ctx; +}; + #include "torc/common/DirectoryTree.hpp" +//#define TORC_INFO_DB "torc_info.ar" + NEXTPNR_NAMESPACE_BEGIN std::unique_ptr torc_info; -TorcInfo::TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string &inPackageName) - : ddb(new DDB(inDeviceName, inPackageName)), sites(ddb->getSites()), tiles(ddb->getTiles()), - segments(ddb->getSegments()) +TorcInfo::TorcInfo(BaseCtx *ctx, const std::string &inDeviceName, const std::string &inPackageName) + : TorcInfo(inDeviceName, inPackageName) { static const boost::regex re_loc(".+_X(\\d+)Y(\\d+)"); boost::cmatch what; @@ -123,9 +139,9 @@ TorcInfo::TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string if (!currentSegment.isTrivial()) { if (currentSegment.getAnchorTileIndex() != tileIndex) continue; - segment_to_wire.emplace(currentSegment, wire_to_tilewire.size()); + segment_to_wire.emplace(currentSegment, w); } else - trivial_to_wire.emplace(currentTilewire, wire_to_tilewire.size()); + trivial_to_wire.emplace(currentTilewire, w); wire_to_tilewire.push_back(currentTilewire); @@ -200,6 +216,8 @@ TorcInfo::TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string DelayInfo d; d.delay = it->second[currentTilewire.getWireIndex()]; wire_to_delay.emplace_back(std::move(d)); + + ++w.index; } } wire_to_tilewire.shrink_to_fit(); @@ -252,7 +270,7 @@ TorcInfo::TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string continue; } } - pips.push_back(p.index); + pips.emplace_back(p); pip_to_arc.emplace_back(a); // arc_to_pip.emplace(a, p.index); const auto &tw = a.getSinkTilewire(); @@ -270,6 +288,11 @@ TorcInfo::TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string pip_to_dst_wire.emplace_back(tilewire_to_wire(tw)); } } +TorcInfo::TorcInfo(const std::string& inDeviceName, const std::string &inPackageName) + : ddb(new DDB(inDeviceName, inPackageName)), sites(ddb->getSites()), tiles(ddb->getTiles()), + segments(ddb->getSegments()) +{ +} // ----------------------------------------------------------------------- @@ -286,11 +309,31 @@ Arch::Arch(ArchArgs args) : args(args) { torc::common::DirectoryTree directoryTree("/opt/torc/src/torc"); if (args.type == ArchArgs::Z020) { - torc_info = std::unique_ptr(new TorcInfo(this, "xc7z020", args.package)); +#ifdef TORC_INFO_DB + std::ifstream ifs(TORC_INFO_DB, std::ios::binary); + if (ifs) { + nextpnr_binary_iarchive ia(ifs, this, "xc7z020", args.package); + ia >> torc_info; + std::cout << ifs.tellg() << std::endl; + } else +#endif + { + torc_info = std::unique_ptr(new TorcInfo(this, "xc7z020", args.package)); +#ifdef TORC_INFO_DB + std::ofstream ofs(TORC_INFO_DB, std::ios::binary); + if (ofs) { + nextpnr_binary_oarchive oa(ofs, this); + oa << torc_info; + ofs.flush(); + std::cout << ofs.tellp() << std::endl; + } + } +#endif } else { log_error("Unsupported XC7 chip type.\n"); } + /*if (getCtx()->verbose)*/ { log_info("Number of bels: %d\n", torc_info->num_bels); log_info("Number of wires: %d\n", torc_info->num_wires); @@ -409,8 +452,6 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const WireId Arch::getBelPinWire(BelId bel, IdString pin) const { - WireId ret; - auto pin_name = pin.str(this); auto bel_type = getBelType(bel); if (bel_type == id_SLICE_LUT6) { @@ -451,7 +492,7 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const log_error("no wire found for site '%s' pin '%s' \n", torc_info->bel_to_name(bel.index).c_str(), pin_name.c_str()); - ret.index = torc_info->tilewire_to_wire(tw); + return torc_info->tilewire_to_wire(tw); // NPNR_ASSERT(bel != BelId()); // @@ -479,8 +520,8 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const // b = i + 1; // } // } - - return ret; + // + //return ret; } std::vector Arch::getBelPins(BelId bel) const @@ -1075,3 +1116,109 @@ void Arch::assignCellInfo(CellInfo *cell) } NEXTPNR_NAMESPACE_END + +// outside of any namespace +BOOST_SERIALIZATION_SPLIT_FREE(Segments::SegmentReference) +BOOST_SERIALIZATION_SPLIT_FREE(CompactSegmentIndex) +BOOST_SERIALIZATION_SPLIT_FREE(TileIndex) +BOOST_SERIALIZATION_SPLIT_FREE(Arc) +BOOST_SERIALIZATION_SPLIT_FREE(Tilewire) +BOOST_SERIALIZATION_SPLIT_FREE(WireIndex) +BOOST_SERIALIZATION_SPLIT_FREE(SiteIndex) +BOOST_SERIALIZATION_SPLIT_FREE(NEXTPNR_NAMESPACE::IdString) + +namespace boost { namespace serialization { + +template +inline void load_construct_data( + Archive & ar, NEXTPNR_NAMESPACE::TorcInfo * t, const unsigned int file_version +){ + const auto& inDeviceName = static_cast(ar).inDeviceName; + const auto& inPackageName = static_cast(ar).inPackageName; + ::new(t)NEXTPNR_NAMESPACE::TorcInfo(inDeviceName, inPackageName); +} + +template +void save(Archive& ar, const Segments::SegmentReference& o, unsigned int) { + ar & o.getCompactSegmentIndex(); + ar & o.getAnchorTileIndex(); +} +template +void load(Archive& ar, Segments::SegmentReference& o, unsigned int) { + CompactSegmentIndex i; + TileIndex j; + ar & i; + ar & j; + o = Segments::SegmentReference(i, j); +} +#define SERIALIZE_POD(__T__) \ +template \ +void save(Archive& ar, const __T__& o, unsigned int) { \ + ar & static_cast<__T__::pod>(o); \ +} \ +template \ +void load(Archive& ar, __T__& o, unsigned int) { \ + __T__::pod i; \ + ar & i; \ + o = __T__(i); \ +} +SERIALIZE_POD(CompactSegmentIndex) +SERIALIZE_POD(TileIndex) +SERIALIZE_POD(WireIndex) +SERIALIZE_POD(SiteIndex) +template +void save(Archive& ar, const Arc& o, unsigned int) { + ar & o.getSourceTilewire(); + ar & o.getSinkTilewire(); +} +template +void load(Archive& ar, Arc& o, unsigned int) { + Tilewire s, t; + ar & s; + ar & t; + o = Arc(s, t); +} +template +void save(Archive& ar, const Tilewire& o, unsigned int) { + ar & o.getTileIndex(); + ar & o.getWireIndex(); +} +template +void load(Archive& ar, Tilewire& o, unsigned int) { + TileIndex i; + WireIndex j; + ar & i; + ar & j; + o.setTileIndex(TileIndex(i)); + o.setWireIndex(WireIndex(j)); +} +template +void serialize(Archive& ar, NEXTPNR_NAMESPACE::Loc& o, unsigned int) { + ar & o.x; + ar & o.y; + ar & o.z; +} +template +void serialize(Archive& ar, NEXTPNR_NAMESPACE::DelayInfo& o, unsigned int) { + ar & o.delay; +} +template +void save(Archive& ar, const NEXTPNR_NAMESPACE::IdString& o, unsigned int) { + const std::string i = o.str(static_cast(ar).ctx); + ar & i; +} +template +void load(Archive& ar, NEXTPNR_NAMESPACE::IdString& o, unsigned int) { + std::string i; + ar & i; + o = static_cast(ar).ctx->id(i); +} +#define SERIALIZE_INDEX(__T__) \ +template \ +void serialize(Archive& ar, __T__& o, unsigned int) { \ + ar & o.index; \ +} +SERIALIZE_INDEX(NEXTPNR_NAMESPACE::BelId) +SERIALIZE_INDEX(NEXTPNR_NAMESPACE::WireId) +SERIALIZE_INDEX(NEXTPNR_NAMESPACE::PipId) +}} // namespace boost::serialization diff --git a/xc7/arch.h b/xc7/arch.h index 410bf8b1..648ace00 100644 --- a/xc7/arch.h +++ b/xc7/arch.h @@ -21,6 +21,8 @@ #error Include "arch.h" via "nextpnr.h" only. #endif +#include + #include "torc/Architecture.hpp" #include "torc/Common.hpp" using namespace torc::architecture; @@ -268,10 +270,10 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD { RelPtr cell_timing; }); -struct Arch; struct TorcInfo { - TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string &inPackageName); + TorcInfo(BaseCtx *ctx, const std::string &inDeviceName, const std::string &inPackageName); + TorcInfo() = delete; std::unique_ptr ddb; const Sites &sites; const Tiles &tiles; @@ -297,7 +299,7 @@ struct TorcInfo ss << "(" << tw.getWireIndex() << "@" << tw.getTileIndex() << ")"; return ss.str(); } - int32_t tilewire_to_wire(const Tilewire &tw) const + WireId tilewire_to_wire(const Tilewire &tw) const { const auto &segment = segments.getTilewireSegment(tw); if (!segment.isTrivial()) @@ -310,16 +312,40 @@ struct TorcInfo std::vector site_index_to_bel; std::vector site_index_to_type; std::vector bel_to_loc; - std::unordered_map segment_to_wire; - std::unordered_map trivial_to_wire; + std::unordered_map segment_to_wire; + std::unordered_map trivial_to_wire; std::vector wire_to_tilewire; int num_wires; std::vector wire_to_delay; - std::vector> wire_to_pips_uphill; - std::vector> wire_to_pips_downhill; + //std::vector> wire_to_pips_uphill; + std::vector> wire_to_pips_downhill; std::vector pip_to_arc; int num_pips; - std::vector pip_to_dst_wire; + std::vector pip_to_dst_wire; + + TorcInfo(const std::string &inDeviceName, const std::string &inPackageName); +private: + friend class boost::serialization::access; + //TorcInfo(const std::string &inDeviceName, const std::string &inPackageName); + //template friend inline void load_construct_data(Archive &ar, T *t, const unsigned int file_version); + template + void serialize(Archive & ar, const unsigned int /*version*/) + { + ar & bel_to_site_index; + ar & num_bels; + ar & site_index_to_bel; + ar & site_index_to_type; + ar & bel_to_loc; + ar & segment_to_wire; + ar & trivial_to_wire; + ar & wire_to_tilewire; + ar & num_wires; + ar & wire_to_delay; + ar & wire_to_pips_downhill; + ar & pip_to_arc; + ar & num_pips; + ar & pip_to_dst_wire; + } }; extern std::unique_ptr torc_info; @@ -438,16 +464,14 @@ struct AllPipRange struct PipIterator { - const int *cursor = nullptr; + const PipId *cursor = nullptr; void operator++() { cursor++; } bool operator!=(const PipIterator &other) const { return cursor != other.cursor; } PipId operator*() const { - PipId ret; - ret.index = *cursor; - return ret; + return *cursor; } }; @@ -797,22 +821,17 @@ struct Arch : BaseCtx WireId getPipSrcWire(PipId pip) const { - WireId wire; NPNR_ASSERT(pip != PipId()); const auto &arc = torc_info->pip_to_arc[pip.index]; const auto &tw = arc.getSourceTilewire(); - wire.index = torc_info->tilewire_to_wire(tw); - - return wire; + return torc_info->tilewire_to_wire(tw); } WireId getPipDstWire(PipId pip) const { - WireId wire; NPNR_ASSERT(pip != PipId()); - wire.index = torc_info->pip_to_dst_wire[pip.index]; - return wire; + return torc_info->pip_to_dst_wire[pip.index]; } DelayInfo getPipDelay(PipId pip) const @@ -829,7 +848,6 @@ struct Arch : BaseCtx const auto &pips = torc_info->wire_to_pips_downhill[wire.index]; range.b.cursor = pips.data(); range.e.cursor = range.b.cursor + pips.size(); - return range; } diff --git a/xc7/family.cmake b/xc7/family.cmake index 4c835e38..c8e1c57f 100644 --- a/xc7/family.cmake +++ b/xc7/family.cmake @@ -1,6 +1,8 @@ include_directories(/opt/torc/src) #include_directories(torc/externals/zlib) +find_package(Boost REQUIRED COMPONENTS serialization ${boost_libs}) + target_link_libraries( nextpnr-${family} PRIVATE /opt/torc/src/torc/architecture/Arc.o