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