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.

526 lines
17 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 1992-2011 jean-pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
  5. * Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@verizon.net>
  6. * Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. /**
  26. * @file netlist.h
  27. */
  28. #ifndef _NETLIST_H_
  29. #define _NETLIST_H_
  30. #include <macros.h>
  31. #include <class_libentry.h>
  32. #include <sch_sheet_path.h>
  33. #include <sch_component.h>
  34. #include <sch_text.h>
  35. /// netlist types
  36. enum NETLIST_TYPE_ID {
  37. NET_TYPE_UNINIT = 0,
  38. NET_TYPE_PCBNEW,
  39. NET_TYPE_ORCADPCB2,
  40. NET_TYPE_CADSTAR,
  41. NET_TYPE_SPICE,
  42. NET_TYPE_CUSTOM1, /* NET_TYPE_CUSTOM1
  43. * is the first id for user netlist format
  44. * NET_TYPE_CUSTOM1+CUSTOMPANEL_COUNTMAX-1
  45. * is the last id for user netlist format
  46. */
  47. //NET_TYPE_CUSTOM_MAX = NET_TYPE_CUSTOM1 + CUSTOMPANEL_COUNTMAX - 1
  48. };
  49. /// Options for Spice netlist generation (OR'ed bits
  50. enum netlistOptions {
  51. NET_USE_X_PREFIX = 2, // for Spice netlist : change "U" and "IC" reference prefix to "X"
  52. NET_PCBNEW_USE_NEW_FORMAT = 1, // For Pcbnew use the new format (S expression and SWEET)
  53. };
  54. class SCH_COMPONENT;
  55. class SCH_REFERENC_LIST;
  56. #define NETLIST_HEAD_STRING "EESchema Netlist Version 1.1"
  57. // Max pin number per component and footprint
  58. #define MAXPIN 5000
  59. /**
  60. * Class SCH_REFERENCE
  61. * is used as a helper to define a component's reference designator in a schematic. This
  62. * helper is required in a complex hierarchy because a component can be used more than
  63. * once and its reference depends on the sheet path. This class is used to flatten the
  64. * schematic hierarchy for annotation, net list generation, and bill of material
  65. * generation.
  66. */
  67. class SCH_REFERENCE
  68. {
  69. private:
  70. /// Component reference prefix, without number (for IC1, this is IC) )
  71. std::string m_Ref; // it's private, use the accessors please
  72. SCH_COMPONENT* m_RootCmp; ///< The component associated the reference object.
  73. LIB_COMPONENT* m_Entry; ///< The source component from a library.
  74. wxPoint m_CmpPos; ///< The physical position of the component in schematic
  75. ///< used to annotate by X or Y position
  76. int m_Unit; ///< The unit number for components with multiple parts
  77. ///< per package.
  78. SCH_SHEET_PATH m_SheetPath; ///< The sheet path for this reference.
  79. bool m_IsNew; ///< True if not yet annotated.
  80. int m_SheetNum; ///< The sheet number for the reference.
  81. time_t m_TimeStamp; ///< The time stamp for the reference.
  82. EDA_TEXT* m_Value; ///< The component value of the refernce. It is the
  83. ///< same for all instances.
  84. int m_NumRef; ///< The numeric part of the reference designator.
  85. int m_Flag;
  86. friend class SCH_REFERENCE_LIST;
  87. public:
  88. SCH_REFERENCE()
  89. {
  90. m_RootCmp = NULL;
  91. m_Entry = NULL;
  92. m_Unit = 0;
  93. m_TimeStamp = 0;
  94. m_IsNew = false;
  95. m_Value = NULL;
  96. m_NumRef = 0;
  97. m_Flag = 0;
  98. m_SheetNum = 0;
  99. }
  100. SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_COMPONENT* aLibComponent,
  101. SCH_SHEET_PATH& aSheetPath );
  102. SCH_COMPONENT* GetComponent() const { return m_RootCmp; }
  103. LIB_COMPONENT* GetLibComponent() const { return m_Entry; }
  104. SCH_SHEET_PATH GetSheetPath() const { return m_SheetPath; }
  105. int GetUnit() const { return m_Unit; }
  106. void SetSheetNumber( int aSheetNumber ) { m_SheetNum = aSheetNumber; }
  107. /**
  108. * Function Annotate
  109. * updates the annotation of the component according the the current object state.
  110. */
  111. void Annotate();
  112. /**
  113. * Function Split
  114. * attempts to split the reference designator into a name (U) and number (1). If the
  115. * last character is '?' or not a digit, the reference is tagged as not annotated.
  116. * For components with multiple parts per package that are not already annotated, set
  117. * m_Unit to a max value (0x7FFFFFFF).
  118. */
  119. void Split();
  120. /* Some accessors which hide the strategy of how the reference is stored,
  121. thereby making it easy to change that strategy.
  122. */
  123. void SetRef( const wxString& aReference )
  124. {
  125. m_Ref = TO_UTF8( aReference );
  126. }
  127. wxString GetRef() const
  128. {
  129. return FROM_UTF8( m_Ref.c_str() );
  130. }
  131. void SetRefStr( const std::string& aReference )
  132. {
  133. m_Ref = aReference;
  134. }
  135. const char* GetRefStr() const
  136. {
  137. return m_Ref.c_str();
  138. }
  139. int CompareValue( const SCH_REFERENCE& item ) const
  140. {
  141. return m_Value->GetText().CmpNoCase( item.m_Value->GetText() );
  142. }
  143. int CompareRef( const SCH_REFERENCE& item ) const
  144. {
  145. return m_Ref.compare( item.m_Ref );
  146. }
  147. int CompareLibName( const SCH_REFERENCE& item ) const
  148. {
  149. return m_RootCmp->GetLibName().CmpNoCase( item.m_RootCmp->GetLibName() );
  150. }
  151. bool IsPartsLocked()
  152. {
  153. return m_Entry->UnitsLocked();
  154. }
  155. };
  156. /**
  157. * Class SCH_REFERENCE_LIST
  158. * is used create a flattened list of components because in a complex hierarchy, a component
  159. * can be used more than once and its reference designator is dependent on the sheet path for
  160. * the same component. This flattened list is used for netlist generation, BOM generation,
  161. * and schematic annotation.
  162. */
  163. class SCH_REFERENCE_LIST
  164. {
  165. private:
  166. std::vector <SCH_REFERENCE> componentFlatList;
  167. public:
  168. /** Constructor
  169. */
  170. SCH_REFERENCE_LIST()
  171. {
  172. }
  173. SCH_REFERENCE& operator[]( int aIndex )
  174. {
  175. return componentFlatList[ aIndex ];
  176. }
  177. /**
  178. * Function GetCount
  179. * @return the number of items in the list
  180. */
  181. unsigned GetCount()
  182. {
  183. return componentFlatList.size();
  184. }
  185. /**
  186. * Function GetItem
  187. * @return the aIdx item
  188. */
  189. SCH_REFERENCE& GetItem( int aIdx )
  190. {
  191. return componentFlatList[aIdx];
  192. }
  193. /**
  194. * Function AddItem
  195. * adds a SCH_REFERENCE object to the list of references.
  196. * @param aItem - a SCH_REFERENCE item to add
  197. */
  198. void AddItem( SCH_REFERENCE& aItem )
  199. {
  200. componentFlatList.push_back( aItem );
  201. }
  202. /**
  203. * Function RemoveItem
  204. * removes an item from the list of references.
  205. *
  206. * @param aIndex is the index of the item to be removed.
  207. */
  208. void RemoveItem( unsigned int aIndex );
  209. /**
  210. * Function RemoveSubComponentsFromList
  211. * Remove sub components from the list, when multiples parts per package are
  212. * found in this list.
  213. * Useful to create BOM, when a component must appear only once
  214. */
  215. void RemoveSubComponentsFromList();
  216. /* Sort functions:
  217. * Sort functions are used to sort components for annotation or BOM generation.
  218. * Because sorting depend on we want to do, there are many sort functions.
  219. * Note:
  220. * When creating BOM, components are fully annotated.
  221. * references are something like U3, U5 or R4, R8
  222. * When annotating, some or all components are not annotated,
  223. * i.e. ref is only U or R, with no number.
  224. */
  225. /**
  226. * Function SplitReferences
  227. * attempts to split all reference designators into a name (U) and number (1). If the
  228. * last character is '?' or not a digit, the reference is tagged as not annotated.
  229. * For components with multiple parts per package that are not already annotated, set
  230. * m_Unit to a max value (0x7FFFFFFF).
  231. * @see SCH_REFERENCE::Split()
  232. */
  233. void SplitReferences()
  234. {
  235. for( unsigned ii = 0; ii < GetCount(); ii++ )
  236. componentFlatList[ii].Split();
  237. }
  238. /**
  239. * function UpdateAnnotation
  240. * Updates the reference components for the schematic project (or the current sheet)
  241. * Note: this function does not calculate the reference numbers stored in m_NumRef
  242. * So, it must be called after calculation of new reference numbers
  243. * @see SCH_REFERENCE::Annotate()
  244. */
  245. void UpdateAnnotation()
  246. {
  247. /* update the reference numbers */
  248. for( unsigned ii = 0; ii < GetCount(); ii++ )
  249. {
  250. componentFlatList[ii].Annotate();
  251. }
  252. }
  253. /**
  254. * Function Annotate
  255. * set the reference designators in the list that have not been annotated.
  256. * @param aUseSheetNum Set to true to start annotation for each sheet at the sheet number
  257. * times \a aSheetIntervalId. Otherwise annotate incrementally.
  258. * @param aSheetIntervalId The per sheet reference designator multiplier.
  259. * <p>
  260. * If a the sheet number is 2 and \a aSheetIntervalId is 100, then the first reference
  261. * designator would be 201 and the last reference designator would be 299 when no overlap
  262. * occurs with sheet number 3. If there are 150 items in sheet number 2, then items are
  263. * referenced U201 to U351, and items in sheet 3 start from U352
  264. * </p>
  265. */
  266. void Annotate( bool aUseSheetNum, int aSheetIntervalId );
  267. /**
  268. * Function CheckAnnotation
  269. * check for annotations errors.
  270. * <p>
  271. * The following annotation error conditions are tested:
  272. * <ul>
  273. * <li>Components not annotated.</li>
  274. * <li>Components having the same reference designator (duplicates).</li>
  275. * <li>Components with multiple parts per package having different reference designators.</li>
  276. * <li>Components with multiple parts per package with invalid part count.</li>
  277. * </ul>
  278. * </p>
  279. * @param aMessageList A wxArrayString to store error messages.
  280. * @return The number of errors found.
  281. */
  282. int CheckAnnotation( wxArrayString* aMessageList );
  283. /**
  284. * Function sortByXCoordinate
  285. * sorts the list of references by X position.
  286. * <p>
  287. * Components are sorted as follows:
  288. * <ul>
  289. * <li>Numeric value of reference designator.</li>
  290. * <li>Sheet number.</li>
  291. * <li>X coordinate position.</li>
  292. * <li>Y coordinate position.</li>
  293. * <li>Time stamp.</li>
  294. * </ul>
  295. * </p>
  296. */
  297. void SortByXCoordinate()
  298. {
  299. sort( componentFlatList.begin(), componentFlatList.end(), sortByXPosition );
  300. }
  301. /**
  302. * Function sortByYCoordinate
  303. * sorts the list of references by Y position.
  304. * <p>
  305. * Components are sorted as follows:
  306. * <ul>
  307. * <li>Numeric value of reference designator.</li>
  308. * <li>Sheet number.</li>
  309. * <li>Y coordinate position.</li>
  310. * <li>X coordinate position.</li>
  311. * <li>Time stamp.</li>
  312. * </ul>
  313. * </p>
  314. */
  315. void SortByYCoordinate()
  316. {
  317. sort( componentFlatList.begin(), componentFlatList.end(), sortByYPosition );
  318. }
  319. /**
  320. * Function SortComponentsByTimeStamp
  321. * sort the flat list by Time Stamp.
  322. * Useful to detect duplicate Time Stamps
  323. */
  324. void SortByTimeStamp()
  325. {
  326. sort( componentFlatList.begin(), componentFlatList.end(), sortByTimeStamp );
  327. }
  328. /**
  329. * Function SortByRefAndValue
  330. * sorts the list of references by value.
  331. * <p>
  332. * Components are sorted in the following order:
  333. * <ul>
  334. * <li>Numeric value of reference designator.</li>
  335. * <li>Value of component.</li>
  336. * <li>Unit number when component has multiple parts.</li>
  337. * <li>Sheet number.</li>
  338. * <li>X coordinate position.</li>
  339. * <li>Y coordinate position.</li>
  340. * </ul>
  341. * </p>
  342. */
  343. void SortByRefAndValue()
  344. {
  345. sort( componentFlatList.begin(), componentFlatList.end(), sortByRefAndValue );
  346. }
  347. /**
  348. * Function SortByReferenceOnly
  349. * sorts the list of references by reference.
  350. * <p>
  351. * Components are sorted in the following order:
  352. * <ul>
  353. * <li>Numeric value of reference designator.</li>
  354. * <li>Unit number when component has multiple parts.</li>
  355. * </ul>
  356. * </p>
  357. */
  358. void SortByReferenceOnly()
  359. {
  360. sort( componentFlatList.begin(), componentFlatList.end(), sortByReferenceOnly );
  361. }
  362. /**
  363. * Function GetUnit
  364. * searches the sorted list of components for a another component with the same
  365. * reference and a given part unit. Use this method to manage components with
  366. * multiple parts per package.
  367. * @param aIndex = index in aComponentsList for of given SCH_REFERENCE item to test.
  368. * @param aUnit = the given unit number to search
  369. * @return index in aComponentsList if found or -1 if not found
  370. */
  371. int FindUnit( size_t aIndex, int aUnit );
  372. /**
  373. * Function ResetHiddenReferences
  374. * clears the annotation for all references that have an invisible reference designator.
  375. * Invisible reference designators always have # as the first letter.
  376. */
  377. void ResetHiddenReferences();
  378. /**
  379. * Function GetRefsInUse
  380. * adds all the reference designator numbers greater than \a aMinRefId to \a aIdList
  381. * skipping the reference at \a aIndex.
  382. * @param aIndex = the current component index to use for reference prefix filtering.
  383. * @param aIdList = the buffer to fill
  384. * @param aMinRefId = the min id value to store. all values < aMinRefId are ignored
  385. */
  386. void GetRefsInUse( int aIndex, std::vector< int >& aIdList, int aMinRefId );
  387. /**
  388. * Function GetLastReference
  389. * returns the last used (greatest) reference number in the reference list
  390. * for the prefix reference given by \a aIndex. The component list must be
  391. * sorted.
  392. *
  393. * @param aIndex The index of the reference item used for the search pattern.
  394. * @param aMinValue The minimum value for the current search.
  395. */
  396. int GetLastReference( int aIndex, int aMinValue );
  397. private:
  398. /* sort functions used to sort componentFlatList
  399. */
  400. static bool sortByRefAndValue( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
  401. static bool sortByXPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
  402. static bool sortByYPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
  403. static bool sortByTimeStamp( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
  404. static bool sortByReferenceOnly( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );
  405. /**
  406. * Function CreateFirstFreeRefId
  407. * searches for the first free reference number in \a aListId of reference numbers in use.
  408. * This function just searches for a hole in a list of incremented numbers, this list must
  409. * be sorted by increasing values and each value can be stored only once. The new value
  410. * is added to the list.
  411. * @see BuildRefIdInUseList to prepare this list
  412. * @param aIdList The buffer that contains the reference numbers in use.
  413. * @param aFirstValue The first expected free value
  414. * @return The first free (not yet used) value.
  415. */
  416. int CreateFirstFreeRefId( std::vector<int>& aIdList, int aFirstValue );
  417. };
  418. /**
  419. * Class BOM_LABEL
  420. * is used to build a List of Labels by handling the list of labels in schematic because in a
  421. * complex hierarchy, a label is used more than once and has more than one sheet path
  422. * so we must create a flat list of labels.
  423. */
  424. class BOM_LABEL
  425. {
  426. KICAD_T m_type;
  427. SCH_ITEM* m_label;
  428. // have to store it here since the object references will be duplicated.
  429. SCH_SHEET_PATH m_sheetPath; //composed of UIDs
  430. static const SCH_SHEET_PATH emptySheetPath;
  431. public:
  432. BOM_LABEL( KICAD_T aType = TYPE_NOT_INIT, SCH_ITEM* aLabel = NULL,
  433. const SCH_SHEET_PATH& aSheetPath = emptySheetPath )
  434. : m_type( aType )
  435. , m_label( aLabel )
  436. , m_sheetPath( aSheetPath )
  437. {
  438. }
  439. KICAD_T GetType() const { return m_type; }
  440. const SCH_ITEM* GetLabel() const { return m_label; }
  441. const SCH_SHEET_PATH& GetSheetPath() const { return m_sheetPath; }
  442. wxString GetText() const
  443. {
  444. const SCH_TEXT* tmp = (SCH_TEXT*) m_label;
  445. return tmp->GetText();
  446. }
  447. };
  448. typedef std::vector <BOM_LABEL> BOM_LABEL_LIST;
  449. #endif // _NETLIST_H_