Skip to content

Commit

Permalink
README.md Adds Simulation Input Syntax
Browse files Browse the repository at this point in the history
The flowchart image in README.md was updated to show the Xyce file
output. README.md was updated with a new section giving the simulation
input file syntax, comment rules, and acceptible values for
placeholders. Updates were made to "solnoutclass.h" so that
SolverDataBase::readSimInput() could actually handle block-interrupting
comments, in-line comments on all important lines, and linear frequency
interpolation of the sweep.
  • Loading branch information
michaelhayashi committed May 29, 2019
1 parent b5080b9 commit cf887a0
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 17 deletions.
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,60 @@ Many thanks are owed to the project sponsors for making the development of this
## Installation and Usage
Follow the instructions given in **INSTALL.md** to install this software and run it from the command line. Users from Purdue University should read **purdue\_install.md** instead for specific steps unique to their environment.

## Simulation Input File (.sim_input) Syntax
Every GDSII file needs to have a simulation input file with the .sim\_input extension created for it. The custom syntax of the simulation input file is given at the bottom of this section. It is important that the information in the blocks underneath the headers in all capital letters appear in the order given. Comments start with `#` and continue for the rest of the line. Comments may appear almost anywhere in the file so long as in-line comments are preceded by a space. The following are placeholders, angle brackets and words in between, which must populated depending on the design:
* \<six design extents>: The six coordinates for the smallest rectangular prism enclosing the design with implied units in the order of xmin (the smallest x-coordinate in the design), xmax, ymin, ymax, zmin, and zmax (the largest z-coordinate in the design).
* A lowercase 'e' may be used for scientific notation.
* For example, `30.00 +149. -47.0 +120. 0.00 +7.53`.
* \<lengthUnit>: The unit by which all given and reported lengths (e.g., total size of design, layer coordinates and heights, and port coordinates) must be multiplied in order to convert to meters. A lowercase 'e' may be used for scientific notation. For example, `1e-6`.
* \<freqUnit>: The unit by which all given and reported temporal frequencies must be multiplied in order to convert to hertz. A lowercase 'e' may be used for scientific notation. For example, `1.0e+6`.
* \<freqStart>: The smallest frequency in the frequency sweep with implied units. For example, `1000.0`.
* \<freqEnd>: The largest frequency in the frequency sweep with implied units. For example, `3000.0`.
* \<nfreq>: The total number of frequencies to include in the sweep. A value of `1` means that \<freqEnd> must equal \<freqStart>. A value of `2` means that only \<freqStart> and \<freqEnd> are included. Any larger integer requires interpolation.
* \<freqScale>: Integer representing frequency interpolation. The recommended value is `0` for logarithmic spacing. The value `1` is for linear spacing.
* \<numLayer>: The total number of layers in this design. The integer here must match the number of active \<layer entry> lines following this line in the file.
* \<layer entry>: An entire line representing a single layer.
* The four pieces of information that must be included in order are the layer name at the start of the line, the z-coordinate of the bottom of the layer (designated with `z = ` before a length with implied units), the height of the layer (designated with `h = ` before a length with implied units), and the relative permittivity of the dielectric making up that insulating parts of that layer (designated with `e = ` before a unitless floating-point number greater than or equal to unity).
* A lowercase 'e' may be used for scientific notation.
* In order to maintain correspondence with the layer numbers used in a GDSII file, the layer names must be a plain integer or be an alphanumeric string with a capital 'M' before the layer number.
* It is strongly recommended to add one layer below the bottommost GDSII layer and a second layer above the topmost GDSII layer to serve as planes of perfect electrical conductor (PEC) representing how the design would behave in a testing environment.
* For example, `ILDM2 z = 1.316 h = 0.12 e = 8.0`.
* \<numPorts>: The total number of ports in this design. The integer here must match the number of active \<port entry> lines following this line in the file.
* \<port entry>: An entire line representing a single port.
* The seven pieces of information that must be included in order are the x-coordinate of the supply point of the port, the y-coordinate of the supply point of the port, the z-coordinate of the supply point of the port, the x-coordinate of the return point of the port, the y-coordinate of the return point of the port, the z-coordinate of the return point of the port, and the directionality of the port.
* A lowercase 'e' may be used for scientific notation.
* The directionality of the port is either `+1` for input ports, `-1` for output ports, or `0` for bidirectional ports or ports with uncertain power flow.
* A port should be added for each input/output pin of the device. Additional ports are needed for every transistor or other active device in the design. For printed circuit boards (PCBs), at least one port is needed for each component on the populated layout.
* For example, `+146. -16.0 4.53 +146. +6.00 4.53 -1`.

```
TOTAL SIZE
<six design extents>
lengthUnit = <lengthUnit>
FREQUENCY
freqUnit = <freqUnit>
freqStart = <freqStart>
freqEnd = <freqEnd>
\# Block-interrupting comment
nfreq = <nfreq>
freqScale = <freqScale>
DIELECTRIC STACK
numStack = <numLayer>
<layer entry> # In-line comment
<...>
<layer entry> # In-line comment
\# Post-block comment
PORT
numPorts = <numPorts>
<port entry> # In-line comment
<...>
<port entry> # In-line comment
\# Post-block comment
```

