Date post: | 14-Jun-2015 |
Category: |
Software |
Upload: | jeff-trull |
View: | 702 times |
Download: | 0 times |
Analyzing On-Chip Interconnectwith Modern C++
Jeff Trull
October 12, 2014
c©2014 Jeffrey E. Trull
Creative Commons 3.0 Attribution License
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Modern C++Influences
Functional Programming
Generic Programming
Design Patterns
The Standard Library
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Modern C++Is
Concepts
Iterators and Ranges
Separation of Data and Algorithm
Functions as First Class Objects
More Declarative than Imperative
Composition over Inheritance
and reusable components that leverage those techniques . . .
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Modern C++Probably Is Not
“C with Classes”
void *
macros
Idiosyncratic reimplementations of standard library features
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Connecting Logic TogetherYou Need Wires
Communication takes time and power proportional to thelength of the wire.
In addition, nearby wires may influence the delay of the wire, oreven produce an erroneous value.
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Connecting Logic TogetherYou Need Wires
Communication takes time and power proportional to thelength of the wire.
In addition, nearby wires may influence the delay of the wire, oreven produce an erroneous value.
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Circuit AnalysisFor Coders
You can think of a circuit as a kind of graph.
Edges are called branches and consist of a singlecomponent with a current that depends on itstype, value, and the voltages of the nodes itconnects
Vertices usually called nodes, are simply connection pointswhere currents flow between components
R
IR
Node 1 Node 2
CIC
Here IR = (VNode1 − VNode2)/R, IC = C ∗ d VNode1−VNode2dt .
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Graph Storage
The Boost.Graph library gives us several options for storinggraphs:
adjacency list The most popular; each vertex indexes alist of its adjacent vertices
compressed sparse row Immutable but very compact
adjacency matrix Represents graphs as matrices. Goodfor dense (many edges per vertex) graphs.
“Implicit” - anything that behaves like a graph
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Graph Storageadjacency matrix
one row, column per vertex︷ ︸︸ ︷
0 0 1 0 0 00 0 0 0 1 11 0 0 0 0 00 0 0 0 0 00 1 0 0 0 00 1 0 0 0 0
If the entry at M[i , j ] is set,there is an edge from vertexi → j . This gives constant timeedge insertion and deletion atthe cost of O(n2) memoryusage.
Foreshadowing
There are subtle connections between graphs and matrices.
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Graph StorageImplicit graphs
This can be anything that behaves like a graph, or moreformally, models a Graph Concept, a set of expressionsthat must be valid when the class is used.
Different graph algorithms place different requirements onthe graphs they operate on. Typically when you create animplicit graph you do the minimum required for thealgorithm you wish to use.
Some things you might want to make an implicit Graphfrom:
A social network’s graph APIA graph databaseSome other graph library’s dataA graph that is procedurally generated
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Graph StorageFor Circuits
I will use quantities from the Boost Units library for storingcomponent values:
Units Example
using namespace boost:: units::si;
quantity <resistance > kohm (1.0 * kilo * ohms);
quantity <capacitance > ff(1.0 * femto * farads);
quantity <time > t = (2 * kohm) * (6 * ff);
std::cout << ‘‘time constant = ‘‘ << t << std::endl;
time constant = 1.2e-11 s
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Graph StorageVertex and Edge Properties
We can assign arbitrary properties to vertices and edges, andaccess them through the Property Map mechanism.
I’ll store strings (node names) with the vertices.
Edges, by contrast, can be one of two component types,which suggests:
Boost.Variant
typedef quantity <resistance , double > resistor_value_t;
typedef quantity <capacitance , double > capacitor_value_t;
typedef boost::variant <resistor_value_t ,
capacitor_value_t > edge_property_t;
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Graph StorageBoost.Variant
A variant can store one of an arbitrary set of types in a safe,compile-time-checked manner:edge_property_t value = resistor_value_t (20.0* ohms);
// stores a resistor
value = capacitor_value_t (17.0* ff);
// now a capacitor
resistor_value_t rvalue = get <resistor_value_t >( value);
// throws - wrong type
The recommended approach to accessing values is the visitor :struct cap_summer : boost:: static_visitor <
capacitor_value_t >
capacitor_value_t operator ()(resistor_value_t const&)
const
return capacitor_value_t (); // zero fF
capacitor_value_t operator ()(capacitor_value_t c)
const
return c;
;
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Graph StorageDefining and Using the Graph
using namespace boost;
typedef adjacency_list <vecS , vecS , undirectedS ,
vertex_property_t , edge_property_t
> ckt_graph_t;
ckt_graph_t circuit;
auto gnd = add_vertex(‘‘gnd’’, circuit);
auto in = add_vertex(‘‘in’’, circuit);
auto out = add_vertex(‘‘out’’, circuit);
add_edge(in, out , 0.1*kohm , circuit);
add_edge(out , gnd , 20.0*ff , circuit);
We can view the results by using the build-in Graphviz writer:
write_graphviz(dbg , circuit ,
make_label_writer(get(vertex_bundle ,
circuit)),
make_label_writer(get(edge_bundle , circuit
)));
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Acquiring DataSPEF
The Standard Parasitic Exchange Format is a commonchoice for storing or transferring parasitic data between tools.It’s relatively compact and fairly easy to parse (by design).We’ll focus on two parts of the standard:
The Name Map
Allows us to abbreviate some potentially very long names:
*NAME MAP
*1 SOME/LONG/INSTANCE/PATH/n12888
*2 SOME/LONG/INSTANCE/PATH/n12889...
Later expressions in the same file may use *1, *2 in place ofthe full names
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Acquiring DataSPEF
Parasitics for each net are split into resistors and capacitors andlisted in a simple format:
Component List
*RES
1 *2172:Z *2173:1 0.230
2 *2173:1 *2173:2 18.1...
*END
We will demonstrate some simple parsing techniques for thesetwo sections, using Boost.Spirit.
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Acquiring DataParsing with Spirit
The Spirit parser library overloads operators to turn expressionsinto parsers. If your needs are simple you can use thoseexpressions directly:
std:: string in("10 20 30 -11");
vector <int > result;
auto beg = in.begin ();
auto end = in.end();
qi:: phrase_parse(beg , end , // input range
*int_ , // grammar
ascii::space , // skipper
result); // synthesized attribute
copy(result.begin(), result.end(),
ostream_iterator <int >(cout , " "));
cout << endl;
outputs:
10 20 30 -11
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Acquiring DataSpirit : Symbol Table
Spirit has a special component called symbols that can beloaded with data and then used as a parser. It is a sort of map,returning the data supplied as a value when the key isencountered in the input.
symbols <char , std::string > name_map_symtab;
typedef rule <spirit :: istream_iterator , std:: string ()>
name_rule;
name_rule nm_num = ’*’ >> +digit;
name_rule nm_name = +char_("a-zA-Z0 -9/_");
namespace phx = boost :: phoenix;
phrase_parse(beg , end ,
lit("*NAME_MAP") >> // grammar
*( nm_num >> nm_name) [
phx::bind(name_map_symtab.add , _1, _2)
// semantic action
],
space);
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Acquiring DataSpirit : Using the Symbol Table
Having loaded the name map, we can use it as a parser itself:
name_rule node_with_symtab = ’*’ >> name_map_symtab >>
char_(’:’) >> +alnum;
phrase_parse(rbeg , rend ,
lit("*RES") >>
*(omit[uint_] >> node_with_symtab >>
node_with_symtab >> double_)[
phx::bind(& ckt_builder :: add_component ,
phx::ref(builder),
_1, _2 , _3 * phx::cref(r_unit)
)]
>> lit("*END"),
space);
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Acquiring DataEstimating Parasitics
Sometimes it is valuable to create an approximate circuit for asignal that does not yet have parasitic information. Startingwith the locations of the endpoints, a tree can be constructedusing various heuristics. One of the simplest to implement is:
The Rectilinear Minimum Spanning Tree
Uses a Manhattan distance metric to select a set ofconnected edges with minimum cost
Requires an initial graph containing all the candidate edges
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Acquiring DataRMST: Strategy
We will:
Create an implicit graph exposing all possible pairs ofedges
Create an implicit “property map” with the Manhattanmetric for edges
Apply the Boost.Graph supplied Prim MST algorithm
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Acquiring DataRMST: Implicit Graph
We need a class to wrap a list of points and model the Graphconcept. In practice, this means a collection of typedefs andfree functions, plus our own (small) logic, e.g.:
struct pin_distance_graph
typedef std::pair <int , int > point_t;
template <typename PtIter >
pin_distance_graph(PtIter beg , PtIter end) : points_(
beg , end)
// (Some of the) Requirements
typedef size_t vertex_descriptor;
typedef std::pair <size_t , size_t > edge_descriptor;
typedef boost:: undirected_tag directed_category;
friend vertices_size_type num_vertices(
pin_distance_graph const& g)
return g.points_.size();
private:
std::vector <point_t > points_;
;
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Acquiring DataRMST: Implicit Edge Weight Map
We don’t need to store a map containing distances for allpossible vertex pairs, because we can calculate them ondemand instead:
typedef pin_distance_graph :: edge_descriptor edge_t;
auto weightpmap = make_function_property_map <edge_t >(
[&pdg]( edge_t e) -> int
auto coord1 = pdg[source(e, pdg)];
auto coord2 = pdg[target(e, pdg)];
return abs(coord1.first - coord2.first) + abs(
coord1.second - coord2.second);
);
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Acquiring DataRMST: Call Prim, make output
// Predecessor map
vector <pin_distance_graph :: vertex_descriptor > predvec(
num_vertices(pdg)); // underlying storage
auto predpmap = make_iterator_property_map(predvec.begin
(), vindex_map);
// Calculate MST
prim_minimum_spanning_tree(pdg , predpmap ,
weight_map(weightpmap).
vertex_index_map(vindex_map));
// Output
auto vitpair = vertices(pdg);
for (auto v : make_iterator_range(vitpair.first , vitpair.
second))
if (predvec[v] == v)
// root node
else
// MST edge between v and its predecessor
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
RMSTExample
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
RMSTComplete Graph
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
RMSTResult
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
RMSTFurther Optimizations
How to perform this kind of estimate well is a popular researchtopic. RMST is easy to calculate but produces trees up to 50%more costly than optimal. Other approaches include:
The Steiner tree, where additional, optional vertices areadded to the graph. This is an NP-hard problem but thereare many published algorithms.
Starting with a Delaunay triangulation instead of acomplete graph, to improve runtime (see Boost.Polygon)
Using a maze router to improve estimates in the presenceof blockages
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Sanitizing Input
Generated parasitics from complex designs can have a numberof issues that produce problems for tools, including:
Resistor loops
Floating (undriven) nodes
Components of very small value
It’s useful to be able to recognize and/or repair these cases, asproblems often manifest themselves as bad math results, withpoor diagnostics.
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Sanitizing DataFloating Node Detection
If a circuit node has no path strictly through resistors to eithera driving cell, or to the ground node, there is nothing reallycontrolling its voltage, so we say it is “floating”. Electricallythis is a bad thing, but it can happen at intermediate stages ina design when the chip wiring is incomplete.
Strategy
We will
Use a filtered Graph to produce a view of the circuit withonly resistor edges
Apply the connected components algorithm to groupcircuit nodes with their driving cell
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Sanitizing DataFloating Node Test Circuit
+−V1
d1 n2 n3
+−V2
d2 n6
n5
n4
n1
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Sanitizing DataFloating Node Test Circuit
+−V1
d1 n2 n3
+−V2
d2 n6
n5
n4
n1
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Sanitizing DataFiltered Graph
// filter predicate for resistor -only graphs
struct is_resistor : boost:: static_visitor <bool >
bool operator ()(resistor_value_t const &) const
return true;
bool operator ()(capacitor_value_t const &) const
return false;
;
struct resistors_only
resistors_only ()
resistors_only(ckt_graph_t const* g) : graph_(g)
bool operator ()(ckt_graph_t :: edge_descriptor e) const
// access edge property (res/cap variant) and
apply predicate visitor
return boost :: apply_visitor(is_resistor (), (*
graph_)[e]);
private:
ckt_graph_t const* graph_; // cannot be ref due to
default ctor requirement
;
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Sanitizing DataConnected Components with Filtered Graph
typedef filtered_graph <ckt_graph_t , resistors_only >
resonly_graph_t;
resonly_graph_t res_graph(float_n , resistors_only (&
float_n));
typedef map <resonly_graph_t :: vertex_descriptor ,
comp_number_t > CCompsStorageMap;
CCompsStorageMap comps; // component map for
algorithm results
boost:: associative_property_map <CCompsStorageMap > cpmap(
comps);
connected_components(res_graph , cpmap , boost :: color_map(
clrpmap));
// can get connected component for each vertex in the
graph now
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayGeneral Idea
Elmore delay is a metric that gives a guaranteed upperbound on the delay of a signal given its parasitic network
It is easy to understand and calculate
It also has fidelity, that is, improving the Elmore delaygenerally improves the true delay also, and to a similardegree.
It can be calculated in two passes through the circuit graph.
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayTest Scenario
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayTest Scenario
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayTest Circuit
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
+−Vvic
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
n1 n2 n3
n5 n6 n7
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayTest Circuit
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
+−Vvic
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
n1 n2 n3
n5 n6 n7
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayTest Circuit
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
+−Vvic
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
n1 n2 n3
n5 n6 n7
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayTest Circuit
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
+−Vvic
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
n1 n2 n3
n5 n6 n7
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayTest Circuit via GraphViz
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayHow it Works
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayHow it Works
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayHow it Works
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayHow it Works
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayHow it Works
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayHow it Works
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayHow it Works
+−Vagg
100Ω 1kΩ 1kΩ
70fF50fF 50fF 50fF
100fF
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayVisitors
For this task we will make use of the Depth-First Searchalgorithms provided by Graph, and the associated Visitormechanism. With these “hooks” we can take actions at theright moment without worrying about writing traversal code.
template <typename Graph >
struct cap_summing_visitor : boost:: default_dfs_visitor
void tree_edge(edge_t e, Graph const& g)
// remember which edges are part of the ‘‘tree ’’
void finish_vertex(vertex_t u, Graph const& g)
// sum capacitance from downstream
;
vector <capacitor_value_t > downstream_caps(
num_vertices(coupling_test));
cap_summing_visitor <ckt_graph_t > capvis(
downstream_caps);
undirected_dfs(coupling_test , edge_color_map(cpmap).
visitor(capvis).root_vertex(vagg));
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayVisitors
The second pass has a similar structure:
// adds up delays. To be run on filtered (R-only) graph
template <typename Graph >
struct delay_calc_visitor : boost :: default_dfs_visitor
void start_vertex(vertex_t u, Graph const &)
// set start vertex delay to 0
void tree_edge(edge_t e, Graph const& g)
// If resistor , calculate the delay to the target
;
vector <delay_t > delays(num_vertices(coupling_test));
delay_calc_visitor <resonly_graph_t >
delvis(downstream_caps , delays);
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Elmore DelayFilter Predicate and Invocation
typedef filtered_graph <ckt_graph_t , resistors_only >
resonly_graph_t;
resonly_graph_t res_graph(coupling_test , resistors_only (&
coupling_test));
depth_first_visit(res_graph , vagg , delvis , cvpmap);
cout << "Elmore delay of aggressor net: " << delays.at(n3
) << endl;
which produces the output:
Elmore delay of aggressor net: 3.72e-10 s
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Matrix RepresentationModified Nodal Analysis
You can also think of a circuit as a set of matrices. Inparticular, you can write out its behavior as a set of differentialequations, and store the coefficients as a description of thecircuit:
C ∗ dXdt = −G ∗ X + B ∗ uY = L ∗ X
where
X is the state vector (node voltages and inputcurrents)
C contains capacitorsG contains every other circuit componentu is the input vectorY is the output vectorB connects the inputs to the systemL connects the outputs
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Matrix RepresentationEigen
Eigen is a mature expression template based matrix librarywith a lot of powerful features such as
Sparse Matrix handling - compact storage for matrices withmany zero elements
Algorithms such as common factorizations, eigenvaluecalculation, etc.
Acceleration lazy evaluation, SIMD parallelization
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Matrix RepresentationComponent Stamps
Values for each of the components are stored in the matrices ina conventional way (a stamp) based on their values andconnecting nodes. For example, a resistor:
template <int sz >
void stamp_r(Eigen::Matrix <double , sz , sz >& G,
Eigen::Matrix <double , sz, sz> const&,
int node1 , int node2 , double r)
G(node1 , node1) += 1.0/r; // first node current
G(node1 , node2) -= 1.0/r;
G(node2 , node2) += 1.0/r; // second node current
G(node2 , node1) -= 1.0/r;
and usage:
stamp_r(G, C, 0, 1, r);
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Matrix RepresentationMoments
The moments of a system are characteristic values that can beused to abstract its behavior mathematically. For our purposeswe need only remember the formula:
mi = L ∗ (G−1 ∗ C )i ∗ G−1 ∗ B
After representing our test circuit in Eigen via MNA, we cancalculate the moments like this:
auto G_QR = G.fullPivHouseholderQr (); // decompose for
solving
Matrix <Float , scount , scount > A = -G_QR.solve(C);
Matrix <Float , scount , icount > R = G_QR.solve(B);
block_moments.push_back(L.transpose () * R + E);
Matrix <Float , scount , scount > AtotheI = A;
for (size_t i = 1; i < count; ++i)
block_moments.push_back(L.transpose () * AtotheI * R);
AtotheI = A * AtotheI;
cerr << "moment 0=\n" << block_moments [0] << endl;
cerr << "moment 1=\n" << block_moments [1] << endl;
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Matrix RepresentationMoments
Producing the output:
moment 0=
1 0
0 1
moment 1=
-3.72e-10 1.1e-10
1.1e-10 -3.72e-10
which is an encouraging sign that we can produce delayestimates from the matrix representation as well.Actually, we can do even better. If we can rearrange our matrixequations to this form:
dXdt = −C−1 ∗ G ∗ X + C−1 ∗ u
We can simulate the circuit.
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
The Boost.ODEInt library
This library, accepted into Boost in September 2012, provides asimple interface for numeric integration. Users need onlyprovide
A state definition (container, number of states, type ofdata)
A callable object that calculates the change in the statevector dX (t)
dt = f (X (t), t)
Initial conditions
A callable object to serve as a sink for the values at eachtime point as they are calculated
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
The Boost.ODEInt librarySimulating our circuit
After a mathematical cleanup process known as regularization,we precompute some matrices so we can quickly calculate thetimestep results needed by ODEInt:
typedef std::vector <double > state_t;
void operator ()(state_t const& x, state_t& dxdt , double)
const
using namespace Eigen;
// need to wrap std :: vector state types for Eigen
Map <const Matrix <double , Dynamic , 1>> xvec(x.data(),
x.size());
Map <Matrix <double , Dynamic , 1>> result(dxdt.
data(), x.size());
// simulating step function at time 0 for simplicity
Matrix <double , 2, 1> u; u << 1.0, 0.0; // aggressor
voltage 1V, victim quiescent
result = drift_ * xvec + input_ * u; // apply
stored matrices
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
The Boost.ODEInt librarySimulation results
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
ConclusionBig Win
By applying Modern C++ techniques and libraries, we canaccomplish a great deal in a few lines of code:
Task LOC
Circuit as Graph 103Circuit as Matrix 198Floating Node Check 110Resistor Loop Check 96RMST Estimator 225Elmore via Graph 216Elmore and simulation via Matrix 157
You can find this code athttp://github.com/jefftrull/OnChipInterconnect
We get to let domain experts work on improving libraries, whilewe focus on our own stuff, leveraging improvements in thestate of the art as they appear.
On-ChipModern C++
Jeff Trull
Modern C++
Interconnect
Graphs
AcquiringData
Parsing
Estimating
Sanitizing
Analysis
Matrices
Simulation
Summary
Further ReadingShout outs
There are many more open source tools and libraries that canbe applied to the world of electronic CAD:
Circuit simulators: ngspice, qucs, xyce
Octave (open source Matlab replacement) - helpful fordebugging/prototyping
computational geometry libraries: CGAL, Boost.Geometry,Boost.Polygon
ILP solvers, SAT solvers
The Boost.Polygon documentation includes a full LVS flow...There is a lot out there.