1 /*
2  * Copyright CERN 2015
3  * @author Maciej Suminski (maciej.suminski@cern.ch)
4  *
5  *    This source code is free software; you can redistribute it
6  *    and/or modify it in source code form under the terms of the GNU
7  *    General Public License as published by the Free Software
8  *    Foundation; either version 2 of the License, or (at your option)
9  *    any later version.
10  *
11  *    This program is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *    GNU General Public License for more details.
15  *
16  *    You should have received a copy of the GNU General Public License
17  *    along with this program; if not, write to the Free Software
18  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 #include "std_types.h"
22 #include "scope.h"
23 
24 static map<perm_string, VTypeDef*> std_types;
25 // this list contains enums used by typedefs in the std_types map
26 static list<const VTypeEnum*> std_enums;
27 
28 const VTypePrimitive primitive_BIT(VTypePrimitive::BIT, true);
29 const VTypePrimitive primitive_INTEGER(VTypePrimitive::INTEGER);
30 const VTypePrimitive primitive_NATURAL(VTypePrimitive::NATURAL);
31 const VTypePrimitive primitive_REAL(VTypePrimitive::REAL);
32 const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC, true);
33 const VTypePrimitive primitive_TIME(VTypePrimitive::TIME, true);
34 
35 VTypeDef type_BOOLEAN(perm_string::literal("boolean"));
36 VTypeDef type_FILE_OPEN_KIND(perm_string::literal("file_open_kind"));
37 VTypeDef type_FILE_OPEN_STATUS(perm_string::literal("file_open_status"));
38 
39 const VTypeArray primitive_CHARACTER(&primitive_BIT,            7, 0);
40 const VTypeArray primitive_BIT_VECTOR(&primitive_BIT,           vector<VTypeArray::range_t> (1));
41 const VTypeArray primitive_BOOL_VECTOR(&type_BOOLEAN,           vector<VTypeArray::range_t> (1));
42 const VTypeArray primitive_STDLOGIC_VECTOR(&primitive_STDLOGIC, vector<VTypeArray::range_t> (1));
43 const VTypeArray primitive_STRING(&primitive_CHARACTER,         vector<VTypeArray::range_t> (1));
44 const VTypeArray primitive_SIGNED(&primitive_STDLOGIC,          vector<VTypeArray::range_t> (1), true);
45 const VTypeArray primitive_UNSIGNED(&primitive_STDLOGIC,        vector<VTypeArray::range_t> (1), false);
46 
generate_global_types(ActiveScope * res)47 void generate_global_types(ActiveScope*res)
48 {
49     // boolean
50       list<perm_string> enum_BOOLEAN_vals;
51       enum_BOOLEAN_vals.push_back(perm_string::literal("false"));
52       enum_BOOLEAN_vals.push_back(perm_string::literal("true"));
53       VTypeEnum*enum_BOOLEAN = new VTypeEnum(&enum_BOOLEAN_vals);
54       type_BOOLEAN.set_definition(enum_BOOLEAN);
55       std_types[type_BOOLEAN.peek_name()] = &type_BOOLEAN;
56       std_enums.push_back(enum_BOOLEAN);
57 
58     // file_open_kind
59       list<perm_string> enum_FILE_OPEN_KIND_vals;
60       enum_FILE_OPEN_KIND_vals.push_back(perm_string::literal("read_mode"));
61       enum_FILE_OPEN_KIND_vals.push_back(perm_string::literal("write_mode"));
62       enum_FILE_OPEN_KIND_vals.push_back(perm_string::literal("append_mode"));
63       VTypeEnum*enum_FILE_OPEN_KIND = new VTypeEnum(&enum_FILE_OPEN_KIND_vals);
64       type_FILE_OPEN_KIND.set_definition(enum_FILE_OPEN_KIND);
65       std_types[type_FILE_OPEN_KIND.peek_name()] = &type_FILE_OPEN_KIND;
66       std_enums.push_back(enum_FILE_OPEN_KIND);
67 
68     // file_open_status
69       list<perm_string> enum_FILE_OPEN_STATUS_vals;
70       enum_FILE_OPEN_STATUS_vals.push_back(perm_string::literal("open_ok"));
71       enum_FILE_OPEN_STATUS_vals.push_back(perm_string::literal("status_error"));
72       enum_FILE_OPEN_STATUS_vals.push_back(perm_string::literal("name_error"));
73       enum_FILE_OPEN_STATUS_vals.push_back(perm_string::literal("mode_error"));
74       VTypeEnum*enum_FILE_OPEN_STATUS = new VTypeEnum(&enum_FILE_OPEN_STATUS_vals);
75       type_FILE_OPEN_STATUS.set_definition(enum_FILE_OPEN_STATUS);
76       std_types[type_FILE_OPEN_STATUS.peek_name()] = &type_FILE_OPEN_STATUS;
77       std_enums.push_back(enum_FILE_OPEN_STATUS);
78 
79       res->use_name(type_BOOLEAN.peek_name(),           &type_BOOLEAN);
80       res->use_name(perm_string::literal("bit"),        &primitive_BIT);
81       res->use_name(perm_string::literal("bit_vector"), &primitive_BIT_VECTOR);
82       res->use_name(perm_string::literal("integer"),    &primitive_INTEGER);
83       res->use_name(perm_string::literal("real"),       &primitive_REAL);
84       res->use_name(perm_string::literal("std_logic"),  &primitive_STDLOGIC);
85       res->use_name(perm_string::literal("character"),  &primitive_CHARACTER);
86       res->use_name(perm_string::literal("string"),     &primitive_STRING);
87       res->use_name(perm_string::literal("natural"),    &primitive_NATURAL);
88       res->use_name(perm_string::literal("time"),       &primitive_TIME);
89 }
90 
delete_global_types()91 void delete_global_types()
92 {
93     typedef_context_t typedef_ctx;
94     for(map<perm_string, VTypeDef*>::iterator cur = std_types.begin();
95             cur != std_types.end(); ++cur) {
96         delete cur->second->peek_definition();
97         delete cur->second;
98     }
99 
100     // std_enums are destroyed above
101 }
102 
find_std_enum_name(perm_string name)103 const VTypeEnum*find_std_enum_name(perm_string name)
104 {
105     for(list<const VTypeEnum*>::const_iterator it = std_enums.begin();
106             it != std_enums.end(); ++it) {
107         if((*it)->has_name(name))
108             return *it;
109     }
110 
111     return NULL;
112 }
113 
emit_std_types(ostream & fd)114 void emit_std_types(ostream&fd)
115 {
116     fd << "`ifndef __VHDL_STD_TYPES" << endl;
117     fd << "`define __VHDL_STD_TYPES" << endl;
118     typedef_context_t typedef_ctx;
119     for(map<perm_string, VTypeDef*>::iterator cur = std_types.begin();
120             cur != std_types.end() ; ++ cur) {
121         cur->second->emit_typedef(fd, typedef_ctx);
122     }
123     fd << "`endif" << endl;
124 }
125 
is_global_type(perm_string name)126 bool is_global_type(perm_string name)
127 {
128       if (name == "boolean") return true;
129       if (name == "bit") return true;
130       if (name == "bit_vector") return true;
131       if (name == "integer") return true;
132       if (name == "real") return true;
133       if (name == "std_logic") return true;
134       if (name == "std_logic_vector") return true;
135       if (name == "character") return true;
136       if (name == "string") return true;
137       if (name == "natural") return true;
138       if (name == "signed") return true;
139       if (name == "unsigned") return true;
140       if (name == "time") return true;
141 
142       return std_types.count(name) > 0;
143 }
144 
145