## Credits and Acknowledgements
* Example Files
* [Purdue On-Chip Electromagnetics Laboratory](https://engineering.purdue.edu/~djiao/) for **singleStrip.imp** (single stripline)
Expand Down
Binary file modified images/gds2Para_mode-s.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
105 changes: 88 additions & 17 deletions solnoutclass.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class SimSettings
double lengthUnit; // Units for lengths (m)
vector<double> limits; // xmin, xmax, ymin, ymax, zmin, zmax (m)
double freqUnit; // Units for frequency (Hz)
double freqScale; // Frequency scaling?
double freqScale; // Frequency scaling (0. for logarithmic [preferred], 1. for linear, otherwise undefined)
size_t nFreq; // Number of frequencies in simulation
vector<double> freqs; // List of frequencies (linear or logarithmic [preferred] spacing)
public:
Expand Down Expand Up @@ -1560,8 +1560,12 @@ struct SolverDataBase
// Handle total size
if (fileLine.compare(0, 10, "TOTAL SIZE") == 0)
{
// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Obtain limits of IC design size
double xmin, xmax, ymin, ymax, zmin, zmax;
Expand All @@ -1581,10 +1585,15 @@ struct SolverDataBase
indCoordEnd = fileLine.find(" ", indCoordStart);
zmin = stod(fileLine.substr(indCoordStart, indCoordEnd - indCoordStart));
indCoordStart = indCoordEnd + 1;
zmax = stod(fileLine.substr(indCoordStart));
indCoordEnd = fileLine.find(" ", indCoordStart);
zmax = stod(fileLine.substr(indCoordStart, indCoordEnd - indCoordStart));

// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Obtain length unit
double lengthUnit = stod(fileLine.substr(fileLine.find("lengthUnit = ") + 13, fileLine.find(" #")));
Expand All @@ -1595,32 +1604,52 @@ struct SolverDataBase
// Handle frequency sweep parameters
else if (fileLine.compare(0, 9, "FREQUENCY") == 0)
{
// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Obtain frequency unit
double freqUnit = stod(fileLine.substr(fileLine.find("freqUnit = ") + 11, fileLine.find(" #")));

// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Obtain first frequency
double freqStart = stod(fileLine.substr(fileLine.find("freqStart = ") + 12, fileLine.find(" #")));

// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Obtain last frequency
double freqEnd = stod(fileLine.substr(fileLine.find("freqEnd = ") + 10, fileLine.find(" #")));

// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Obtain number of frequencies
size_t nFreq = stoi(fileLine.substr(fileLine.find("nfreq = ") + 8, fileLine.find(" #")));

// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Obtain frequency scaling
double freqScale = stod(fileLine.substr(fileLine.find("freqScale = ") + 12, fileLine.find(" #")));
Expand All @@ -1636,7 +1665,17 @@ struct SolverDataBase
freqList.push_back(freqStart);
freqList.push_back(freqEnd);
}
else
else if ((nFreq > 2) && (freqScale == 1.)) // Linear interpolation of frequency sweep
{
double linStep = (freqEnd - freqStart) / (nFreq - 1);
freqList.push_back(freqStart);
for (size_t indi = 1; indi < nFreq - 1; indi++)
{
freqList.push_back(freqList.back() + linStep);
}
freqList.push_back(freqEnd); // Ensure last frequency is exact
}
else // Logarithmic interpolation of frequency sweep
{
double exp10Step = log10(freqEnd / freqStart) / (nFreq - 1);
freqList.push_back(freqStart);
Expand All @@ -1655,14 +1694,30 @@ struct SolverDataBase
// Handle dielectric stack-up
else if (fileLine.compare(0, 16, "DIELECTRIC STACK") == 0)
{
// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Obtain number of dieletric layers in stack-up
size_t numStack = stoi(fileLine.substr(fileLine.find("numStack = ") + 11, fileLine.find(" #")));
size_t numStack = 0;
if (fileLine.find("numStack = ") < string::npos)
{
numStack = stoi(fileLine.substr(fileLine.find("numStack = ") + 11, fileLine.find(" #")));
}
else if (fileLine.find("numLayer = ") < string::npos)
{
numStack = stoi(fileLine.substr(fileLine.find("numLayer = ") + 11, fileLine.find(" #")));
}

// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Read each line in dielectric stack
for (size_t indStack = 0; indStack < numStack; indStack++)
Expand Down Expand Up @@ -1735,15 +1790,23 @@ struct SolverDataBase
// Register a new layer in layers field
(this->layers).emplace_back(Layer(layerName, layerNumGDSII, layerZStart, layerHeight, layerEpsilonR, layerLossTan, layerSigma));

// Keep moving down the dielectric stack
// Keep moving down the dielectric stack, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}
}
}
// Handle port list if not already populated by GDSII file
else if ((fileLine.compare(0, 4, "PORT") == 0) && ((this->para).getPorts().size() == 0))
{
// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Obtain number of ports in list
size_t numPort = 0;
Expand All @@ -1756,8 +1819,12 @@ struct SolverDataBase
numPort = stoi(fileLine.substr(fileLine.find("numPort = ") + 10, fileLine.find(" #")));
}

// Move down one line
// Move down one line, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}

// Read each line in the port list
vector<Port> ports;
Expand Down Expand Up @@ -1837,8 +1904,12 @@ struct SolverDataBase
}
ports.emplace_back(Port("port" + to_string(indPort + 1), portDir, 50., {xsup, ysup, zsup, xret, yret, zret}, portLayer));

// Move down one line
// Move down one line in port list, skipping comments
getline(inputFile, fileLine);
while (fileLine.compare(0, 1, "#") == 0)
{
getline(inputFile, fileLine);
}
}

// Propagate port list to parasitics data structure now
Expand Down

0 comments on commit cf887a0

Please sign in to comment.