Commit e0815667 authored by dickelbeck's avatar dickelbeck

more specctra dsn work

parent 12dfd80f
...@@ -75,6 +75,7 @@ const static KEYWORD tokens[] = { ...@@ -75,6 +75,7 @@ const static KEYWORD tokens[] = {
TOKDEF(base_design), TOKDEF(base_design),
TOKDEF(bbv_ctr2ctr), TOKDEF(bbv_ctr2ctr),
TOKDEF(bond), TOKDEF(bond),
TOKDEF(both),
TOKDEF(bottom), TOKDEF(bottom),
TOKDEF(bottom_layer_sel), TOKDEF(bottom_layer_sel),
TOKDEF(boundary), TOKDEF(boundary),
...@@ -246,6 +247,7 @@ const static KEYWORD tokens[] = { ...@@ -246,6 +247,7 @@ const static KEYWORD tokens[] = {
TOKDEF(noexpose), TOKDEF(noexpose),
TOKDEF(noise_accumulation), TOKDEF(noise_accumulation),
TOKDEF(noise_calculation), TOKDEF(noise_calculation),
TOKDEF(normal),
TOKDEF(object_type), TOKDEF(object_type),
TOKDEF(off), TOKDEF(off),
TOKDEF(off_grid), TOKDEF(off_grid),
...@@ -327,8 +329,8 @@ const static KEYWORD tokens[] = { ...@@ -327,8 +329,8 @@ const static KEYWORD tokens[] = {
TOKDEF(roundoff_rotation), TOKDEF(roundoff_rotation),
TOKDEF(route), TOKDEF(route),
TOKDEF(routes), TOKDEF(routes),
TOKDEF(routes_include),
TOKDEF(route_to_fanout_only), TOKDEF(route_to_fanout_only),
TOKDEF(routes_include),
TOKDEF(rule), TOKDEF(rule),
TOKDEF(same_net_checking), TOKDEF(same_net_checking),
TOKDEF(sample_window), TOKDEF(sample_window),
...@@ -385,8 +387,8 @@ const static KEYWORD tokens[] = { ...@@ -385,8 +387,8 @@ const static KEYWORD tokens[] = {
TOKDEF(terminator), TOKDEF(terminator),
TOKDEF(term_only), TOKDEF(term_only),
TOKDEF(test), TOKDEF(test),
TOKDEF(testpoint),
TOKDEF(test_points), TOKDEF(test_points),
TOKDEF(testpoint),
TOKDEF(threshold), TOKDEF(threshold),
TOKDEF(time_length_factor), TOKDEF(time_length_factor),
TOKDEF(time_resolution), TOKDEF(time_resolution),
......
...@@ -53,8 +53,9 @@ enum DSN_T { ...@@ -53,8 +53,9 @@ enum DSN_T {
T_EOF = -1, // special case for end of file T_EOF = -1, // special case for end of file
// from here down, this list segment should be coordinated with the // from here down, this list segment should be coordinated with the
// const static KEYWORD tokens[] array below, and must be sorted // const static KEYWORD tokens[] array in dsn.cpp, and must be sorted
// alphabetically. // alphabetically. Remember that '_' is less than any alpha character
// according to ASCII.
T_absolute, // this one should be == zero T_absolute, // this one should be == zero
T_added, T_added,
...@@ -74,6 +75,7 @@ enum DSN_T { ...@@ -74,6 +75,7 @@ enum DSN_T {
T_base_design, T_base_design,
T_bbv_ctr2ctr, T_bbv_ctr2ctr,
T_bond, T_bond,
T_both,
T_bottom, T_bottom,
T_bottom_layer_sel, T_bottom_layer_sel,
T_boundary, T_boundary,
...@@ -245,6 +247,7 @@ enum DSN_T { ...@@ -245,6 +247,7 @@ enum DSN_T {
T_noexpose, T_noexpose,
T_noise_accumulation, T_noise_accumulation,
T_noise_calculation, T_noise_calculation,
T_normal,
T_object_type, T_object_type,
T_off, T_off,
T_off_grid, T_off_grid,
...@@ -326,8 +329,8 @@ enum DSN_T { ...@@ -326,8 +329,8 @@ enum DSN_T {
T_roundoff_rotation, T_roundoff_rotation,
T_route, T_route,
T_routes, T_routes,
T_routes_include,
T_route_to_fanout_only, T_route_to_fanout_only,
T_routes_include,
T_rule, T_rule,
T_same_net_checking, T_same_net_checking,
T_sample_window, T_sample_window,
...@@ -384,8 +387,8 @@ enum DSN_T { ...@@ -384,8 +387,8 @@ enum DSN_T {
T_terminator, T_terminator,
T_term_only, T_term_only,
T_test, T_test,
T_testpoint,
T_test_points, T_test_points,
T_testpoint,
T_threshold, T_threshold,
T_time_length_factor, T_time_length_factor,
T_time_resolution, T_time_resolution,
......
...@@ -585,10 +585,8 @@ public: ...@@ -585,10 +585,8 @@ public:
rectangle->Format( out, nestLevel+1 ); rectangle->Format( out, nestLevel+1 );
else else
{ {
for( unsigned i=0; i<paths.size(); ++i ) for( PATHS::iterator i=paths.begin(); i!=paths.end(); ++i )
{ i->Format( out, nestLevel+1 );
paths[i].Format( out, nestLevel+1 );
}
} }
out->Print( nestLevel, ")\n" ); out->Print( nestLevel, ")\n" );
...@@ -793,8 +791,8 @@ public: ...@@ -793,8 +791,8 @@ public:
if( place_rules ) if( place_rules )
place_rules->Format( out, nestLevel+1 ); place_rules->Format( out, nestLevel+1 );
for( unsigned i=0; i<windows.size(); ++i ) for( WINDOWS::iterator i=windows.begin(); i!=windows.end(); ++i )
windows[i].Format( out, nestLevel+1 ); i->Format( out, nestLevel+1 );
out->Print( nestLevel, ")\n" ); out->Print( nestLevel, ")\n" );
} }
...@@ -819,8 +817,7 @@ public: ...@@ -819,8 +817,7 @@ public:
{ {
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) ); out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
for( STRINGS::const_iterator i=padstacks.begin(); for( STRINGS::iterator i=padstacks.begin(); i!=padstacks.end(); ++i )
i!=padstacks.end(); ++i )
{ {
const char* quote = out->GetQuoteChar( i->c_str() ); const char* quote = out->GetQuoteChar( i->c_str() );
...@@ -1088,8 +1085,8 @@ public: ...@@ -1088,8 +1085,8 @@ public:
{ {
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) ); out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
for( unsigned i=0; i<layer_pairs.size(); ++i ) for( LAYER_PAIRS::iterator i=layer_pairs.begin(); i!=layer_pairs.end(); ++i )
layer_pairs[i].Format( out, nestLevel+1 ); i->Format( out, nestLevel+1 );
out->Print( nestLevel, ")\n" ); out->Print( nestLevel, ")\n" );
} }
...@@ -1330,8 +1327,8 @@ public: ...@@ -1330,8 +1327,8 @@ public:
if( unit ) if( unit )
unit->Format( out, nestLevel ); unit->Format( out, nestLevel );
for( unsigned i=0; i<layers.size(); ++i ) for( LAYERS::iterator i=layers.begin(); i!=layers.end(); ++i )
layers[i].Format( out, nestLevel ); i->Format( out, nestLevel );
if( layer_noise_weight ) if( layer_noise_weight )
layer_noise_weight->Format( out, nestLevel ); layer_noise_weight->Format( out, nestLevel );
...@@ -1342,14 +1339,14 @@ public: ...@@ -1342,14 +1339,14 @@ public:
if( place_boundary ) if( place_boundary )
place_boundary->Format( out, nestLevel ); place_boundary->Format( out, nestLevel );
for( unsigned i=0; i<planes.size(); ++i ) for( PLANES::iterator i=planes.begin(); i!=planes.end(); ++i )
planes[i].Format( out, nestLevel ); i->Format( out, nestLevel );
for( unsigned i=0; i<regions.size(); ++i ) for( REGIONS::iterator i=regions.begin(); i!=regions.end(); ++i )
regions[i].Format( out, nestLevel ); i->Format( out, nestLevel );
for( unsigned i=0; i<keepouts.size(); ++i ) for( KEEPOUTS::iterator i=keepouts.begin(); i!=keepouts.end(); ++i )
keepouts[i].Format( out, nestLevel ); i->Format( out, nestLevel );
if( via ) if( via )
via->Format( out, nestLevel ); via->Format( out, nestLevel );
...@@ -1368,8 +1365,8 @@ public: ...@@ -1368,8 +1365,8 @@ public:
if( place_rules ) if( place_rules )
place_rules->Format( out, nestLevel ); place_rules->Format( out, nestLevel );
for( unsigned i=0; i<grids.size(); ++i ) for( GRIDS::iterator i=grids.begin(); i!=grids.end(); ++i )
grids[i].Format( out, nestLevel ); i->Format( out, nestLevel );
} }
DSN_T GetUnits() DSN_T GetUnits()
...@@ -1448,7 +1445,7 @@ public: ...@@ -1448,7 +1445,7 @@ public:
void SetRotation( double aRotation ) void SetRotation( double aRotation )
{ {
rotation = (float) aRotation; rotation = (float) aRotation;
isRotated = true; isRotated = (aRotation != 0.0);
} }
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ); void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError );
...@@ -1477,8 +1474,8 @@ public: ...@@ -1477,8 +1474,8 @@ public:
out->Print( nestLevel, "(%s %s%s%s\n", LEXER::GetTokenText( Type() ), out->Print( nestLevel, "(%s %s%s%s\n", LEXER::GetTokenText( Type() ),
quote, image_id.c_str(), quote ); quote, image_id.c_str(), quote );
for( unsigned i=0; i<places.size(); ++i ) for( PLACES::iterator i=places.begin(); i!=places.end(); ++i )
places[i].Format( out, nestLevel+1 ); i->Format( out, nestLevel+1 );
out->Print( nestLevel, ")\n" ); out->Print( nestLevel, ")\n" );
} }
...@@ -1520,28 +1517,8 @@ public: ...@@ -1520,28 +1517,8 @@ public:
LEXER::GetTokenText( flip_style ) ); LEXER::GetTokenText( flip_style ) );
} }
for( unsigned i=0; i<components.size(); ++i ) for( COMPONENTS::iterator i=components.begin(); i!=components.end(); ++i )
components[i].Format( out, nestLevel ); i->Format( out, nestLevel );
}
};
class IMAGE : public ELEM
{
friend class SPECCTRA_DB;
UNIT_RES* unit;
public:
IMAGE( ELEM* aParent ) :
ELEM( T_image, aParent )
{
unit = 0;
}
~IMAGE()
{
delete unit;
} }
DSN_T GetUnits() DSN_T GetUnits()
...@@ -1571,8 +1548,8 @@ class SHAPE : public ELEM ...@@ -1571,8 +1548,8 @@ class SHAPE : public ELEM
public: public:
SHAPE( ELEM* aParent ) : SHAPE( ELEM* aParent, DSN_T aType = T_shape ) :
ELEM( T_shape, aParent ) ELEM( aType, aParent )
{ {
connect = T_on; connect = T_on;
...@@ -1607,8 +1584,128 @@ public: ...@@ -1607,8 +1584,128 @@ public:
if( connect == T_off ) if( connect == T_off )
out->Print( nestLevel, "(connect %s)\n", LEXER::GetTokenText( connect ) ); out->Print( nestLevel, "(connect %s)\n", LEXER::GetTokenText( connect ) );
for( unsigned i=0; i<windows.size(); ++i ) for( WINDOWS::iterator i=windows.begin(); i!=windows.end(); ++i )
windows[i].Format( out, nestLevel ); i->Format( out, nestLevel );
}
};
class PIN : public ELEM
{
friend class SPECCTRA_DB;
std::string padstack_id;
float rotation;
bool isRotated;
std::string pin_id;
POINT vertex;
public:
PIN( ELEM* aParent ) :
ELEM( T_pin, aParent )
{
rotation = 0.0;
isRotated = false;
}
void SetRotation( double aRotation )
{
rotation = (float) aRotation;
isRotated = (aRotation != 0.0);
}
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
const char* quote = out->GetQuoteChar( padstack_id.c_str() );
if( isRotated )
out->Print( nestLevel, "(pin %s%s%s (rotate %1.2f)",
quote, padstack_id.c_str(), quote,
rotation
);
else
out->Print( nestLevel, "(pin %s%s%s", quote, padstack_id.c_str(), quote );
quote = out->GetQuoteChar( pin_id.c_str() );
out->Print( 0, " %s%s%s %f %f)\n", quote, pin_id.c_str(), quote,
vertex.x, vertex.y );
}
};
class IMAGE : public ELEM
{
friend class SPECCTRA_DB;
std::string image_id;
DSN_T side;
UNIT_RES* unit;
/* The grammar spec says only one outline is supported, but I am seeing
*.dsn examples with multiple outlines. So the outlines will go into
the kids list.
*/
typedef boost::ptr_vector<PIN> PINS;
PINS pins;
RULE* rules;
RULE* place_rules;
public:
IMAGE( ELEM* aParent ) :
ELEM( T_image, aParent )
{
side = T_both;
unit = 0;
rules = 0;
place_rules = 0;
}
~IMAGE()
{
delete unit;
delete rules;
delete place_rules;
}
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
const char* quote = out->GetQuoteChar( image_id.c_str() );
out->Print( nestLevel, "(%s %s%s%s", LEXER::GetTokenText( Type() ),
quote, image_id.c_str(), quote );
if( side != T_both )
out->Print( 0, " (side %s)", LEXER::GetTokenText( side ) );
out->Print( 0, "\n");
if( unit )
unit->Format( out, nestLevel+1 );
// format the kids, which in this class are the shapes
ELEM::FormatContents( out, nestLevel+1 );
for( PINS::iterator i=pins.begin(); i!=pins.end(); ++i )
i->Format( out, nestLevel+1 );
if( rules )
rules->Format( out, nestLevel+1 );
if( place_rules )
place_rules->Format( out, nestLevel+1 );
out->Print( nestLevel, ")\n" );
}
DSN_T GetUnits()
{
if( unit )
return unit->GetUnits();
return ELEM::GetUnits();
} }
}; };
...@@ -1622,9 +1719,12 @@ class PADSTACK : public ELEM ...@@ -1622,9 +1719,12 @@ class PADSTACK : public ELEM
/* The shapes are stored in the kids list */ /* The shapes are stored in the kids list */
RULE* rules;
DSN_T rotate; DSN_T rotate;
DSN_T absolute; DSN_T absolute;
DSN_T attach;
std::string via_id;
RULE* rules;
public: public:
...@@ -1632,9 +1732,10 @@ public: ...@@ -1632,9 +1732,10 @@ public:
ELEM( T_padstack, aParent ) ELEM( T_padstack, aParent )
{ {
unit = 0; unit = 0;
rules = 0;
rotate = T_on; rotate = T_on;
absolute = T_off; absolute = T_off;
rules = 0;
attach = T_off;
} }
~PADSTACK() ~PADSTACK()
{ {
...@@ -1655,11 +1756,26 @@ public: ...@@ -1655,11 +1756,26 @@ public:
// format the kids, which in this class are the shapes // format the kids, which in this class are the shapes
ELEM::FormatContents( out, nestLevel+1 ); ELEM::FormatContents( out, nestLevel+1 );
if( rotate == T_off ) out->Print( nestLevel+1, "%s", "" );
out->Print( nestLevel+1, "(rotate %s)", LEXER::GetTokenText( rotate ) );
if( absolute == T_on ) // spec for <attach_descriptor> says default is on, so
out->Print( nestLevel+1, "(absolute %s)", LEXER::GetTokenText( absolute ) ); // print the off condition to override this.
if( attach == T_off )
out->Print( 0, "(attach off)" );
else if( attach == T_on )
{
const char* quote = out->GetQuoteChar( via_id.c_str() );
out->Print( 0, "(attach on (use_via %s%s%s))",
quote, via_id.c_str(), quote );
}
if( rotate == T_off ) // print the non-default
out->Print( 0, "(rotate %s)", LEXER::GetTokenText( rotate ) );
if( absolute == T_on ) // print the non-default
out->Print( 0, "(absolute %s)", LEXER::GetTokenText( absolute ) );
out->Print( 0, "\n" );
if( rules ) if( rules )
rules->Format( out, nestLevel+1 ); rules->Format( out, nestLevel+1 );
...@@ -1712,11 +1828,11 @@ public: ...@@ -1712,11 +1828,11 @@ public:
if( unit ) if( unit )
unit->Format( out, nestLevel ); unit->Format( out, nestLevel );
for( unsigned i=0; i<images.size(); ++i ) for( IMAGES::iterator i=images.begin(); i!=images.end(); ++i )
images[i].Format( out, nestLevel ); i->Format( out, nestLevel );
for( unsigned i=0; i<padstacks.size(); ++i ) for( PADSTACKS::iterator i=padstacks.begin(); i!=padstacks.end(); ++i )
padstacks[i].Format( out, nestLevel ); i->Format( out, nestLevel );
} }
DSN_T GetUnits() DSN_T GetUnits()
...@@ -1729,6 +1845,113 @@ public: ...@@ -1729,6 +1845,113 @@ public:
}; };
class PIN_REF : public ELEM
{
friend class SPECCTRA_DB;
std::string component_id;
std::string pin_id;
public:
PIN_REF( ELEM* aParent ) :
ELEM( T_pin, aParent )
{
}
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
out->Print( nestLevel, "\"%s\"-\"%s\"\n",
component_id.c_str(), pin_id.c_str() );
}
};
class NET : public ELEM
{
friend class SPECCTRA_DB;
std::string net_id;
bool unassigned;
int net_number;
DSN_T pins_type; ///< T_pins | T_order
typedef std::vector<PIN_REF> PIN_REFS;
PIN_REFS pins;
DSN_T type; ///< T_fix | T_normal
DSN_T supply; ///< T_power | T_ground
RULE* rules;
public:
NET( ELEM* aParent ) :
ELEM( T_net, aParent )
{
unassigned = false;
net_number = T_NONE;
pins_type = T_pins;
type = T_NONE;
supply = T_NONE;
rules = 0;
}
~NET()
{
delete rules;
}
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
const char* quote = out->GetQuoteChar( net_id.c_str() );
out->Print( nestLevel, "(%s %s%s%s ", LEXER::GetTokenText( Type() ),
quote, net_id.c_str(), quote );
if( unassigned )
out->Print( 0, "(unassigned)" );
if( net_number != T_NONE )
out->Print( 0, "(net_number %d)", net_number );
out->Print( 0, "\n" );
out->Print( nestLevel+1, "(%s\n", LEXER::GetTokenText( pins_type ) );
for( PIN_REFS::iterator i=pins.begin(); i!=pins.end(); ++i )
i->Format( out, nestLevel+2 );
out->Print( nestLevel+1, ")\n" );
out->Print( nestLevel, ")\n" );
}
};
class NETWORK : public ELEM
{
friend class SPECCTRA_DB;
typedef boost::ptr_vector<NET> NETS;
NETS nets;
public:
NETWORK( ELEM* aParent ) :
ELEM( T_network, aParent )
{
}
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
for( NETS::iterator i=nets.begin(); i!=nets.end(); ++i )
i->Format( out, nestLevel );
}
};
class PCB : public ELEM class PCB : public ELEM
{ {
friend class SPECCTRA_DB; friend class SPECCTRA_DB;
...@@ -1740,6 +1963,7 @@ class PCB : public ELEM ...@@ -1740,6 +1963,7 @@ class PCB : public ELEM
STRUCTURE* structure; STRUCTURE* structure;
PLACEMENT* placement; PLACEMENT* placement;
LIBRARY* library; LIBRARY* library;
NETWORK* network;
public: public:
...@@ -1752,6 +1976,7 @@ public: ...@@ -1752,6 +1976,7 @@ public:
structure = 0; structure = 0;
placement = 0; placement = 0;
library = 0; library = 0;
network = 0;
} }
~PCB() ~PCB()
...@@ -1762,6 +1987,7 @@ public: ...@@ -1762,6 +1987,7 @@ public:
delete structure; delete structure;
delete placement; delete placement;
delete library; delete library;
delete network;
} }
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
...@@ -1789,6 +2015,9 @@ public: ...@@ -1789,6 +2015,9 @@ public:
if( library ) if( library )
library->Format( out, nestLevel+1 ); library->Format( out, nestLevel+1 );
if( network )
network->Format( out, nestLevel+1 );
out->Print( nestLevel, ")\n" ); out->Print( nestLevel, ")\n" );
} }
...@@ -1879,8 +2108,11 @@ class SPECCTRA_DB : public OUTPUTFORMATTER ...@@ -1879,8 +2108,11 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
void doPROPERTIES( PROPERTIES* growth ) throw( IOError ); void doPROPERTIES( PROPERTIES* growth ) throw( IOError );
void doPADSTACK( PADSTACK* growth ) throw( IOError ); void doPADSTACK( PADSTACK* growth ) throw( IOError );
void doSHAPE( SHAPE* growth ) throw( IOError ); void doSHAPE( SHAPE* growth ) throw( IOError );
void doIMAGE( IMAGE* growth ) throw( IOError );
void doLIBRARY( LIBRARY* growth ) throw( IOError ); void doLIBRARY( LIBRARY* growth ) throw( IOError );
void doPIN( PIN* growth ) throw( IOError );
void doNET( NET* growth ) throw( IOError );
void doNETWORK( NETWORK* growth ) throw( IOError );
public: public:
...@@ -2087,6 +2319,13 @@ void SPECCTRA_DB::doPCB( PCB* growth ) throw( IOError ) ...@@ -2087,6 +2319,13 @@ void SPECCTRA_DB::doPCB( PCB* growth ) throw( IOError )
doLIBRARY( growth->library ); doLIBRARY( growth->library );
break; break;
case T_network:
if( growth->network )
unexpected( tok );
growth->network = new NETWORK( growth );
doNETWORK( growth->network );
break;
default: default:
unexpected( lexer->CurText() ); unexpected( lexer->CurText() );
} }
...@@ -3551,6 +3790,20 @@ void SPECCTRA_DB::doPADSTACK( PADSTACK* growth ) throw( IOError ) ...@@ -3551,6 +3790,20 @@ void SPECCTRA_DB::doPADSTACK( PADSTACK* growth ) throw( IOError )
{ {
DSN_T tok = nextTok(); DSN_T tok = nextTok();
/* (padstack <padstack_id >
[<unit_descriptor> ]
{(shape <shape_descriptor>
[<reduced_shape_descriptor> ]
[(connect [on | off])]
[{<window_descriptor> }]
)}
[<attach_descriptor> ]
[{<pad_via_site_descriptor> }]
[(rotate [on | off])]
[(absolute [on | off])]
[(rule <clearance_descriptor> )])
*/
if( !isSymbol( tok ) ) if( !isSymbol( tok ) )
expecting( "padstack_id" ); expecting( "padstack_id" );
...@@ -3596,6 +3849,39 @@ void SPECCTRA_DB::doPADSTACK( PADSTACK* growth ) throw( IOError ) ...@@ -3596,6 +3849,39 @@ void SPECCTRA_DB::doPADSTACK( PADSTACK* growth ) throw( IOError )
doSHAPE( shape ); doSHAPE( shape );
break; break;
case T_attach:
tok = nextTok();
if( tok!=T_off && tok!=T_on )
expecting( "off|on" );
growth->attach = tok;
tok = nextTok();
if( tok == T_LEFT )
{
if( nextTok() != T_use_via )
expecting( T_use_via );
tok = nextTok();
if( !isSymbol( tok ) )
expecting( T_SYMBOL );
growth->via_id = lexer->CurText();
if( nextTok()!=T_RIGHT || nextTok()!=T_RIGHT )
expecting( T_RIGHT );
}
break;
/*
case T_via_site: not supported
break;
*/
case T_rule:
if( growth->rules )
unexpected( tok );
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
break;
default: default:
unexpected( lexer->CurText() ); unexpected( lexer->CurText() );
} }
...@@ -3607,12 +3893,30 @@ void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IOError ) ...@@ -3607,12 +3893,30 @@ void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IOError )
{ {
DSN_T tok; DSN_T tok;
/* (shape <shape_descriptor>
[<reduced_shape_descriptor> ]
[(connect [on | off])]
[{<window_descriptor> }])
*/
while( (tok = nextTok()) != T_RIGHT ) while( (tok = nextTok()) != T_RIGHT )
{ {
if( tok != T_LEFT ) if( tok != T_LEFT )
expecting( T_LEFT ); expecting( T_LEFT );
tok = nextTok(); tok = nextTok();
switch( tok )
{
case T_rect:
case T_circle:
case T_path:
case T_polygon:
case T_qarc:
if( growth->rectangle || growth->circle || growth->path || growth->qarc )
unexpected( tok );
default: ;
}
switch( tok ) switch( tok )
{ {
case T_rect: case T_rect:
...@@ -3641,6 +3945,8 @@ void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IOError ) ...@@ -3641,6 +3945,8 @@ void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IOError )
if( tok!=T_on && tok!=T_off ) if( tok!=T_on && tok!=T_off )
expecting( "on|off" ); expecting( "on|off" );
growth->connect = tok; growth->connect = tok;
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
break; break;
case T_window: case T_window:
...@@ -3657,10 +3963,156 @@ void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IOError ) ...@@ -3657,10 +3963,156 @@ void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IOError )
} }
void SPECCTRA_DB::doIMAGE( IMAGE* growth ) throw( IOError )
{
DSN_T tok = nextTok();
/* <image_descriptor >::=
(image <image_id >
[(side [front | back | both])]
[<unit_descriptor> ]
[<outline_descriptor> ]
{(pin <padstack_id > [(rotate <rotation> )]
[<reference_descriptor> | <pin_array_descriptor> ]
[<user_property_descriptor> ])}
[{<conductor_shape_descriptor> }]
[{<conductor_via_descriptor> }]
[<rule_descriptor> ]
[<place_rule_descriptor> ]
[{<keepout_descriptor> }]
[<image_property_descriptor> ]
)
*/
if( !isSymbol( tok ) )
expecting( "image_id" );
growth->image_id = lexer->CurText();
while( (tok = nextTok()) != T_RIGHT )
{
if( tok != T_LEFT )
expecting( T_LEFT );
tok = nextTok();
switch( tok )
{
case T_unit:
if( growth->unit )
unexpected( tok );
growth->unit = new UNIT_RES( growth, tok );
doUNIT( growth->unit );
break;
case T_side:
tok = nextTok();
if( tok!=T_front && tok!=T_back && tok!=T_both )
expecting( "front|back|both" );
growth->side = tok;
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
break;
case T_outline:
SHAPE* outline;
outline = new SHAPE( growth, T_outline ); // use SHAPE for T_outline
growth->Append( outline );
doSHAPE( outline );
break;
case T_pin:
PIN* pin;
pin = new PIN( growth );
growth->pins.push_back( pin );
doPIN( pin );
break;
case T_rule:
if( growth->rules )
unexpected( tok );
growth->rules = new RULE( growth, tok );
doRULE( growth->rules );
break;
case T_place_rule:
if( growth->place_rules )
unexpected( tok );
growth->place_rules = new RULE( growth, tok );
doRULE( growth->place_rules );
break;
default:
unexpected( lexer->CurText() );
}
}
}
void SPECCTRA_DB::doPIN( PIN* growth ) throw( IOError )
{
DSN_T tok = nextTok();
/* (pin <padstack_id > [(rotate <rotation> )]
[<reference_descriptor> | <pin_array_descriptor> ]
[<user_property_descriptor> ])
*/
if( !isSymbol( tok ) )
expecting( "padstack_id" );
growth->padstack_id = lexer->CurText();
tok = nextTok();
if( tok == T_LEFT )
{
tok = nextTok();
if( tok != T_rotate )
expecting( T_rotate );
if( nextTok() != T_NUMBER )
expecting( T_NUMBER );
growth->SetRotation( strtod( lexer->CurText(), 0 ) );
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
tok = nextTok();
}
if( !isSymbol(tok) && tok!=T_NUMBER )
expecting( "pin_id" );
growth->pin_id = lexer->CurText();
if( nextTok() != T_NUMBER )
expecting( T_NUMBER );
growth->vertex.x = strtod( lexer->CurText(), 0 );
if( nextTok() != T_NUMBER )
expecting( T_NUMBER );
growth->vertex.x = strtod( lexer->CurText(), 0 );
if( nextTok() != T_RIGHT )
unexpected( lexer->CurText() );
}
void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError ) void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError )
{ {
DSN_T tok; DSN_T tok;
/* <library_descriptor >::=
(library
[<unit_descriptor> ]
{<image_descriptor> }
[{<jumper_descriptor> }]
{<padstack_descriptor> }
{<via_array_template_descriptor> }
[<directory_descriptor> ]
[<extra_image_directory_descriptor> ]
[{<family_family_descriptor> }]
[{<image_image_descriptor> }]
)
*/
while( (tok = nextTok()) != T_RIGHT ) while( (tok = nextTok()) != T_RIGHT )
{ {
if( tok != T_LEFT ) if( tok != T_LEFT )
...@@ -3670,6 +4122,8 @@ void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError ) ...@@ -3670,6 +4122,8 @@ void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError )
switch( tok ) switch( tok )
{ {
case T_unit: case T_unit:
if( growth->unit )
unexpected( tok );
growth->unit = new UNIT_RES( growth, tok ); growth->unit = new UNIT_RES( growth, tok );
doUNIT( growth->unit ); doUNIT( growth->unit );
break; break;
...@@ -3681,10 +4135,147 @@ void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError ) ...@@ -3681,10 +4135,147 @@ void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError )
doPADSTACK( padstack ); doPADSTACK( padstack );
break; break;
/* @todo
case T_image: case T_image:
IMAGE* image;
image = new IMAGE( growth );
growth->images.push_back( image );
doIMAGE( image );
break;
default:
unexpected( lexer->CurText() );
}
}
}
void SPECCTRA_DB::doNET( NET* growth ) throw( IOError )
{
DSN_T tok = nextTok();
/* <net_descriptor >::=
(net <net_id >
[(unassigned)]
[(net_number <integer >)]
[(pins {<pin_reference> }) | (order {<pin_reference> })]
[<component_order_descriptor> ]
[(type [fix | normal])]
[<user_property_descriptor> ]
[<circuit_descriptor> ]
[<rule_descriptor> ]
[{<layer_rule_descriptor> }]
[<fromto_descriptor> ]
[(expose {<pin_reference> })]
[(noexpose {<pin_reference> })]
[(source {<pin_reference> })]
[(load {<pin_reference> })]
[(terminator {<pin_reference> })]
[(supply [power | ground])]
)
*/
if( !isSymbol( tok ) )
expecting( "net_id" );
growth->net_id = lexer->CurText();
while( (tok = nextTok()) != T_RIGHT )
{
if( tok != T_LEFT )
expecting( T_LEFT );
tok = nextTok();
switch( tok )
{
case T_unassigned:
growth->unassigned = true;
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
break;
case T_net_number:
if( nextTok() != T_NUMBER )
expecting( T_NUMBER );
growth->net_number = atoi( lexer->CurText() );
if( nextTok() != T_NUMBER )
expecting( T_NUMBER );
break;
case T_type:
tok = nextTok();
if( tok!=T_fix && tok!=T_normal )
expecting( "fix|normal" );
growth->type = tok;
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
break;
case T_pins:
case T_order:
growth->pins_type = tok;
{
PIN_REF empty( growth );
while( (tok = nextTok()) != T_RIGHT )
{
PIN_REF* pin_ref;
// copy the empty one, then fill its copy later thru pin_ref.
growth->pins.push_back( empty );
pin_ref = &growth->pins.back();
if( !isSymbol(tok) )
expecting("component_id");
pin_ref->component_id = lexer->CurText();
if( nextTok() != T_DASH )
expecting( T_DASH );
tok = nextTok();
if( !isSymbol(tok) )
expecting("component_id");
pin_ref->pin_id = lexer->CurText();
}
}
break;
default:
unexpected( lexer->CurText() );
}
}
}
void SPECCTRA_DB::doNETWORK( NETWORK* growth ) throw( IOError )
{
DSN_T tok;
/* <network_descriptor >::=
(network
{<net_descriptor>}
[{<class_descriptor> }]
[{<class_class_descriptor> }]
[{<group_descriptor> }]
[{<group_set_descriptor> }]
[{<pair_descriptor> }]
[{<bundle_descriptor> }]
)
*/
while( (tok = nextTok()) != T_RIGHT )
{
if( tok != T_LEFT )
expecting( T_LEFT );
tok = nextTok();
switch( tok )
{
case T_net:
NET* net;
net = new NET( growth );
growth->nets.push_back( net );
doNET( net );
break; break;
*/
default: default:
unexpected( lexer->CurText() ); unexpected( lexer->CurText() );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment