1 /*
2 PADRING -- a padring generator for ASICs.
3
4 Copyright (c) 2019, Niels Moseley <niels@symbioticeda.com>
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 */
19
20 #include <sstream>
21 #include <fstream>
22 #include <iomanip>
23 #include <complex>
24 #include <math.h>
25 #include <assert.h>
26 #include "logging.h"
27 #include "defwriter.h"
28
DEFWriter(std::ostream & os,uint32_t width,uint32_t height)29 DEFWriter::DEFWriter(std::ostream &os, uint32_t width, uint32_t height)
30 : m_def(os),
31 m_width(width),
32 m_height(height),
33 m_cellCount(0),
34 m_databaseUnits(0.0)
35 {
36 // make sure the stringstream doesn't use
37 // exponential notation with doubles!
38 m_ss << std::setprecision(std::numeric_limits<double>::digits10);
39 }
40
~DEFWriter()41 DEFWriter::~DEFWriter()
42 {
43 m_def.flush();
44 writeToFile();
45 }
46
writeToFile()47 void DEFWriter::writeToFile()
48 {
49 assert(!m_designName.empty());
50
51 m_def << "DESIGN " << m_designName << " ;\n";
52 m_def << "UNITS DISTANCE MICRONS " << m_databaseUnits << " ; \n";
53 m_def << "COMPONENTS " << m_cellCount << " ;\n";
54
55 m_def << m_ss.str();
56
57 m_def << "END COMPONENTS\n";
58 m_def << "END DESIGN\n";
59 }
60
61
toDEFCoordinates(double & x,double & y)62 void DEFWriter::toDEFCoordinates(double &x, double &y)
63 {
64 //return std::complex<double>(p.real(), m_height - p.imag());
65 //FIXME: use database units defined in LEF file!
66
67 if (m_databaseUnits < 1e-12)
68 {
69 doLog(LOG_WARN, "DEF database units not set! does your imported LEF file specify it?\n");
70 doLog(LOG_WARN, " Assuming the value is 100.0\n");
71 m_databaseUnits = 100.0;
72 }
73
74 x *= m_databaseUnits;
75 y *= m_databaseUnits;
76 }
77
writeCell(const LayoutItem * item)78 void DEFWriter::writeCell(const LayoutItem *item)
79 {
80 if (item == nullptr)
81 {
82 return;
83 }
84
85 double rot = 0.0;
86 double x = item->m_x;
87 double y = item->m_y;
88
89 m_cellCount++;
90
91 if (item->m_ltype == LayoutItem::TYPE_FILLER)
92 {
93 m_ss << " - FILLER_" << m_cellCount << " " << item->m_cellname << "\n";
94 }
95 else
96 {
97 m_ss << " - " << item->m_instance << " " << item->m_cellname << "\n";
98 }
99 // do corners
100 if (item->m_location == "NW")
101 {
102 y -= item->m_lefinfo->m_sx;
103 toDEFCoordinates(x,y);
104 m_ss << " + PLACED ( " << x << " " << y << " ) ";
105 m_ss << "W ;\n";
106 }
107 else if (item->m_location == "SE")
108 {
109 // South East orientation, rotation = 90 degrees
110 //x += item->m_lefinfo->m_sy;
111 toDEFCoordinates(x,y);
112 m_ss << " + PLACED ( " << x << " " << y << " ) ";
113 m_ss << "E ;\n";
114 }
115 else if (item->m_location == "NE")
116 {
117 y -= item->m_lefinfo->m_sy;
118 toDEFCoordinates(x,y);
119 m_ss << " + PLACED ( " << x << " " << y << " ) ";
120 m_ss << "N ;\n";
121 }
122 else if (item->m_location == "SW")
123 {
124 toDEFCoordinates(x,y);
125 m_ss << " + PLACED ( " << x << " " << y << " ) ";
126 m_ss << "S ;\n";
127 }
128 else if (item->m_location == "E")
129 {
130 x -= item->m_lefinfo->m_sy;
131 toDEFCoordinates(x,y);
132 m_ss << " + PLACED ( " << x << " " << y << " ) ";
133
134 if (!item->m_flipped)
135 {
136 m_ss << " E" << " ;\n";
137 }
138 else
139 {
140 m_ss << " W" << " ;\n";
141 }
142 }
143 else if (item->m_location == "N")
144 {
145 y -= item->m_lefinfo->m_sy;
146 toDEFCoordinates(x,y);
147 m_ss << " + PLACED ( " << x << " " << y << " ) ";
148 if (!item->m_flipped)
149 {
150 m_ss << " N" << " ;\n";
151 }
152 else
153 {
154 m_ss << " S" << " ;\n";
155 }
156 }
157 else if (item->m_location == "S")
158 {
159 //y -= item->m_lefinfo->m_sy;
160 toDEFCoordinates(x,y);
161 m_ss << " + PLACED ( " << x << " " << y << " ) ";
162 if (!item->m_flipped)
163 {
164 m_ss << " S" << " ;\n";
165 }
166 else
167 {
168 m_ss << " N" << " ;\n";
169 }
170 }
171 else
172 {
173 toDEFCoordinates(x,y);
174 m_ss << " + PLACED ( " << x << " " << y << " ) ";
175 if (!item->m_flipped)
176 {
177 m_ss << " W" << " ;\n";
178 }
179 else
180 {
181 m_ss << " E" << " ;\n";
182 }
183 }
184 }
185