From e3db34aa0bdb34c06c129e9a51199da5e155e489 Mon Sep 17 00:00:00 2001 From: Roland Coeurjoly Date: Thu, 23 May 2024 03:56:23 +0200 Subject: [PATCH] Move DriverMap implementation to drivertools.cc --- kernel/drivertools.cc | 41 +++++++++ kernel/drivertools.h | 200 +++++++++++++++--------------------------- 2 files changed, 110 insertions(+), 131 deletions(-) diff --git a/kernel/drivertools.cc b/kernel/drivertools.cc index 2f8a16906fc..c3936277978 100644 --- a/kernel/drivertools.cc +++ b/kernel/drivertools.cc @@ -2166,4 +2166,45 @@ const char *log_signal(DriveSpec const &spec) return log_str(str); } +DriverMap::DriverMap() : next_offset(1 + static_cast(State::Sm)) +{ + celltypes.setup(); +} + +DriverMap::DriverMap(Design *design) : next_offset(1 + static_cast(State::Sm)) +{ + celltypes.setup(); + celltypes.setup_design(design); +} + +DriverMap::DriveBitId::DriveBitId() : id(-1) {} + +DriverMap::DriveBitId::DriveBitId(int id) : id(id) {} + +bool DriverMap::DriveBitId::operator==(const DriveBitId &other) const +{ + return id == other.id; +} + +bool DriverMap::DriveBitId::operator!=(const DriveBitId &other) const +{ + return id != other.id; +} + +bool DriverMap::DriveBitId::operator<(const DriveBitId &other) const +{ + return id < other.id; +} + +unsigned int DriverMap::DriveBitId::hash() const +{ + return id; +} + +bool DriverMap::keep_wire(Wire *wire) { + // TODO configurable + return wire->has_attribute(ID(keep)); +} + + YOSYS_NAMESPACE_END diff --git a/kernel/drivertools.h b/kernel/drivertools.h index a79bc10eb13..cc99207f629 100644 --- a/kernel/drivertools.h +++ b/kernel/drivertools.h @@ -422,122 +422,82 @@ struct DriveSpec struct DriverMap { - CellTypes celltypes; + CellTypes celltypes; - DriverMap() { celltypes.setup(); } - DriverMap(Design *design) { celltypes.setup(); celltypes.setup_design(design); } + DriverMap(); + DriverMap(Design *design); private: + struct DriveBitId + { + int id; - // Internally we represent all DriveBits by mapping them to DriveBitIds - // which use less memory and are cheaper to compare. - struct DriveBitId - { - int id = -1; - - DriveBitId() {}; - - DriveBitId(int id) : id(id) { } - - bool operator==(const DriveBitId &other) const { return id == other.id; } - bool operator!=(const DriveBitId &other) const { return id != other.id; } - bool operator<(const DriveBitId &other) const { return id < other.id; } - unsigned int hash() const { return id; } - }; - // Essentially a dict> but using less memory - // and fewer allocations - struct DriveBitGraph { - dict first_edges; - dict second_edges; - dict> more_edges; - - void add_edge(DriveBitId src, DriveBitId dst); - DriveBitId pop_edge(DriveBitId src); - void clear(DriveBitId src); - bool contains(DriveBitId src); - int count(DriveBitId src); - - DriveBitId at(DriveBitId src, int index); - }; + DriveBitId(); + DriveBitId(int id); - // The following two maps maintain a sparse DriveBit to DriveBitId mapping. - // This saves a lot of memory compared to a `dict` or - // `idict`. - - // Maps wires to the first DriveBitId of the consecutive range used for - // that wire. - dict wire_offsets; - - // Maps cell ports to a the first DriveBitId of the consecutive range used - // for that cell port. - dict, DriveBitId> port_offsets; - - // For the inverse map that maps DriveBitIds back to DriveBits we use a - // sorted map containing only the first DriveBit for each wire and cell - // port. - std::map drive_bits; - - // As a memory optimization for gate level net lists we store single-bit - // wires and cell ports in a `dict` which requires less memory and fewer - // allocations than `std::map` but doesn't support the kind of lookups we - // need for a sparse coarse grained mapping. - dict isolated_drive_bits; - - // Used for allocating DriveBitIds, none and constant states use a fixewd - // mapping to the first few ids, which we need to skip. - int next_offset = 1 + (int)State::Sm; - - // Union-Find over directly connected bits that share the same single - // driver or are undriven. We never merge connections between drivers - // and/or kept wires. - mfp same_driver; - - // For each bit, store a set of connected driver bits for which the - // explicit connection should be preserved and the driving direction is - // locally unambiguous (one side only drives or requires a driven value). - DriveBitGraph connected_drivers; - - // For each bit, store a set of connected driver bits for which the - // explicit connection should be preserved and the driving direction is - // locally ambiguous. Every such ambiguous connection is also present in - // the reverse direction and has to be resolved when querying drivers. - DriveBitGraph connected_undirected; - - // Subset of `connected_undirected` for caching the resolved driving - // direction. In case multiple drivers are present this can still contain - // both orientations of a single connection, but for a single driver only - // one will be present. - DriveBitGraph connected_oriented; - - // Stores for which bits we already resolved the orientation (cached in - // `connected_oriented`). - pool oriented_present; - - - enum class BitMode { - NONE = 0, // Not driven, no need to keep wire - DRIVEN = 1, // Not driven, uses a value driven elsewhere - DRIVEN_UNIQUE = 2, // Uses a value driven elsewhere, has at most one direct connection - KEEP = 3, // Wire that should be kept - TRISTATE = 4, // Can drive a value but can also use a value driven elsewhere - DRIVER = 5, // Drives a value - }; + bool operator==(const DriveBitId &other) const; + bool operator!=(const DriveBitId &other) const; + bool operator<(const DriveBitId &other) const; + unsigned int hash() const; + }; - BitMode bit_mode(DriveBit const &bit); - DriveBitId id_from_drive_bit(DriveBit const &bit); - DriveBit drive_bit_from_id(DriveBitId id); + struct DriveBitGraph + { + dict first_edges; + dict second_edges; + dict> more_edges; + + void add_edge(DriveBitId src, DriveBitId dst); + DriveBitId pop_edge(DriveBitId src); + void clear(DriveBitId src); + bool contains(DriveBitId src); + int count(DriveBitId src); + DriveBitId at(DriveBitId src, int index); + }; - void connect_directed_merge(DriveBitId driven_id, DriveBitId driver_id); - void connect_directed_buffer(DriveBitId driven_id, DriveBitId driver_id); - void connect_undirected(DriveBitId a_id, DriveBitId b_id); + dict wire_offsets; + dict, DriveBitId> port_offsets; + std::map drive_bits; + dict isolated_drive_bits; + int next_offset; + mfp same_driver; + DriveBitGraph connected_drivers; + DriveBitGraph connected_undirected; + DriveBitGraph connected_oriented; + pool oriented_present; + + enum class BitMode + { + NONE = 0, + DRIVEN = 1, + DRIVEN_UNIQUE = 2, + KEEP = 3, + TRISTATE = 4, + DRIVER = 5, + }; + BitMode bit_mode(DriveBit const &bit); + DriveBitId id_from_drive_bit(DriveBit const &bit); + DriveBit drive_bit_from_id(DriveBitId id); + void connect_directed_merge(DriveBitId driven_id, DriveBitId driver_id); + void connect_directed_buffer(DriveBitId driven_id, DriveBitId driver_id); + void connect_undirected(DriveBitId a_id, DriveBitId b_id); + void add_port(Cell *cell, IdString const &port, SigSpec const &b); + void orient_undirected(DriveBitId id); + bool keep_wire(Wire *wire); + + // Only used a local variables in `orient_undirected`, always cleared, only + // stored to reduce allocations. + pool orient_undirected_seen; + pool orient_undirected_drivers; + dict orient_undirected_distance; + + public: + void add(Module *module); + void add(DriveBit const &a, DriveBit const &b); - void add(Module *module); - - // Add a single bit connection to the driver map. - void add(DriveBit const &a, DriveBit const &b); - + template static constexpr bool is_sig_type() { return @@ -561,31 +521,9 @@ struct DriverMap add(DriveBit(a[i]), DriveBit(b[i])); } - - // Specialized version that avoids unpacking - void add(SigSpec const &a, SigSpec const &b); - -private: - void add_port(Cell *cell, IdString const &port, SigSpec const &b); - - // Only used a local variables in `orient_undirected`, always cleared, only - // stored to reduce allocations. - pool orient_undirected_seen; - pool orient_undirected_drivers; - dict orient_undirected_distance; - - void orient_undirected(DriveBitId id); - -public: - DriveBit operator()(DriveBit const &bit); - - DriveSpec operator()(DriveSpec spec); - -private: - bool keep_wire(Wire *wire) { - // TODO configurable - return wire->has_attribute(ID(keep)); - } + void add(SigSpec const &a, SigSpec const &b); + DriveBit operator()(DriveBit const &bit); + DriveSpec operator()(DriveSpec spec); }; YOSYS_NAMESPACE_END