/*
* hyp2mat - convert hyperlynx files to matlab scripts
* Copyright 2012 Koen De Vleeschauwer.
*
* This file is part of hyp2mat.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include "hypfile.h"
#include "parser.h"
using namespace std;
using namespace HypFile;
HypFile::Hyp::Hyp()
: trace_scanner(false), trace_parser(false), trace_hyp(false)
{
unit = 1;
metal_thickness_unit = 1;
use_die_for_metal = false;
min_circle_segments = 8; // 8 seems minimal, 16 seems more than sufficient.
arc_precision = 0;
pi = M_PI;
inches = 0.0254; /* inches to m */
copper_imperial_weight = 1.341; /* metal thickness in ounces/ft2. 1 oz/ft2 copper = 1.341 mil */
copper_metric_weight = 0.1116; /* metal thickness in grams/cm2. 1 gr/cm2 copper = 0.1116 cm */
copper_bulk_resistivity = 1.724e-8;
copper_temperature_coefficient = 0.00393;
fr4_epsilon_r = 4.3;
fr4_loss_tangent = 0.020;
conformal_epsilon_r = 3.3; /* dielectric constant of conformal layer */
board.plane_separation = -1.0; /* distance between PLANE polygon and copper of different nets; -1 if not set */
}
/*
* parse a Hyperlynx file
*/
bool HypFile::Hyp::load(const std::string &filename)
{
if (trace_hyp) cerr << "parsing " << filename << endl;
/* open input file */
if (filename != "-") {
yyin = fopen (filename.c_str(),"r");
if (!yyin) {
cerr << "Can't open input file " << filename << endl;
return false;
}
}
/* parse input file */
yy_flex_debug = trace_scanner;
yydebug = trace_parser;
int retval = yyparse(this);
/* close input file */
fclose(yyin);
bool success = retval == 0;
return success;
}
/*
* Error output
*/
void HypFile::Hyp::error(const std::string& msg)
{
cerr << msg << endl;
}
/*
* Dumps internal structures for debugging.
*/
bool HypFile::Hyp::save(const std::string& filename)
{
/*
* Open file for output
*/
if ((filename != "-") && (freopen(filename.c_str(), "w", stdout) == NULL)) {
std::ostringstream err_msg;
err_msg << "could not open '" << filename << "' for writing";
error(err_msg.str());
return true;
}
/*
* Variables
*/
cout << "unit = " << unit << endl;
cout << "metal_thickness_unit = " << metal_thickness_unit << endl;
cout << "use_die_for_metal = " << use_die_for_metal << endl;
cout << "min_circle_segments = " << min_circle_segments << endl;
cout << "arc_precision = " << arc_precision << endl;
cout << "pi = " << pi << endl;
cout << "inches = " << inches << endl;
cout << "copper_imperial_weight = " << copper_imperial_weight << endl;
cout << "copper_metric_weight = " << copper_metric_weight << endl;
cout << "copper_bulk_resistivity = " << copper_bulk_resistivity << endl;
cout << "copper_temperature_coefficient = " << copper_temperature_coefficient << endl;
cout << "fr4_epsilon_r = " << fr4_epsilon_r << endl;
cout << "fr4_loss_tangent = " << fr4_loss_tangent << endl;
cout << "conformal_epsilon_r = " << conformal_epsilon_r << endl;
/*
* Export board
*/
cout << "board" << endl;
for (PolygonList::iterator i = board.edge.begin(); i != board.edge.end(); ++i) {
cout << " polygon" << endl;
cout << " positive " << i->positive << endl;
for (PointList::iterator j = i->vertex.begin(); j != i->vertex.end(); ++j) {
cout << " x = " << j->x << endl;
cout << " y = " << j->y << endl;
}
}
cout << " plane_separation = " << board.plane_separation << endl;
cout << " board_attribute" << endl;
for (AttributeList::iterator j = board.attribute.begin(); j != board.attribute.end(); ++j) {
cout << " name = '" << j->name << "'" << endl;
cout << " value = '" << j->value << "'" << endl;
}
/*
* Export devices
*/
cout << "device" << endl;
for (DeviceList::iterator dev_it = device.begin(); dev_it != device.end(); ++dev_it) {
cout << " device" << endl;
cout << " device_type = '" << dev_it->device_type << "'" << endl;
cout << " ref = '" << dev_it->ref << "'" << endl;
cout << " name = '" << dev_it->name << "'" << endl;
cout << " value_float = " << dev_it->value_float << endl;
cout << " value_float_set = " << dev_it->value_float_set << endl;
cout << " value_string = '" << dev_it->value_string << "'" << endl;
cout << " value_string_set = " << dev_it->value_string_set << endl;
cout << " layer_name = '" << dev_it->layer_name << "'" << endl;
cout << " package = '" << dev_it->package << "'" << endl;
}
/*
* Export supplies
*/
cout << "supplies" << endl;
for (SupplyList::iterator supp_it = supply.begin(); supp_it != supply.end(); ++supp_it) {
cout << " supply" << endl;
cout << " name = '" << supp_it->name << "'" << endl;
cout << " value_float = " << supp_it->value_float << endl;
cout << " voltage_specified = " << supp_it->voltage_specified << endl;
cout << " conversion = " << supp_it->conversion << endl;
}
/*
* Export stackup
*/
cout << "layers" << endl;
for (LayerList::iterator it = stackup.begin(); it != stackup.end(); ++it) {
cout << " layer" << endl;
cout << " layer_name = '" << it->layer_name << "'" << endl;
cout << " layer_type = " << it->layer_type << " ";
switch (it->layer_type) {
case LAYER_SIGNAL: cout << "LAYER_SIGNAL"; break;
case LAYER_DIELECTRIC: cout << "LAYER_DIELECTRIC"; break;
case LAYER_PLANE: cout << "LAYER_PLANE"; break;
default: cout << "Error"; break;
}
cout << endl;
cout << " bulk_resistivity = " << it->bulk_resistivity << endl;
cout << " conformal = " << it->conformal << endl;
cout << " epsilon_r = " << it->epsilon_r << endl;
cout << " layer_name = " << it->layer_name << endl;
cout << " loss_tangent = " << it->loss_tangent << endl;
cout << " material_name = " << it->material_name << endl;
cout << " plane_separation = " << it->plane_separation << endl;
cout << " plating_thickness = " << it->plating_thickness << endl;
cout << " prepreg = " << it->prepreg << endl;
cout << " temperature_coefficient = " << it->temperature_coefficient << endl;
cout << " thickness = " << it->thickness << endl;
cout << " z0 = " << it->z0 << endl;
cout << " z1 = " << it->z1 << endl;
}
/*
* Padstack
*/
cout << "padstacks" << endl;
for (PadstackList::iterator it = padstack.begin(); it != padstack.end(); ++it) {
cout << " padstack" << endl;
cout << " padstack_name = '" << it->padstack_name << "'" << endl;
cout << " drill_size = " << it->drill_size << endl;
cout << " pads" << endl;
for (PadList::iterator p = it->pads.begin(); p != it->pads.end(); ++p) {
cout << " pad" << endl;
cout << " layer_name = '" << p->layer_name << "'" << endl;
cout << " pad_type = " << p->pad_type << " ";
switch (p->pad_type) {
case PAD_TYPE_METAL: cout << "PAD_TYPE_METAL"; break;
case PAD_TYPE_ANTIPAD: cout << "PAD_TYPE_ANTIPAD"; break;
case PAD_TYPE_THERMAL_RELIEF: cout << "PAD_TYPE_THERMAL_RELIEF"; break;
default: cout << "Error"; break;
}
cout << endl;
cout << " pad_shape = " << p->pad_shape << " ";
switch (p->pad_shape) {
case PAD_SHAPE_OVAL: cout << "PAD_SHAPE_OVAL"; break;
case PAD_SHAPE_RECTANGULAR: cout << "PAD_SHAPE_RECTANGULAR"; break;
case PAD_SHAPE_OBLONG: cout << "PAD_SHAPE_OBLONG"; break;
default: cout << "Error"; break;
}
cout << endl;
cout << " pad_sx = " << p->pad_sx << endl;
cout << " pad_sy = " << p->pad_sy << endl;
cout << " pad_angle = " << p->pad_angle << endl;
cout << " thermal_clear_shape = " << p->thermal_clear_shape << " ";
switch (p->thermal_clear_shape) {
case PAD_SHAPE_OVAL: cout << "PAD_SHAPE_OVAL"; break;
case PAD_SHAPE_RECTANGULAR: cout << "PAD_SHAPE_RECTANGULAR"; break;
case PAD_SHAPE_OBLONG: cout << "PAD_SHAPE_OBLONG"; break;
default: cout << "Error"; break;
}
cout << endl;
cout << " thermal_clear_sx = " << p->thermal_clear_sx << endl;
cout << " thermal_clear_sy = " << p->thermal_clear_sy << endl;
cout << " thermal_clear_angle = " << p->thermal_clear_angle << endl;
}
}
/*
* Net
*/
cout << "net" << endl;
for (NetList::iterator i = net.begin(); i != net.end(); ++i) {
cout << " net" << endl;
cout << " net_name = '" << i->net_name << "'" << endl;
/*
* Net Polygons
*/
for (PolygonMap::iterator j = i->metal.begin(); j != i->metal.end(); ++j) {
cout << " polygon id " << j->first << endl;
for (PolygonList::iterator k = j->second.begin(); k != j->second.end(); ++k) {
cout << " polygon" << endl;
cout << " positive " << k->positive << endl;
cout << " width " << k->width << endl;
cout << " layer_name " << k->layer_name << endl;
for (PointList::iterator l = k->vertex.begin(); l != k->vertex.end(); ++l) {
cout << " x = " << l->x << endl;
cout << " y = " << l->y << endl;
}
}
}
/*
* Net Vias
*/
cout << " vias" << endl;
for (ViaList::iterator j = i->via.begin(); j != i->via.end(); ++j) {
cout << " via" << endl;
cout << " x = " << j->x << endl;
cout << " y = " << j->y << endl;
cout << " layer0_name = " << j->layer0_name << endl;
cout << " layer1_name = " << j->layer1_name << endl;
cout << " radius = " << j->radius << endl;
}
/*
* Net Pins
*/
cout << " pins" << endl;
for (PinList::iterator j = i->pin.begin(); j != i->pin.end(); ++j) {
cout << " pin" << endl;
cout << " x = " << j->x << endl;
cout << " y = " << j->y << endl;
cout << " pin_reference = " << j->pin_reference << endl;
cout << " padstack_name = " << j->padstack_name << endl;
cout << " pin_function = " << j->pin_function << " ";
switch (j->pin_function) {
case PIN_SIM_IN: cout << "PIN_SIM_IN"; break;
case PIN_SIM_OUT: cout << "PIN_SIM_OUT"; break;
case PIN_SIM_BOTH: cout << "PIN_SIM_BOTH"; break;
default: cout << "Error"; break;
}
cout << endl;
}
/*
* Net Unrouted segments
*/
cout << " unrouted_segments" << endl;
for (UnroutedSegmentList::iterator j = i->unrouted_segment.begin(); j != i->unrouted_segment.end(); ++j) {
cout << " unrouted_segment" << endl;
cout << " x1 = " << j->x1 << endl;
cout << " y1 = " << j->y1 << endl;
cout << " layer1_name = " << j->layer1_name << endl;
cout << " x2 = " << j->x2 << endl;
cout << " y2 = " << j->y2 << endl;
cout << " layer2_name = " << j->layer2_name << endl;
cout << " zlayer_name_set = " << j->zlayer_name_set << endl;
cout << " zlayer_name = " << j->zlayer_name << endl;
cout << " width = " << j->width << endl;
cout << " impedance_set = " << j->impedance_set << endl;
cout << " impedance = " << j->impedance << endl;
cout << " delay = " << j->delay << endl;
cout << " resistance = " << j->resistance << endl;
}
/*
* Net Attributes
*/
if (!i->attribute.empty()) cout << " attribute" << endl;
for (AttributeList::iterator j = i->attribute.begin(); j != i->attribute.end(); ++j) {
cout << " name = '" << j->name << "'" << endl;
cout << " value = '" << j->value << "'" << endl;
}
}
/*
* Net Class
*/
cout << "net_class" << endl;
for (NetClassList::iterator i = net_class.begin(); i != net_class.end(); ++i) {
cout << " net_class" << endl;
cout << " net_class_name = '" << i->net_class_name << "'" << endl;
cout << " net_class_element" << endl;
for (StringList::iterator j = i->net_class_element.begin(); j != i->net_class_element.end(); ++j) {
cout << " net_name = '" << *j << "'" << endl;
}
if (!i->attribute.empty()) cout << " attribute" << endl;
for (AttributeList::iterator j = i->attribute.begin(); j != i->attribute.end(); ++j) {
cout << " name = '" << j->name << "'" << endl;
cout << " value = '" << j->value << "'" << endl;
}
}
cout << "end" << endl;
fclose(stdout);
return true;
}
/* not truncated */