aboutsummaryrefslogtreecommitdiffstats
path: root/common/kernel/context.h
blob: 4a5667d03961be54532df1b7d90fe6d31b1fd8aa (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
131
132
133
134
135
136
137
/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  Claire Xenia Wolf <claire@yosyshq.com>
 *  Copyright (C) 2018  Serge Bazanski <q3k@q3k.org>
 *
 *  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 CONTEXT_H
#define CONTEXT_H

#include <boost/lexical_cast.hpp>

#include "arch.h"
#include "deterministic_rng.h"

NEXTPNR_NAMESPACE_BEGIN

struct Context : Arch, DeterministicRNG
{
    bool verbose = false;
    bool debug = false;
    bool force = false;

    // Should we disable printing of the location of nets in the critical path?
    bool disable_critical_path_source_print = false;
    // True when detailed per-net timing is to be stored / reported
    bool detailed_timing_report = false;

    ArchArgs arch_args;

    Context(ArchArgs args) : Arch(args)
    {
        BaseCtx::as_ctx = this;
        arch_args = args;
    }

    ArchArgs getArchArgs() { return arch_args; }

    // --------------------------------------------------------------

    delay_t predictArcDelay(const NetInfo *net_info, const PortRef &sink) const;

    WireId getNetinfoSourceWire(const NetInfo *net_info) const;
    SSOArray<WireId, 2> getNetinfoSinkWires(const NetInfo *net_info, const PortRef &sink) const;
    size_t getNetinfoSinkWireCount(const NetInfo *net_info, const PortRef &sink) const;
    WireId getNetinfoSinkWire(const NetInfo *net_info, const PortRef &sink, size_t phys_idx) const;
    delay_t getNetinfoRouteDelay(const NetInfo *net_info, const PortRef &sink) const;

    // provided by router1.cc
    bool checkRoutedDesign() const;
    bool getActualRouteDelay(WireId src_wire, WireId dst_wire, delay_t *delay = nullptr,
                             dict<WireId, PipId> *route = nullptr, bool useEstimate = true);

    // --------------------------------------------------------------
    // Dispatch to the Arch API or pseudo-cell API accordingly
    bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayQuad &delay) const override
    {
        return cell->pseudo_cell ? cell->pseudo_cell->getDelay(fromPort, toPort, delay)
                                 : Arch::getCellDelay(cell, fromPort, toPort, delay);
    }
    TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const override
    {
        return cell->pseudo_cell ? cell->pseudo_cell->getPortTimingClass(port, clockInfoCount)
                                 : Arch::getPortTimingClass(cell, port, clockInfoCount);
    }
    TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const override
    {
        return cell->pseudo_cell ? cell->pseudo_cell->getPortClockingInfo(port, index)
                                 : Arch::getPortClockingInfo(cell, port, index);
    }

    // --------------------------------------------------------------
    // call after changing hierpath or adding/removing nets and cells
    void fixupHierarchy();

    // --------------------------------------------------------------

    // provided by sdf.cc
    void writeSDF(std::ostream &out, bool cvc_mode = false) const;

    // --------------------------------------------------------------

    // provided by svg.cc
    void writeSVG(const std::string &filename, const std::string &flags = "") const;

    // --------------------------------------------------------------

    // provided by report.cc
    void writeReport(std::ostream &out) const;
    // --------------------------------------------------------------

    uint32_t checksum() const;

    void check() const;
    void archcheck() const;

    template <typename T> T setting(const char *name, T defaultValue)
    {
        IdString new_id = id(name);
        auto found = settings.find(new_id);
        if (found != settings.end())
            return boost::lexical_cast<T>(found->second.is_string ? found->second.as_string()
                                                                  : std::to_string(found->second.as_int64()));
        else
            settings[id(name)] = std::to_string(defaultValue);

        return defaultValue;
    }

    template <typename T> T setting(const char *name) const
    {
        IdString new_id = id(name);
        auto found = settings.find(new_id);
        if (found != settings.end())
            return boost::lexical_cast<T>(found->second.is_string ? found->second.as_string()
                                                                  : std::to_string(found->second.as_int64()));
        else
            throw std::runtime_error("settings does not exists");
    }
};

NEXTPNR_NAMESPACE_END

#endif /* CONTEXT_H */