Files
essim/src/system/pin_model.hpp
François cb61e9b084 P3: unify connector layout + BSDL behind one PinModel provider
New PinModel interface (spec_for / layout / source) + a single apply_model(
Part*, const PinModel&) that materialises missing layout pins and sets each
pin's spec only where the model speaks (spec.source != None), so one source
never clobbers another's. ConnectorModel wraps pin_role/pin_layout;
BsdlPinModel wraps a parsed BsdlModel (indexed by port name and physical pad).
set-connector-type and screen_settype now use ConnectorModel + apply_model;
attach-bsdl and the restore re-apply keep calling apply_bsdl, now a thin
adapter over apply_model. Behaviour-preserving: unit tests (73 cases) green and
the real 8-card system re-runs identically (1517/1517 bound, same JTAG
findings). Covered by test_pin_model.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 16:02:39 +02:00

56 lines
2.0 KiB
C++

#ifndef _PIN_MODEL_HPP_
#define _PIN_MODEL_HPP_
#include "pin_spec.hpp"
#include <string>
#include <utility>
#include <vector>
class Part;
// A source of *expected* pin attributes for a part — a connector layout, a BSDL
// device, (later) a SPICE/Modelica model. Both of today's sources implement this
// interface and feed the single `apply_model()`, so `verify` stays agnostic of
// where a pin's spec came from.
struct PinModel {
virtual ~PinModel() = default;
// Expected spec for the pin identified by `pin_name` — its logical name, and
// for models that index physical pads, its package ball too. Returns a
// default PinSpec (source == None) when the model has nothing to say.
virtual PinSpec spec_for(const std::string &pin_name) const = 0;
// Canonical full pin-name list, used to materialise pins absent from the
// imported netlist. Empty means the model does not drive materialisation.
virtual std::vector<std::string> layout() const = 0;
// Which source this model represents (recorded in each spec it sets).
virtual SpecSource source() const = 0;
};
struct ApplyReport {
int pins_total = 0; ///< pins on the part after materialisation
int set = 0; ///< pins whose spec the model set
int materialised = 0; ///< pins created from layout()
};
// Materialise the layout pins missing from the part, then set each pin's `spec`
// from the model — only where the model actually speaks for that pin
// (`spec.source != None`), so a model never wipes another source's spec.
ApplyReport apply_model(Part *part, const PinModel &model);
// Connector-layout model: wraps `pin_role(kind, name)` / `pin_layout(kind)`.
class ConnectorModel : public PinModel {
public:
explicit ConnectorModel(std::string kind) : kind_(std::move(kind)) {}
PinSpec spec_for(const std::string &pin_name) const override;
std::vector<std::string> layout() const override;
SpecSource source() const override { return SpecSource::ConnectorModel; }
private:
std::string kind_;
};
#endif // _PIN_MODEL_HPP_