Files
essim/src/system/pin_spec.hpp
François fe5b2c3d96 P3.2: source precedence + model-vs-netlist conflict check
Rank the spec sources (spec_source_rank: UserOverride > Bsdl > ConnectorModel
> Inferred > Imported); apply_model now refuses to overwrite a spec owned by a
higher-rank source, so one model never clobbers a more authoritative one. New
check_source_conflicts(System*) emits SourceConflict for a pin the BSDL
declares power/ground (a must-connect rail) that the netlist leaves
unconnected — a rail floated in the schematic; surfaced as a sixth `verify`
pass. Unit tests (75 cases) green; the real 8-card system reports 0 conflicts
(its rails are all connected) while the JTAG findings remain.

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

72 lines
2.6 KiB
C++

#ifndef _PIN_SPEC_HPP_
#define _PIN_SPEC_HPP_
#include "signal_type.hpp"
#include <string>
#pragma once
// Direction of a pin as seen from the component (port/BSDL semantics).
enum class PinDirection { Unknown, In, Out, Bidir, Passive, Power };
// Functional role of a pin. Richer than SignalType (which classifies *nets*):
// this classifies the *pin* itself and carries the TAP roles JTAG checks need.
enum class PinFunction {
Unknown, Power, Ground, Signal, Clock, NoConnect,
JtagTdi, JtagTdo, JtagTms, JtagTck, JtagTrst
};
// Where a pin's expected attributes came from. Lets verify report conflicts and
// lets a user override win over a model-derived value.
enum class SpecSource { None, Imported, ConnectorModel, Bsdl, Inferred, UserOverride };
// Expected, model-derived attributes of a pin (from a connector layout, a BSDL
// model, …). The "expected" half of the expected-vs-observed verify duality;
// the "observed" half stays Pin::signal() + the net + inference.
struct PinSpec {
PinFunction function = PinFunction::Unknown;
PinDirection direction = PinDirection::Unknown;
std::string pad; ///< Physical terminal (package ball/pin); "" if unknown.
SpecSource source = SpecSource::None;
};
// PinFunction -> the net SignalType a pin of that function expects to sit on.
inline SignalType to_signal_type(PinFunction f)
{
switch (f) {
case PinFunction::Power: return SignalType::Power;
case PinFunction::Ground: return SignalType::GndShield;
default: return SignalType::Other;
}
}
// Coarse SignalType -> PinFunction, used when a model only yields a SignalType.
inline PinFunction function_from_signal_type(SignalType t)
{
switch (t) {
case SignalType::Power: return PinFunction::Power;
case SignalType::GndShield: return PinFunction::Ground;
default: return PinFunction::Unknown;
}
}
// Precedence of spec sources: a higher rank wins when two sources speak for the
// same pin. A user override beats any model; a device model (BSDL) beats a
// connector layout; both beat plain import / inference. Used by apply_model to
// avoid clobbering a more authoritative spec.
inline int spec_source_rank(SpecSource s)
{
switch (s) {
case SpecSource::None: return 0;
case SpecSource::Imported: return 1;
case SpecSource::Inferred: return 2;
case SpecSource::ConnectorModel: return 3;
case SpecSource::Bsdl: return 4;
case SpecSource::UserOverride: return 5;
}
return 0;
}
#endif // _PIN_SPEC_HPP_