CADSTAR Parts: Fix parsing of hidden pins (possible for several pins per net!)
This commit is contained in:
parent
6ab2112135
commit
b70fe88145
|
@ -231,7 +231,7 @@ struct EQUIVALENT_PINS_GROUP :
|
|||
<
|
||||
plus<WHITESPACE_OR_CONTINUATION>,
|
||||
EQUIVALENT_PIN,
|
||||
plus<one<'='>, EQUIVALENT_PIN>
|
||||
plus<one<'='>, star<WHITESPACE_OR_CONTINUATION>, EQUIVALENT_PIN>
|
||||
>
|
||||
{};
|
||||
|
||||
|
@ -489,25 +489,14 @@ struct PIN_ENTRY :
|
|||
>
|
||||
{};
|
||||
|
||||
struct PIN_LIST : plus<PIN_ENTRY, star<WHITESPACE>, opt<LINE_CONTINUATION>> {};
|
||||
|
||||
struct SYMBOL_ENTRY :
|
||||
seq
|
||||
<
|
||||
SCH_SYMBOL_LINE,
|
||||
plus
|
||||
<
|
||||
PIN_ENTRY,
|
||||
star<WHITESPACE>,
|
||||
opt<LINE_CONTINUATION>
|
||||
>,
|
||||
opt<eol>
|
||||
>
|
||||
{};
|
||||
struct SYMBOL_ENTRY : seq<SCH_SYMBOL_LINE, PIN_LIST, opt<eol>>{};
|
||||
|
||||
|
||||
///<Signame>_<PinIdentifier>[.<Position>][!<Pintype>][:<Loading>]
|
||||
// /<Signame>_<PinIdentifier>[.<Position>][!<Pintype>][:<Loading>]
|
||||
struct PIN_SIGNAL_NAME : seq<one<'/'>, STRING_EXCLUDING<WHITESPACE>> {};
|
||||
struct HIDDEN_PIN_ENTRY : seq<PIN_SIGNAL_NAME, plus<WHITESPACE>, PIN_ENTRY, opt<eol>>{};
|
||||
struct HIDDEN_PIN_ENTRY : seq<PIN_SIGNAL_NAME, plus<WHITESPACE>, PIN_LIST, opt<eol>>{};
|
||||
|
||||
|
||||
//******************
|
||||
|
@ -548,7 +537,6 @@ struct PART_ENTRY :
|
|||
>
|
||||
{};
|
||||
|
||||
struct UNMATCHED_CONTENT : STRING_EXCLUDING<FORMAT, PART_ENTRY> {}; //@todo remove once parser is complete
|
||||
|
||||
/**
|
||||
* Grammar for CADSTAR Parts Library file format (*.lib)
|
||||
|
@ -561,7 +549,6 @@ struct GRAMMAR :
|
|||
sor
|
||||
<
|
||||
PART_ENTRY,
|
||||
//UNMATCHED_CONTENT, //@todo remove once parser is complete
|
||||
EMPTY_LINE // optional empty line
|
||||
>,
|
||||
opt<eol>
|
||||
|
|
|
@ -162,9 +162,12 @@ struct CADSTAR_PART_ENTRY
|
|||
|
||||
/**
|
||||
* Pins with an implied electrical connection to a net, not part of any symbol
|
||||
* (Note: we probably will need to import these into the first gate or something)
|
||||
* (Note: we probably will need to import these into the first gate)
|
||||
*
|
||||
* First = name of net (e.g. VCC/GND)
|
||||
* Second = list of pins of the part that are connected to this net
|
||||
*/
|
||||
std::vector<CADSTAR_PART_PIN> m_HiddenPins;
|
||||
std::map<std::string, std::vector<CADSTAR_PART_PIN>> m_HiddenPins;
|
||||
};
|
||||
|
||||
|
||||
|
@ -191,24 +194,21 @@ struct CADSTAR_PART_PIN
|
|||
m_Identifier( 0 ),
|
||||
m_Position( CADSTAR_PIN_POSITION::TOP_RIGHT ),
|
||||
m_Type( CADSTAR_PIN_TYPE::UNCOMMITTED ),
|
||||
m_Loading(),
|
||||
m_Signal()
|
||||
m_Loading()
|
||||
{};
|
||||
|
||||
CADSTAR_PART_PIN( long aId, CADSTAR_PIN_POSITION aPos, CADSTAR_PIN_TYPE aType,
|
||||
std::optional<long> aLoading, std::optional<std::string> aSignal ) :
|
||||
std::optional<long> aLoading ) :
|
||||
m_Identifier( aId ),
|
||||
m_Position( aPos ),
|
||||
m_Type( aType ),
|
||||
m_Loading( aLoading ),
|
||||
m_Signal( aSignal )
|
||||
m_Loading( aLoading )
|
||||
{};
|
||||
|
||||
long m_Identifier;
|
||||
CADSTAR_PIN_POSITION m_Position;
|
||||
CADSTAR_PIN_TYPE m_Type;
|
||||
std::optional<long> m_Loading;
|
||||
std::optional<std::string> m_Signal; // e.g. GND or VCC
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ struct CADSTAR_LIB_PARSER_STATE
|
|||
{
|
||||
std::string m_CurrentString;
|
||||
std::string m_CurrentAttrName;
|
||||
std::string m_CurrentSignalName;
|
||||
long m_CurrentLong = 0;
|
||||
std::vector<long> m_CurrentPinEquivalenceGroup;
|
||||
std::set<std::string> m_CurrentElementsParsed;
|
||||
|
@ -151,13 +152,13 @@ DEFINE_STRING_ACTION( STEM, m_CurrentPart.m_ComponentStem );
|
|||
DEFINE_STRING_ACTION( SYM_ELEMENT_NAME, m_CurrentSwapGroup.m_Name );
|
||||
DEFINE_STRING_ACTION( USER_PART_ATTRIBUTE_NAME, m_CurrentAttrName );
|
||||
DEFINE_STRING_ACTION( ATTRIBUTE_NAME, m_CurrentAttrName );
|
||||
DEFINE_STRING_ACTION( PIN_SIGNAL_NAME, m_CurrentSignalName );
|
||||
DEFINE_STRING_ACTION( ACCEPTANCE_PART_NAME, m_CurrentPart.m_AcceptancePartName );
|
||||
DEFINE_STRING_ACTION( ACCEPTANCE_TEXT, m_CurrentPart.m_AcceptanceText );
|
||||
DEFINE_STRING_ACTION( SPICE_PART_NAME, m_CurrentPart.m_SpicePartName );
|
||||
DEFINE_STRING_ACTION( SPICE_MODEL, m_CurrentPart.m_SpiceModel );
|
||||
DEFINE_STRING_ACTION( SCH_NAME, m_CurrentSymbol.m_SymbolName );
|
||||
DEFINE_STRING_ACTION( SCH_ALTERNATE, m_CurrentSymbol.m_SymbolAlternateName );
|
||||
DEFINE_STRING_ACTION( PIN_SIGNAL_NAME, m_CurrentPin.m_Signal );
|
||||
|
||||
|
||||
// STRING SEGMENT action
|
||||
|
@ -239,14 +240,6 @@ DECLARE_SINGLE_MATCH_RULE( SPI_LINE, );
|
|||
DECLARE_SINGLE_MATCH_RULE( PAC_LINE, );
|
||||
|
||||
|
||||
//@todo remove once complete
|
||||
template <>
|
||||
struct CADSTAR_LIB_PARSER_ACTION<UNMATCHED_CONTENT>
|
||||
{
|
||||
static void apply0( CADSTAR_LIB_PARSER_STATE& s ) { s.m_CurrentString = ""; }
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct CADSTAR_LIB_PARSER_ACTION<PINNAME_ENTRY>
|
||||
{
|
||||
|
@ -412,7 +405,8 @@ struct CADSTAR_LIB_PARSER_ACTION<HIDDEN_PIN_ENTRY>
|
|||
{
|
||||
static void apply0( CADSTAR_LIB_PARSER_STATE& s )
|
||||
{
|
||||
s.m_CurrentPart.m_HiddenPins.push_back( std::move( s.m_CurrentPinList[0] ) );
|
||||
s.m_CurrentPart.m_HiddenPins.insert(
|
||||
{ std::move( s.m_CurrentSignalName ), std::move( s.m_CurrentPinList ) } );
|
||||
s.m_CurrentPinList.clear();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -230,45 +230,37 @@ CADSTAR_SCH_ARCHIVE_LOADER::loadLibPart( const CADSTAR_PART_ENTRY& aPart )
|
|||
VECTOR2I direction( 0, -1 );
|
||||
int spacing = schIUScale.MilsToIU( 50 ); // for now, place on a 50mil grid
|
||||
|
||||
for( const CADSTAR_PART_PIN& csPin : aPart.m_HiddenPins )
|
||||
for( auto& [signalName, csPinVector] : aPart.m_HiddenPins )
|
||||
{
|
||||
std::unique_ptr<LIB_PIN> pin = std::make_unique<LIB_PIN>( retSym.get() );
|
||||
|
||||
long pinNum = csPin.m_Identifier;
|
||||
pin->SetNumber( wxString::Format( "%ld", pinNum ) );
|
||||
|
||||
if( csPin.m_Signal.has_value() )
|
||||
for( const CADSTAR_PART_PIN& csPin : csPinVector )
|
||||
{
|
||||
// Implied net connection
|
||||
pin->SetName( csPin.m_Signal.value() );
|
||||
std::unique_ptr<LIB_PIN> pin = std::make_unique<LIB_PIN>( retSym.get() );
|
||||
|
||||
long pinNum = csPin.m_Identifier;
|
||||
pin->SetNumber( wxString::Format( "%ld", pinNum ) );
|
||||
pin->SetName( signalName );
|
||||
pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
|
||||
}
|
||||
else if( aPart.m_PinNamesMap.count( pinNum ) )
|
||||
{
|
||||
pin->SetName( HandleTextOverbar( aPart.m_PinNamesMap.at( pinNum ) ) );
|
||||
pin->SetType( getKiCadPinType( csPin.m_Type ) );
|
||||
}
|
||||
|
||||
pin->SetVisible( false );
|
||||
pin->SetVisible( false );
|
||||
|
||||
// Generate the coordinate for the pin. We don't want overlapping pins
|
||||
// and ideally close to the center of the symbol, so we load pins sequentially
|
||||
// in a spiral sequence
|
||||
if( delta.x == delta.y
|
||||
|| ( delta.x < 0 && delta.x == -delta.y )
|
||||
|| ( delta.x > 0 && delta.x == 1 - delta.y ) )
|
||||
{
|
||||
// change direction
|
||||
direction = { -direction.y, direction.x };
|
||||
// Generate the coordinate for the pin. We don't want overlapping pins
|
||||
// and ideally close to the center of the symbol, so we load pins
|
||||
// in a spiral sequence around the center
|
||||
if( delta.x == delta.y || ( delta.x < 0 && delta.x == -delta.y )
|
||||
|| ( delta.x > 0 && delta.x == 1 - delta.y ) )
|
||||
{
|
||||
// change direction
|
||||
direction = { -direction.y, direction.x };
|
||||
}
|
||||
|
||||
delta += direction;
|
||||
VECTOR2I offset = delta * spacing;
|
||||
pin->SetPosition( symCenter + offset );
|
||||
pin->SetLength( 0 ); //CADSTAR Pins are just a point (have no length)
|
||||
pin->SetShape( GRAPHIC_PINSHAPE::LINE );
|
||||
pin->SetUnit( unit );
|
||||
retSym->AddDrawItem( pin.release() );
|
||||
}
|
||||
|
||||
delta += direction;
|
||||
VECTOR2I offset = delta * spacing;
|
||||
pin->SetPosition( symCenter + offset );
|
||||
pin->SetLength( 0 ); //CADSTAR Pins are just a point (have no length)
|
||||
pin->SetShape( GRAPHIC_PINSHAPE::LINE );
|
||||
pin->SetUnit( unit );
|
||||
retSym->AddDrawItem( pin.release() );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE( ReadFile )
|
|||
|
||||
// Check hidden pins
|
||||
BOOST_REQUIRE_EQUAL( partEntry.m_HiddenPins.size(), 1 );
|
||||
BOOST_CHECK_EQUAL( partEntry.m_HiddenPins[0].m_Signal, "GND" );
|
||||
BOOST_CHECK_EQUAL( partEntry.m_HiddenPins.count( "GND" ), 1 );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ BOOST_AUTO_TEST_CASE( ReadContent )
|
|||
"<SCM Symbol Refname2>\r\n"
|
||||
"4.2!U:1000 5.1!I 6.3!Q\r\n"
|
||||
"/GND 7.0!G:2000\r\n"
|
||||
"/VCC 8.0!P:2000\r\n";
|
||||
"/VCC 8.0!P:2000 9.1 10.0\r\n";
|
||||
//"etc ...\r\n"
|
||||
//"/<Signame> <PinIdentifier>.<Position>!<Pintype>:<Loading>\r\n"
|
||||
//"/<Signame> <PinIdentifier>.<Position>!<Pintype>:<Loading>\r\n";
|
||||
|
@ -404,24 +404,31 @@ BOOST_AUTO_TEST_CASE( ReadContent )
|
|||
// Check symbols
|
||||
std::vector<CADSTAR_PART_SYMBOL_ENTRY> symbols = result.m_PartEntries[0].m_Symbols;
|
||||
|
||||
std::vector<CADSTAR_PART_SYMBOL_ENTRY> expectedSymbols = {
|
||||
{ "<SCM Symbol Refname1>",
|
||||
"<SCM Alternate Refname>",
|
||||
{ CADSTAR_PART_PIN( 1, CADSTAR_PIN_POSITION::TOP_RIGHT, CADSTAR_PIN_TYPE::TRISTATE_DRIVER,
|
||||
2000, std::optional<std::string>() ),
|
||||
CADSTAR_PART_PIN( 2, CADSTAR_PIN_POSITION::TOP_LEFT, CADSTAR_PIN_TYPE::TRISTATE_INPUT,
|
||||
std::optional<long>(), std::optional<std::string>() ),
|
||||
CADSTAR_PART_PIN( 3, CADSTAR_PIN_POSITION::BOTTOM_LEFT, CADSTAR_PIN_TYPE::TRISTATE_BIDIR,
|
||||
std::optional<long>(), std::optional<std::string>() ) }
|
||||
std::vector<CADSTAR_PART_SYMBOL_ENTRY> expectedSymbols =
|
||||
{
|
||||
{
|
||||
"<SCM Symbol Refname1>",
|
||||
"<SCM Alternate Refname>",
|
||||
{
|
||||
{ 1, CADSTAR_PIN_POSITION::TOP_RIGHT, CADSTAR_PIN_TYPE::TRISTATE_DRIVER,
|
||||
2000 },
|
||||
{ 2, CADSTAR_PIN_POSITION::TOP_LEFT, CADSTAR_PIN_TYPE::TRISTATE_INPUT,
|
||||
std::nullopt },
|
||||
{ 3, CADSTAR_PIN_POSITION::BOTTOM_LEFT, CADSTAR_PIN_TYPE::TRISTATE_BIDIR,
|
||||
std::nullopt }
|
||||
}
|
||||
},
|
||||
{ "<SCM Symbol Refname2>",
|
||||
std::optional<std::string>(),
|
||||
{ CADSTAR_PART_PIN( 4, CADSTAR_PIN_POSITION::BOTTOM_LEFT, CADSTAR_PIN_TYPE::UNCOMMITTED,
|
||||
1000, std::optional<std::string>() ),
|
||||
CADSTAR_PART_PIN( 5, CADSTAR_PIN_POSITION::TOP_LEFT, CADSTAR_PIN_TYPE::INPUT,
|
||||
std::optional<long>(), std::optional<std::string>() ),
|
||||
CADSTAR_PART_PIN( 6, CADSTAR_PIN_POSITION::BOTTOM_RIGHT, CADSTAR_PIN_TYPE::OUTPUT_NOT_NORM_OR,
|
||||
std::optional<long>(), std::optional<std::string>() ) }
|
||||
{
|
||||
"<SCM Symbol Refname2>",
|
||||
std::nullopt,
|
||||
{
|
||||
{ 4, CADSTAR_PIN_POSITION::BOTTOM_LEFT, CADSTAR_PIN_TYPE::UNCOMMITTED,
|
||||
1000 },
|
||||
{ 5, CADSTAR_PIN_POSITION::TOP_LEFT, CADSTAR_PIN_TYPE::INPUT,
|
||||
std::nullopt },
|
||||
{ 6, CADSTAR_PIN_POSITION::BOTTOM_RIGHT, CADSTAR_PIN_TYPE::OUTPUT_NOT_NORM_OR,
|
||||
std::nullopt }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -451,7 +458,6 @@ BOOST_AUTO_TEST_CASE( ReadContent )
|
|||
BOOST_CHECK( itPinsA->m_Position == itPinsB->m_Position );
|
||||
BOOST_CHECK( itPinsA->m_Type == itPinsB->m_Type );
|
||||
BOOST_CHECK_EQUAL( itPinsA->m_Loading, itPinsB->m_Loading );
|
||||
BOOST_CHECK_EQUAL( itPinsA->m_Signal, itPinsB->m_Signal );
|
||||
}
|
||||
|
||||
++itPinsA;
|
||||
|
@ -464,30 +470,54 @@ BOOST_AUTO_TEST_CASE( ReadContent )
|
|||
}
|
||||
|
||||
// Compare hidden pins
|
||||
std::vector<CADSTAR_PART_PIN> expectedHiddenPins = {
|
||||
{ 7, CADSTAR_PIN_POSITION::TOP_RIGHT, CADSTAR_PIN_TYPE::GROUND, 2000, "GND" },
|
||||
{ 8, CADSTAR_PIN_POSITION::TOP_RIGHT, CADSTAR_PIN_TYPE::POWER, 2000, "VCC" }
|
||||
std::map<std::string,std::vector<CADSTAR_PART_PIN>> expectedHiddenPins =
|
||||
{
|
||||
{
|
||||
"GND",
|
||||
{
|
||||
{ 7, CADSTAR_PIN_POSITION::TOP_RIGHT, CADSTAR_PIN_TYPE::GROUND, 2000 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"VCC",
|
||||
{
|
||||
{ 8, CADSTAR_PIN_POSITION::TOP_RIGHT, CADSTAR_PIN_TYPE::POWER, 2000 },
|
||||
{ 9, CADSTAR_PIN_POSITION::TOP_LEFT, CADSTAR_PIN_TYPE::UNCOMMITTED, std::nullopt },
|
||||
{ 10, CADSTAR_PIN_POSITION::TOP_RIGHT, CADSTAR_PIN_TYPE::UNCOMMITTED, std::nullopt }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_REQUIRE_EQUAL( result.m_PartEntries[0].m_HiddenPins.size(), expectedHiddenPins.size() );
|
||||
|
||||
auto itPinsA = result.m_PartEntries[0].m_HiddenPins.begin();
|
||||
auto itPinsB = expectedHiddenPins.begin();
|
||||
auto itEntryA = result.m_PartEntries[0].m_HiddenPins.begin();
|
||||
auto itEntryB = expectedHiddenPins.begin();
|
||||
|
||||
while( itPinsA != result.m_PartEntries[0].m_HiddenPins.end()
|
||||
|| itPinsB != expectedHiddenPins.end() )
|
||||
while( itEntryA != result.m_PartEntries[0].m_HiddenPins.end()
|
||||
|| itEntryB != expectedHiddenPins.end() )
|
||||
{
|
||||
BOOST_TEST_CONTEXT( "Pin Identifier = " << itPinsB->m_Signal )
|
||||
BOOST_TEST_CONTEXT( "Check Hidden pins - Signal = " << itEntryB->first )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( itPinsA->m_Identifier, itPinsB->m_Identifier );
|
||||
BOOST_CHECK( itPinsA->m_Position == itPinsB->m_Position );
|
||||
BOOST_CHECK( itPinsA->m_Type == itPinsB->m_Type );
|
||||
BOOST_CHECK_EQUAL( itPinsA->m_Loading, itPinsB->m_Loading );
|
||||
BOOST_CHECK_EQUAL( itPinsA->m_Signal, itPinsB->m_Signal );
|
||||
BOOST_CHECK_EQUAL( itEntryA->first, itEntryB->first );
|
||||
BOOST_REQUIRE_EQUAL( itEntryA->second.size(), itEntryB->second.size() );
|
||||
|
||||
auto itPinsA = itEntryA->second.begin();
|
||||
auto itPinsB = itEntryB->second.begin();
|
||||
|
||||
while( itPinsA != itEntryA->second.end() || itPinsB != itEntryB->second.end() )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( itPinsA->m_Identifier, itPinsB->m_Identifier );
|
||||
BOOST_CHECK( itPinsA->m_Position == itPinsB->m_Position );
|
||||
BOOST_CHECK( itPinsA->m_Type == itPinsB->m_Type );
|
||||
BOOST_CHECK_EQUAL( itPinsA->m_Loading, itPinsB->m_Loading );
|
||||
|
||||
++itPinsA;
|
||||
++itPinsB;
|
||||
}
|
||||
}
|
||||
|
||||
++itPinsA;
|
||||
++itPinsB;
|
||||
++itEntryA;
|
||||
++itEntryB;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue