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