You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

347 lines
8.9 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2018 CERN
  5. * @author Jon Evans <jon@craftyjon.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef _SCH_CONNECTION_H
  21. #define _SCH_CONNECTION_H
  22. #include <memory>
  23. #include <unordered_set>
  24. #include <boost/optional.hpp>
  25. #include <wx/regex.h>
  26. #include <bus_alias.h>
  27. #include <msgpanel.h>
  28. #include <sch_sheet_path.h>
  29. class SCH_ITEM;
  30. class SCH_SHEET_PATH;
  31. enum CONNECTION_TYPE
  32. {
  33. CONNECTION_NONE, ///< No connection to this item
  34. CONNECTION_NET, ///< This item represents a net
  35. CONNECTION_BUS, ///< This item represents a bus vector
  36. CONNECTION_BUS_GROUP, ///< This item represents a bus group
  37. };
  38. /**
  39. * Each graphical item can have a SCH_CONNECTION describing its logical
  40. * connection (to a bus or net). These are generated when netlisting, or when
  41. * editing operations that can change the netlist are performed.
  42. *
  43. * In hierarchical schematics, a single SCH_ITEM object can refer to multiple
  44. * distinct parts of a design (in the case of a sub-sheet that is instanced
  45. * more than once in a higher level sheet). Because of this, a single item may
  46. * contain more than one SCH_CONNECTION -- each is specific to a sheet.
  47. *
  48. * Components contain connections for each of their pins (and for each sheet
  49. * they exist on) but don't use their own connection object.
  50. */
  51. class SCH_CONNECTION
  52. {
  53. public:
  54. SCH_CONNECTION( SCH_ITEM* aParent = nullptr, SCH_SHEET_PATH aPath = SCH_SHEET_PATH() );
  55. ~SCH_CONNECTION()
  56. {}
  57. /**
  58. * Note: the equality operator for SCH_CONNECTION only tests the net
  59. * properties, not the ownership / sheet location!
  60. */
  61. bool operator==( const SCH_CONNECTION& aOther ) const;
  62. bool operator!=( const SCH_CONNECTION& aOther ) const;
  63. /**
  64. * Configures the connection given a label.
  65. * For CONNECTION_NET, this just sets the name.
  66. * For CONNECTION_BUS, this will deduce the correct BUS_TYPE and also
  67. * generate a correct list of members.
  68. */
  69. void ConfigureFromLabel( wxString aLabel );
  70. /**
  71. * Clears connectivity information
  72. */
  73. void Reset();
  74. /**
  75. * Copies connectivity information (but not parent) from another connection
  76. *
  77. * @param aOther is the connection to clone
  78. */
  79. void Clone( SCH_CONNECTION& aOther );
  80. SCH_ITEM* Parent() const
  81. {
  82. return m_parent;
  83. }
  84. SCH_ITEM* Driver() const
  85. {
  86. return m_driver;
  87. }
  88. SCH_SHEET_PATH Sheet() const
  89. {
  90. return m_sheet;
  91. }
  92. void SetDriver( SCH_ITEM* aItem );
  93. void SetSheet( SCH_SHEET_PATH aSheet );
  94. /**
  95. * Checks if the SCH_ITEM this connection is attached to can drive connections
  96. * Drivers can be labels, sheet pins, or component pins.
  97. *
  98. * @return true if the attached items is a driver
  99. */
  100. bool IsDriver() const;
  101. bool IsBus() const
  102. {
  103. return ( m_type == CONNECTION_BUS || m_type == CONNECTION_BUS_GROUP );
  104. }
  105. bool IsNet() const
  106. {
  107. return ( m_type == CONNECTION_NET );
  108. }
  109. bool IsDirty() const
  110. {
  111. return m_dirty;
  112. }
  113. void SetDirty()
  114. {
  115. m_dirty = true;
  116. }
  117. void ClearDirty()
  118. {
  119. m_dirty = false;
  120. }
  121. wxString Name( bool aIgnoreSheet = false ) const;
  122. wxString Prefix() const
  123. {
  124. return m_prefix;
  125. }
  126. void SetPrefix( wxString aPrefix )
  127. {
  128. m_prefix = aPrefix;
  129. }
  130. CONNECTION_TYPE Type() const
  131. {
  132. return m_type;
  133. }
  134. void SetType( CONNECTION_TYPE aType )
  135. {
  136. m_type = aType;
  137. }
  138. int NetCode() const
  139. {
  140. return m_net_code;
  141. }
  142. void SetNetCode( int aCode )
  143. {
  144. m_net_code = aCode;
  145. }
  146. int BusCode() const
  147. {
  148. return m_bus_code;
  149. }
  150. void SetBusCode( int aCode )
  151. {
  152. m_bus_code = aCode;
  153. }
  154. int SubgraphCode() const
  155. {
  156. return m_subgraph_code;
  157. }
  158. void SetSubgraphCode( int aCode )
  159. {
  160. m_subgraph_code = aCode;
  161. }
  162. long VectorStart() const
  163. {
  164. return m_vector_start;
  165. }
  166. long VectorEnd() const
  167. {
  168. return m_vector_end;
  169. }
  170. long VectorIndex() const
  171. {
  172. return m_vector_index;
  173. }
  174. wxString VectorPrefix() const
  175. {
  176. return m_vector_prefix;
  177. }
  178. std::vector< std::shared_ptr< SCH_CONNECTION > >& Members()
  179. {
  180. return m_members;
  181. }
  182. const std::vector< std::shared_ptr< SCH_CONNECTION > >& Members() const
  183. {
  184. return m_members;
  185. }
  186. /**
  187. * Returns true if aOther is a subset of this connection or vice versa.
  188. *
  189. * For plain nets, this just tests whether or not the connectio names are
  190. * the same. For buses, this tests whether the two have any shared members.
  191. *
  192. * Will always return false if one connection is a bus and the other a net.
  193. */
  194. bool IsSubsetOf( SCH_CONNECTION* aOther ) const;
  195. /**
  196. * Returns true if this connection is a member of bus connection aOther
  197. *
  198. * Will always return false if aOther is not a bus connection
  199. */
  200. bool IsMemberOfBus( SCH_CONNECTION* aOther ) const;
  201. /**
  202. * Parses a bus vector (e.g. A[7..0]) into name, begin, and end.
  203. * Ensures that begin and end are positive and that end > begin.
  204. *
  205. * @param vector is a bus vector label string
  206. * @param name output of the name portion of the label
  207. * @param begin is the first entry in the vector
  208. * @param end is the last entry in the vector
  209. */
  210. void ParseBusVector( wxString vector, wxString* name,
  211. long* begin, long* end ) const;
  212. /**
  213. * Parses a bus group label into the name and a list of components
  214. *
  215. * @param aGroup is the input label, e.g. "USB{DP DM}"
  216. * @param name is the output group name, e.g. "USB"
  217. * @param aMemberList is a list of member strings, e.g. "DP", "DM"
  218. * @return true if aGroup was successfully parsed
  219. */
  220. bool ParseBusGroup( wxString aGroup, wxString* name,
  221. std::vector<wxString>& aMemberList ) const;
  222. /**
  223. * Adds information about the connection object to aList
  224. */
  225. void AppendInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const;
  226. /**
  227. * Adds extended debug information about the connection object to aList
  228. */
  229. void AppendDebugInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const;
  230. /**
  231. * Test if \a aLabel has a bus notation.
  232. *
  233. * @param aLabel A wxString object containing the label to test.
  234. * @return true if text is a bus notation format otherwise false is returned.
  235. */
  236. bool IsBusLabel( const wxString& aLabel );
  237. /**
  238. * Test if \a aLabel has a bus vector notation (simple bus, e.g. A[7..0])
  239. *
  240. * @param aLabel A wxString object containing the label to test.
  241. * @return true if text is a bus notation format otherwise false is returned.
  242. */
  243. bool IsBusVectorLabel( const wxString& aLabel );
  244. /**
  245. * Test if \a aLabel has a bus group notation.
  246. *
  247. * @param aLabel A wxString object containing the label to test.
  248. * @return true if text is a bus group notation format
  249. */
  250. bool IsBusGroupLabel( const wxString& aLabel );
  251. private:
  252. bool m_dirty;
  253. SCH_SHEET_PATH m_sheet; ///< The hierarchical sheet this connection is on
  254. SCH_ITEM* m_parent; ///< The SCH_ITEM this connection is owned by
  255. SCH_ITEM* m_driver; ///< The SCH_ITEM that drives this connection's net
  256. CONNECTION_TYPE m_type; ///< @see enum CONNECTION_TYPE
  257. wxString m_name; ///< Name of the bus.
  258. ///< Prefix if connection is member of a labeled bus group (or "" if not)
  259. wxString m_prefix;
  260. int m_net_code; // TODO(JE) remove if unused
  261. int m_bus_code; // TODO(JE) remove if unused
  262. int m_subgraph_code; ///< Groups directly-connected items
  263. long m_vector_index; ///< Index of bus vector member nets
  264. long m_vector_start; ///< Highest member of a vector bus
  265. long m_vector_end; ///< Lowest member of a vector bus
  266. ///< Prefix name of the vector, if m_type == CONNECTION_BUS (or "" if not)
  267. wxString m_vector_prefix;
  268. /**
  269. * For bus connections, store a list of member connections
  270. *
  271. * NOTE: All connections that Clone() others share the list of member
  272. * pointers. This seems fine at the moment.
  273. */
  274. std::vector< std::shared_ptr< SCH_CONNECTION > > m_members;
  275. };
  276. #endif