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 #ifndef config_reader_h
21 #define config_reader_h
22 
23 #include<list>
24 #include<vector>
25 #include<array>
26 #include<string>
27 #include<iostream>
28 
29 #include "linereader.h"
30 
31 /** reads a IO configuration file
32 
33     Example file:
34 
35     DESIGN PADRING
36     AREA 1000 1000
37     GRID 1
38     CORNER CORNER1 NW CORNERESDP
39     CORNER CORNER2 SW CORNERESDP
40     CORNER CORNER3 SE CORNERESDP
41     CORNER CORNER4 NE CORNERESDP
42     PAD IO1 N BBC16F
43     PAD IO2 N BBC16F
44     PAD IO3 N BBC16F
45     PAD IO4 N BBC16F
46     SPACE 50            # fixed space between cells
47     PAD IO5 N BBC16F
48     PAD IO6 N BBC16F
49     PAD IO7 N BBC16F
50     PAD IO8 N BBC16F
51 
52 */
53 
54 class ConfigReader
55 {
56 public:
ConfigReader()57     ConfigReader() : m_padCount(0) {}
58 
~ConfigReader()59     virtual ~ConfigReader() {}
60 
61     enum token_t
62     {
63         TOK_EOF,
64         TOK_IDENT,
65         TOK_STRING,
66         TOK_NUMBER,
67         TOK_MINUS,
68         TOK_LBRACKET,
69         TOK_RBRACKET,
70         TOK_LPAREN,
71         TOK_RPAREN,
72         TOK_HASH,
73         TOK_SEMICOL,
74         TOK_EOL,
75         TOK_ERR
76     };
77 
78     bool parse(std::istream &configfile);
79 
80     /** callback for a corner */
onCorner(const std::string & instance,const std::string & location,const std::string & cellname)81     virtual void onCorner(
82         const std::string &instance,
83         const std::string &location,
84         const std::string &cellname)
85     {
86         std::cout << "CORNER " << instance << " " << location << " " << cellname << "\n";
87     }
88 
89     /** callback for a pad
90      *  location is one of N,S,W,E
91      *  if flipped == true, the (unplaced/unrotated) cell is flipped along the y axis.
92     */
onPad(const std::string & instance,const std::string & location,const std::string & cellname,bool flipped)93     virtual void onPad(
94         const std::string &instance,
95         const std::string &location,
96         const std::string &cellname,
97         bool flipped)
98     {
99         std::cout << "PAD " << instance << " " << location << " " << cellname << "\n";
100     }
101 
102     /** callback for die area in microns */
onArea(double x,double y)103     virtual void onArea(double x, double y)
104     {
105         std::cout << "Area " << x << " " << y << "\n";
106     }
107 
108     /** callback for grid spacing in microns */
onGrid(double grid)109     virtual void onGrid(double grid)
110     {
111         std::cout << "Grid " << grid << "\n";
112     }
113 
114     /** callback for grid spacing in microns */
onFiller(const std::string & fillerName)115     virtual void onFiller(const std::string &fillerName)
116     {
117         std::cout << "Filler prefix:" << fillerName << "\n";
118     }
119 
120     /** callback for space in microns */
onSpace(double space)121     virtual void onSpace(double space)
122     {
123         std::cout << "Space " << space << "\n";
124     }
125 
126     /** callback for offset in microns */
onOffset(double offset)127     virtual void onOffset(double offset)
128     {
129         std::cout << "Offset " << offset << "\n";
130     }
131 
132     /** callback for design name */
onDesignName(const std::string & designName)133     virtual void onDesignName(const std::string &designName)
134     {
135         std::cout << "Design name " << designName << "\n";
136     }
137 
138     /** return the number of pad cells (excluding corners) */
getPadCellCount()139     uint32_t getPadCellCount() const
140     {
141         return m_padCount;
142     }
143 
144 protected:
145     bool isWhitespace(char c) const;
146     bool isAlpha(char c) const;
147     bool isDigit(char c) const;
148     bool isAlphaNumeric(char c) const;
149     bool isSpecialIdentChar(char c) const;
150 
151     bool inArray(const std::string &value, const std::array<std::string, 4> &array);
152 
153     bool parsePad();
154     bool parseCorner();
155     bool parseArea();
156     bool parseGrid();
157     bool parseSpace();
158     bool parseOffset();
159     bool parseFiller();
160     bool parseDesignName();
161 
162     token_t      tokenize(std::string &tokstr);
163     char         m_tokchar;
164 
165     void error(const std::string &errstr);
166 
167     std::istream *m_is;
168     uint32_t      m_lineNum;
169     uint32_t      m_padCount;   ///< number of pad cells excluding corners
170 };
171 
172 
173 #endif
174 
175 
176