aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange/site_lut_mapping_cache.h
blob: b07e3e77ea5338d52dfab8ff9932ed071e2d4b2b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2021  Symbiflow Authors
 *
 *  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 SITE_LUT_MAPPING_CACHE_H
#define SITE_LUT_MAPPING_CACHE_H

#include "idstring.h"
#include "nextpnr_namespaces.h"

NEXTPNR_NAMESPACE_BEGIN

// Key structure used in site LUT mapping cache
struct SiteLutMappingKey {

    // Maximum number of LUT cells
    static constexpr size_t MAX_LUT_CELLS  = 8;
    // Maximum number of LUT inputs per cell
    static constexpr size_t MAX_LUT_INPUTS = 6;

    // LUT Cell data
    struct Cell {
        IdString    type;       // Cell type
        int32_t     belIndex;   // Bound BEL index
  
        // Port to net assignments. These are local net ids generated during
        // key creation. This is to abstract connections from actual design
        // net names. the Id 0 means unconnected.
        int32_t     conns [MAX_LUT_INPUTS];
    };

    int32_t           tileType; // Tile type
    int32_t           siteType; // Site type in that tile type
    std::vector<Cell> cells;    // LUT cell data

    unsigned int      hash_;    // Precomputed hash

    static SiteLutMappingKey create (const SiteInformation& siteInfo);

    void computeHash () {
        hash_ = mkhash(0, tileType);
        hash_ = mkhash(hash_, siteType);
        for (const auto& cell : cells) {
            hash_ = mkhash(hash_, cell.type.index);
            hash_ = mkhash(hash_, cell.belIndex);
            for (size_t i=0; i<MAX_LUT_INPUTS; ++i) {
                hash_ = mkhash(hash_, cell.conns[i]);
            }
        }
    }
   
    bool operator == (const SiteLutMappingKey &other) const {
        return (hash_ == other.hash_) &&
               (tileType == other.tileType) &&
               (siteType == other.siteType) &&
               (cells == other.cells);
    }

    bool operator != (const SiteLutMappingKey &other) const {
        return (hash_ != other.hash_) ||
               (tileType != other.tileType) ||
               (siteType != other.siteType) ||
               (cells != other.cells);
    }

    unsigned int hash () const {
        return hash_;
    }
};

// Site LUT mapping result data
struct SiteLutMappingResult {

    // LUT cell data
    struct Cell {
        int32_t                     belIndex; // BEL in tile index
        LutCell                     lutCell;  // LUT mapping data
        dict<IdString, IdString>    belPins;  // Cell to BEL pin mapping
    };

    bool                isValid; // Validity flag
    std::vector<Cell>   cells;   // Cell data

    pool<std::pair<IdString, IdString>>  blockedWires;

    // Applies the mapping result to the site
    bool apply  (const SiteInformation& siteInfo);
};

// Site LUT mapping cache object
class SiteLutMappingCache {
public:

    void add    (const SiteLutMappingKey& key, const SiteLutMappingResult& result);
    bool get    (const SiteLutMappingKey& key, SiteLutMappingResult* result);

    void clear      ();
    void clearStats ();

    float getMissRatio () const {
        return (float)numMisses / (float)(numHits + numMisses);
    }

private:

    dict<SiteLutMappingKey, SiteLutMappingResult> cache_;

    size_t numHits   = 0;
    size_t numMisses = 0;
};


NEXTPNR_NAMESPACE_END

#endif /* SITE_LUT_MAPPING_CACHE_H */