#ifndef _BSDL_MODEL_HPP_ #define _BSDL_MODEL_HPP_ #include "pin_model.hpp" #include "pin_spec.hpp" #include #include #include class Part; struct bsdl; // libbsdl C model — opaque here. // A parsed BSDL device reduced to essim's pin vocabulary. Value type: the // underlying libbsdl C model is consumed and freed during construction, so a // BsdlModel carries no C resources and copies/moves freely. class BsdlModel { public: struct Port { std::string name; ///< Logical BSDL port name. PinDirection direction = PinDirection::Unknown; PinFunction function = PinFunction::Unknown; ///< TAP role / power / ground / signal. std::string pad; ///< Physical package pin (PIN_MAP); "" if unmapped. }; static BsdlModel from_file(const std::string &path); static BsdlModel from_buffer(const std::string &text, const std::string &name = "bsdl"); bool valid() const { return ok_; } const std::string &entity() const { return entity_; } const std::string &error() const { return error_; } const std::vector &ports() const { return ports_; } private: static BsdlModel from_handle(struct bsdl *d); // consumes (frees) d. bool ok_ = false; std::string entity_; std::string error_; std::vector ports_; }; // Adapts a parsed BSDL device to the PinModel interface, indexing its ports by // both logical name and physical pad (so a netlist that names IC pins either by // signal or by ball both resolve). `layout()` is empty — BSDL drives specs, not // pin materialisation, since the netlist's pin naming may differ from the port // names. class BsdlPinModel : public PinModel { public: explicit BsdlPinModel(const BsdlModel &model); PinSpec spec_for(const std::string &pin_name) const override; std::vector layout() const override { return {}; } SpecSource source() const override { return SpecSource::Bsdl; } private: std::unordered_map by_name_; std::unordered_map by_pad_; }; // Outcome of binding a model onto a Part's pins. struct BsdlApplyReport { int pins_total = 0; int bound = 0; ///< Ports matched to a pin (by name, then by physical pad). int unbound = 0; ///< Ports with no matching pin on the part. }; // Set each matched Pin's `spec` (function / direction / pad, source = Bsdl) from // the model. A port is matched to a pin by port name first, then by physical pad // — so a netlist that names IC pins either by signal or by ball both bind. BsdlApplyReport apply_bsdl(Part *part, const BsdlModel &model); #endif // _BSDL_MODEL_HPP_