-
Notifications
You must be signed in to change notification settings - Fork 119
/
dont-replicate-automate-2017-02-17.html
233 lines (192 loc) · 24.4 KB
/
dont-replicate-automate-2017-02-17.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
<!DOCTYPE html>
<html lang="en">
<head>
<title>SKiDL — Don't Replicate, Automate!</title>
<meta charset="utf-8" />
<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" type="text/css" href="/skidl/theme/css/style.css" />
<link rel='stylesheet' id='oswald-css' href='http://fonts.googleapis.com/css?family=Oswald&ver=3.3.2' type='text/css' media='all' />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Oswald&family=Roboto+Condensed&display=swap" rel="stylesheet">
<!-- <style type="text/css">
body.custom-background { background-color: #f5f5f5; }
</style> -->
<link rel="alternate" type="application/atom+xml"
title="SKiDL — Flux Atom"
href="/skidl/" />
<!--[if lte IE 8]><script src="/skidl/theme/js/html5shiv.js"></script><![endif]-->
</head>
<body class="home blog custom-background " >
<div id="container">
<div id="header">
<h1 id="site-title"><a href="/skidl"><img src="/skidl/images/banner.png" width="100%"></a></h1>
<!-- <h1 id="site-title"><a href="/skidl">SKiDL</a></h1> -->
</div><!-- /#banner -->
<div id="menu">
<div class="menu-navigation-container">
<ul id="menu-navigation" class="menu">
<li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="https://github.com/devbisme/skidl">Github</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="https://github.com/devbisme/skidl/discussions">Forum</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="/skidl/category/posts.html">Blog</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="/skidl/api/html/index.html">API</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="/skidl/">Home</a></li>
</ul>
</div> <!--/#menu-navigation-container-->
</div><!-- /#menu -->
<div class="page-title">
</div>
<div id="contents">
<div class="post type-post status-publish format-standard hentry category-general" id="post">
<div class="entry-meta">
<span class="date"><a href="/skidl/dont-replicate-automate-2017-02-17.html">Fri 17 February 2017</a></span>
/
<span class="byline"><a href="/skidl/author/dave-vandenbout.html">Dave Vandenbout</a></span>
</div> <!-- /#entry-meta -->
<div class="main">
<h2 class="entry-title">
<a href="/skidl/dont-replicate-automate-2017-02-17.html" title="Permalink to Don't Replicate, Automate!" rel="bookmark">Don't Replicate, Automate!</a>
</h2>
<div class="entry-content">
<p>I used to work during summers for a bricklayer.
I learned one thing there: air conditioning is pretty good stuff. (We should do more of it.)</p>
<p>Some people think bricklaying would be a great job, kind of like playing Tetris
all day, except with real blocks.
But here's what the <em>real</em> reality is:</p>
<div class="highlight"><pre><span></span><code><span class="nv">Pick</span><span class="w"> </span><span class="nv">up</span><span class="w"> </span><span class="nv">brick</span>,<span class="w"> </span><span class="nv">apply</span><span class="w"> </span><span class="nv">mortar</span>,<span class="w"> </span><span class="nv">place</span>,<span class="w"> </span><span class="nv">tap</span><span class="w"> </span><span class="nv">down</span>,<span class="w"> </span><span class="nv">remove</span><span class="w"> </span><span class="nv">excess</span><span class="w"> </span><span class="nv">mortar</span>.
<span class="nv">Pick</span><span class="w"> </span><span class="nv">up</span><span class="w"> </span><span class="nv">brick</span>,<span class="w"> </span><span class="nv">apply</span><span class="w"> </span><span class="nv">mortar</span>,<span class="w"> </span><span class="nv">place</span>,<span class="w"> </span><span class="nv">tap</span><span class="w"> </span><span class="nv">down</span>,<span class="w"> </span><span class="nv">remove</span><span class="w"> </span><span class="nv">excess</span><span class="w"> </span><span class="nv">mortar</span>.
<span class="nv">Pick</span><span class="w"> </span><span class="nv">up</span><span class="w"> </span><span class="nv">brick</span>,<span class="w"> </span><span class="nv">apply</span><span class="w"> </span><span class="nv">mortar</span>,<span class="w"> </span><span class="nv">place</span>,<span class="w"> </span><span class="nv">tap</span><span class="w"> </span><span class="nv">down</span>,<span class="w"> </span><span class="nv">remove</span><span class="w"> </span><span class="nv">excess</span><span class="w"> </span><span class="nv">mortar</span>.
<span class="nv">Row</span><span class="w"> </span><span class="nv">after</span><span class="w"> </span><span class="nv">row</span>.
<span class="nv">Wall</span><span class="w"> </span><span class="nv">after</span><span class="w"> </span><span class="nv">wall</span>.
<span class="nv">Job</span><span class="w"> </span><span class="nv">after</span><span class="w"> </span><span class="nv">job</span>.
<span class="k">Until</span><span class="w"> </span><span class="nv">you</span><span class="w"> </span><span class="nv">die</span>.<span class="w"> </span><span class="nv">Of</span><span class="w"> </span><span class="nv">the</span><span class="w"> </span><span class="nv">heat</span>.
</code></pre></div>
<p>One day, I graduated and went to work as an electrical engineer.
Big plus: air conditioning! (We should do more of it.)
Big minus: there's a lot of high-tech bricklaying.</p>
<p>Case in point: bypass capacitors.
Electronic components need these to smooth out the ripples
and transients on their power supply inputs.
A general rule-of-thumb is there should be one bypass cap for each
ground pin on a chip.
But there are chips nowadays that have hundreds of ground pins which means
placing hundreds of bypass caps.
Here's a section of a schematic showing just the bypass caps for a
relatively small chip with around a dozen ground pins:</p>
<p><img alt="Schematic with bypass capacitors." src="images/dont-replicate-automate/bypass-caps.png"></p>
<p>And here's the design process:</p>
<div class="highlight"><pre><span></span><code><span class="nv">Click</span><span class="w"> </span><span class="nv">on</span><span class="w"> </span><span class="nv">capacitor</span><span class="w"> </span><span class="nv">symbol</span>.<span class="w"> </span><span class="nv">Drag</span><span class="w"> </span><span class="o">&</span><span class="w"> </span><span class="nv">drop</span>.<span class="w"> </span><span class="nv">Attach</span><span class="w"> </span><span class="nv">power</span>.<span class="w"> </span><span class="nv">Attach</span><span class="w"> </span><span class="nv">ground</span>.
<span class="nv">Click</span><span class="w"> </span><span class="nv">on</span><span class="w"> </span><span class="nv">capacitor</span><span class="w"> </span><span class="nv">symbol</span>.<span class="w"> </span><span class="nv">Drag</span><span class="w"> </span><span class="o">&</span><span class="w"> </span><span class="nv">drop</span>.<span class="w"> </span><span class="nv">Attach</span><span class="w"> </span><span class="nv">power</span>.<span class="w"> </span><span class="nv">Attach</span><span class="w"> </span><span class="nv">ground</span>.
<span class="nv">Click</span><span class="w"> </span><span class="nv">on</span><span class="w"> </span><span class="nv">capacitor</span><span class="w"> </span><span class="nv">symbol</span>.<span class="w"> </span><span class="nv">Drag</span><span class="w"> </span><span class="o">&</span><span class="w"> </span><span class="nv">drop</span>.<span class="w"> </span><span class="nv">Attach</span><span class="w"> </span><span class="nv">power</span>.<span class="w"> </span><span class="nv">Attach</span><span class="w"> </span><span class="nv">ground</span>.
<span class="nv">Part</span><span class="w"> </span><span class="nv">after</span><span class="w"> </span><span class="nv">part</span>.
<span class="nv">Page</span><span class="w"> </span><span class="nv">after</span><span class="w"> </span><span class="nv">page</span>.
<span class="nv">Design</span><span class="w"> </span><span class="nv">after</span><span class="w"> </span><span class="nv">design</span>.
<span class="k">Until</span><span class="w"> </span><span class="nv">you</span><span class="w"> </span><span class="nv">die</span>.<span class="w"> </span><span class="nv">Of</span><span class="w"> </span><span class="nv">boredom</span>.
</code></pre></div>
<p>As I discovered with bricklaying, that's no way to live.
This particular problem is caused by the manual nature of graphical schematic editors:
they require the application of conscious thought to each repetition of common operations.
Even if you use copy-paste to lay down multiple bypass caps, you're still repeating yourself.
And each repetition is an opportunity for an error to creep in.</p>
<p>That's one reason I invented SKiDL, a programming language for creating schematics.
Unlike GUI-based tools, programming languages are great at automating repetitive stuff.
I'll demonstrate that by writing code that automatically adds the
bypass capacitors to a chip.</p>
<p>Assume I have a chip with a bunch of ground pins, say twenty.
With SKiDL, I could create the bypass caps like this:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">skidl</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">vdd</span> <span class="o">=</span> <span class="n">Net</span><span class="p">(</span><span class="s1">'+3.3V'</span><span class="p">)</span>
<span class="n">gnd</span> <span class="o">=</span> <span class="n">Net</span><span class="p">(</span><span class="s1">'GND'</span><span class="p">)</span>
<span class="n">bypcap1</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="s2">"Device"</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="s1">'0.1uF'</span><span class="p">,</span> <span class="n">footprint</span><span class="o">=</span><span class="s1">'Capacitors_SMD:C_0603'</span><span class="p">)</span>
<span class="n">bypcap1</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span>
<span class="n">bypcap2</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="s2">"Device"</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="s1">'0.1uF'</span><span class="p">,</span> <span class="n">footprint</span><span class="o">=</span><span class="s1">'Capacitors_SMD:C_0603'</span><span class="p">)</span>
<span class="n">bypcap2</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span>
<span class="o">...</span>
<span class="n">bypcap19</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="s2">"Device"</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="s1">'0.1uF'</span><span class="p">,</span> <span class="n">footprint</span><span class="o">=</span><span class="s1">'Capacitors_SMD:C_0603'</span><span class="p">)</span>
<span class="n">bypcap19</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span>
<span class="n">bypcap20</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="s2">"Device"</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="s1">'0.1uF'</span><span class="p">,</span> <span class="n">footprint</span><span class="o">=</span><span class="s1">'Capacitors_SMD:C_0603'</span><span class="p">)</span>
<span class="n">bypcap20</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span>
</code></pre></div>
<p>Servicable, but not very readable.
Let's recast it as a loop:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">skidl</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">vdd</span> <span class="o">=</span> <span class="n">Net</span><span class="p">(</span><span class="s1">'+3.3V'</span><span class="p">)</span>
<span class="n">gnd</span> <span class="o">=</span> <span class="n">Net</span><span class="p">(</span><span class="s1">'GND'</span><span class="p">)</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">):</span>
<span class="n">bypcap</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="s2">"Device"</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="s1">'0.1uF'</span><span class="p">,</span> <span class="n">footprint</span><span class="o">=</span><span class="s1">'Capacitors_SMD:C_0603'</span><span class="p">)</span>
<span class="n">bypcap</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span>
</code></pre></div>
<p>That little <code>for</code> loop will instantiate twenty caps and connect each one to power and ground.
Boom! Easy.</p>
<p>Easy, but not very general.
I have to know how many ground pins there are on the chip and then write a loop.
Too much work; SKiDL should figure that out for me.
How about if SKiDL counts the number of ground pins on a chip and uses that
to set the loop bound like this:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">skidl</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">vdd</span> <span class="o">=</span> <span class="n">Net</span><span class="p">(</span><span class="s1">'+3.3V'</span><span class="p">)</span>
<span class="n">gnd</span> <span class="o">=</span> <span class="n">Net</span><span class="p">(</span><span class="s1">'GND'</span><span class="p">)</span>
<span class="n">fpga</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="s1">'xilinx'</span><span class="p">,</span> <span class="s1">'XC3S200AN/FT256'</span><span class="p">)</span> <span class="c1"># Create a XILINX FPGA.</span>
<span class="n">num_gnd_pins</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">fpga</span><span class="p">[</span><span class="s1">'GND'</span><span class="p">])</span> <span class="c1"># Get a list of ground pins and count them.</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_gnd_pins</span><span class="p">):</span>
<span class="n">bypcap</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="s2">"Device"</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="s1">'0.1uF'</span><span class="p">,</span> <span class="n">footprint</span><span class="o">=</span><span class="s1">'Capacitors_SMD:C_0603'</span><span class="p">)</span>
<span class="n">bypcap</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span>
</code></pre></div>
<p>Better, but I really don't want to type out that loop for every chip that needs bypass caps.
Luckily, programming languages have functions to encapsulate code that's used multiple times.
SKiDL is a programming language, so it must have them too!
Let's encapsulate the bypass cap instantiation loop in one:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">skidl</span> <span class="kn">import</span> <span class="o">*</span>
<span class="k">def</span> <span class="nf">add_bypass_caps</span><span class="p">(</span><span class="n">chip</span><span class="p">,</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span><span class="p">):</span>
<span class="w"> </span><span class="sd">'''Add bypass capacitors between vdd and gnd to a chip, one for each ground pin.'''</span>
<span class="n">num_gnd_pins</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">chip</span><span class="p">[</span><span class="s1">'GND'</span><span class="p">])</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_gnd_pins</span><span class="p">):</span>
<span class="n">bypcap</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="s2">"Device"</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="s1">'0.1uF'</span><span class="p">,</span> <span class="n">footprint</span><span class="o">=</span><span class="s1">'Capacitors_SMD:C_0603'</span><span class="p">)</span>
<span class="n">bypcap</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span>
<span class="n">vdd</span> <span class="o">=</span> <span class="n">Net</span><span class="p">(</span><span class="s1">'+3.3V'</span><span class="p">)</span>
<span class="n">gnd</span> <span class="o">=</span> <span class="n">Net</span><span class="p">(</span><span class="s1">'GND'</span><span class="p">)</span>
<span class="n">fpga</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="s1">'xilinx'</span><span class="p">,</span> <span class="s1">'XC3S200AN/FT256'</span><span class="p">)</span>
<span class="n">add_bypass_caps</span><span class="p">(</span><span class="n">fpga</span><span class="p">,</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span><span class="p">)</span> <span class="c1"># Call function to add the bypass caps.</span>
</code></pre></div>
<p>That's good; now all that's needed is a function call.
But maybe I don't want to do <em>even that much.</em>
Instead, I could create a subclass of the <code>Part</code> class that adds the bypass caps
when I first instantiate the chip:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">skidl</span> <span class="kn">import</span> <span class="o">*</span>
<span class="k">def</span> <span class="nf">add_bypass_caps</span><span class="p">(</span><span class="n">chip</span><span class="p">,</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span><span class="p">):</span>
<span class="w"> </span><span class="sd">'''Add bypass capacitors between vdd and gnd to a chip, one for each ground pin.'''</span>
<span class="n">num_gnd_pins</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">chip</span><span class="p">[</span><span class="s1">'GND'</span><span class="p">])</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_gnd_pins</span><span class="p">):</span>
<span class="n">bypcap</span> <span class="o">=</span> <span class="n">Part</span><span class="p">(</span><span class="s2">"Device"</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="s1">'0.1uF'</span><span class="p">,</span> <span class="n">footprint</span><span class="o">=</span><span class="s1">'Capacitors_SMD:C_0603'</span><span class="p">)</span>
<span class="n">bypcap</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">]</span> <span class="o">+=</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span>
<span class="k">class</span> <span class="nc">PartWithBypassCaps</span><span class="p">(</span><span class="n">Part</span><span class="p">):</span>
<span class="w"> </span><span class="sd">'''A subclass of Part that adds bypass caps to the part that's created.'''</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="n">Part</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="c1"># Normal part creation.</span>
<span class="n">add_bypass_caps</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">vdd</span><span class="p">,</span> <span class="n">gnd</span><span class="p">)</span> <span class="c1"># Add bypass caps.</span>
<span class="n">vdd</span> <span class="o">=</span> <span class="n">Net</span><span class="p">(</span><span class="s1">'+3.3V'</span><span class="p">)</span>
<span class="n">gnd</span> <span class="o">=</span> <span class="n">Net</span><span class="p">(</span><span class="s1">'GND'</span><span class="p">)</span>
<span class="c1"># Instantiate the chip and also get all the bypass caps automatically.</span>
<span class="n">fpga</span> <span class="o">=</span> <span class="n">PartWithBypassCaps</span><span class="p">(</span><span class="s1">'xilinx'</span><span class="p">,</span> <span class="s1">'XC3S200AN/FT256'</span><span class="p">,</span> <span class="n">gnd</span><span class="o">=</span><span class="n">gnd</span><span class="p">,</span> <span class="n">vdd</span><span class="o">=</span><span class="n">vdd</span><span class="p">)</span>
</code></pre></div>
<p>So I've gone from explicitly instantiating each bypass capacitor,
to using a loop, then a function, and finally ended up with a
class that adds the caps implicitly.
And that class can be used for chip after chip in design after design
until I die. But not of boredom!</p>
<p>Are there shortcomings in my technique?
Of course (and I'll correct them in a future blog post), but I wanted to keep
the code simple so it wouldn't distract from the primary point of
using SKiDL:</p>
<p><strong>Automation is pretty good stuff. (We should do more of it.)</strong></p>
</div> <!--/#entry-content-->
</div> <!--/#main-->
</div> <!--/#post-->
</div>
<div id="footer">
<p> </p>
</div><!-- /#footer -->
</div><!-- /#container -->
<div style="display:none"></div>
</body>
</html>