vhdlpp: Refactored the way of handling standard types.

This commit is contained in:
Maciej Suminski 2015-06-11 22:01:22 +02:00
parent b666b9c0bf
commit d39f692cfd
15 changed files with 223 additions and 142 deletions

View File

@ -57,7 +57,7 @@ LIBS = @LIBS@ @EXTRALIBS@
M = StringHeap.o LineInfo.o
O = main.o architec.o compiler.o entity.o std_funcs.o \
O = main.o architec.o compiler.o entity.o std_funcs.o std_types.o \
expression.o package.o scope.o sequential.o subprogram.o vsignal.o vtype.o \
vtype_match.o \
architec_elaborate.o entity_elaborate.o expression_elaborate.o \

View File

@ -25,6 +25,7 @@
# include "vsignal.h"
# include "subprogram.h"
# include "library.h"
# include "std_types.h"
# include <iostream>
# include <typeinfo>
# include "parse_types.h"
@ -980,7 +981,7 @@ const VType* ExpNameALL::probe_type(Entity*, ScopeBase*) const
const VType* ExpRelation::probe_type(Entity*, ScopeBase*) const
{
return &primitive_BOOLEAN;
return &type_BOOLEAN;
}
int ExpRelation::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)

View File

@ -22,6 +22,7 @@
# include "parse_misc.h"
# include "compiler.h"
# include "package.h"
# include "std_types.h"
# include <fstream>
# include <list>
# include <map>
@ -318,14 +319,10 @@ static void import_ieee_use_numeric_bit(ActiveScope*res, perm_string name)
bool all_flag = name=="all";
if (all_flag || name == "signed") {
vector<VTypeArray::range_t> dims (1);
res->use_name(perm_string::literal("signed"),
new VTypeArray(&primitive_STDLOGIC, dims, true));
res->use_name(perm_string::literal("signed"), &primitive_SIGNED);
}
if (all_flag || name == "unsigned") {
vector<VTypeArray::range_t> dims (1);
res->use_name(perm_string::literal("unsigned"),
new VTypeArray(&primitive_BIT, dims, false));
res->use_name(perm_string::literal("unsigned"), &primitive_UNSIGNED);
}
}
@ -334,14 +331,10 @@ static void import_ieee_use_numeric_std(ActiveScope*res, perm_string name)
bool all_flag = name=="all";
if (all_flag || name == "signed") {
vector<VTypeArray::range_t> dims (1);
res->use_name(perm_string::literal("signed"),
new VTypeArray(&primitive_STDLOGIC, dims, true));
res->use_name(perm_string::literal("signed"), &primitive_SIGNED);
}
if (all_flag || name == "unsigned") {
vector<VTypeArray::range_t> dims (1);
res->use_name(perm_string::literal("unsigned"),
new VTypeArray(&primitive_STDLOGIC, dims, false));
res->use_name(perm_string::literal("unsigned"), &primitive_UNSIGNED);
}
}
@ -382,60 +375,6 @@ static void import_std_use(const YYLTYPE&loc, ActiveScope*/*res*/, perm_string p
}
}
const VTypePrimitive primitive_BOOLEAN(VTypePrimitive::BOOLEAN, true);
const VTypePrimitive primitive_BIT(VTypePrimitive::BIT, true);
const VTypePrimitive primitive_INTEGER(VTypePrimitive::INTEGER);
const VTypePrimitive primitive_NATURAL(VTypePrimitive::NATURAL);
const VTypePrimitive primitive_REAL(VTypePrimitive::REAL);
const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC, true);
const VTypePrimitive primitive_CHARACTER(VTypePrimitive::CHARACTER);
const VTypePrimitive primitive_TIME(VTypePrimitive::TIME);
const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector<VTypeArray::range_t> (1));
const VTypeArray primitive_BOOL_VECTOR(&primitive_BOOLEAN, vector<VTypeArray::range_t> (1));
const VTypeArray primitive_STDLOGIC_VECTOR(&primitive_STDLOGIC, vector<VTypeArray::range_t> (1));
const VTypeArray primitive_STRING(&primitive_CHARACTER, vector<VTypeArray::range_t> (1));
void generate_global_types(ActiveScope*res)
{
res->use_name(perm_string::literal("boolean"), &primitive_BOOLEAN);
res->use_name(perm_string::literal("bit"), &primitive_BIT);
res->use_name(perm_string::literal("bit_vector"), &primitive_BIT_VECTOR);
res->use_name(perm_string::literal("integer"), &primitive_INTEGER);
res->use_name(perm_string::literal("real"), &primitive_REAL);
res->use_name(perm_string::literal("std_logic"), &primitive_STDLOGIC);
res->use_name(perm_string::literal("character"), &primitive_CHARACTER);
res->use_name(perm_string::literal("string"), &primitive_STRING);
res->use_name(perm_string::literal("natural"), &primitive_NATURAL);
res->use_name(perm_string::literal("time"), &primitive_TIME);
}
void emit_std_types(ostream&out)
{
out << "`ifndef __VHDL_STD_TYPES" << endl;
out << "`define __VHDL_STD_TYPES" << endl;
out << "typedef enum bit { \\false , \\true } boolean ;" << endl;
out << "`endif" << endl;
}
bool is_global_type(perm_string name)
{
if (name == "boolean") return true;
if (name == "bit") return true;
if (name == "bit_vector") return true;
if (name == "integer") return true;
if (name == "real") return true;
if (name == "std_logic") return true;
if (name == "std_logic_vector") return true;
if (name == "character") return true;
if (name == "string") return true;
if (name == "natural") return true;
if (name == "signed") return true;
if (name == "unsigned") return true;
if (name == "time") return true;
return false;
}
void library_set_work_path(const char*path)
{
assert(library_work_path == 0);

View File

@ -26,8 +26,5 @@ extern void library_add_directory(const char*directory);
extern SubprogramHeader*library_find_subprogram(perm_string name);
extern void emit_std_types(ostream&out);
extern int emit_packages(void);
#endif /* IVL_library_H */

View File

@ -77,6 +77,7 @@ const char NOTICE[] =
# include "compiler.h"
# include "library.h"
# include "std_funcs.h"
# include "std_types.h"
# include "parse_api.h"
# include "vtype.h"
# include <fstream>

View File

@ -22,6 +22,7 @@
# include "entity.h"
# include "subprogram.h"
# include "parse_misc.h"
# include "std_types.h"
# include "ivl_assert.h"
Package::Package(perm_string n, const ActiveScope&ref)
@ -57,6 +58,11 @@ void Package::write_to_stream(ostream&fd) const
const VTypeDef*def = dynamic_cast<const VTypeDef*> (cur->second);
if (def == 0)
continue;
// Do not include global types in types dump
if (is_global_type(cur->first))
continue;
fd << "type " << cur->first << ";" << endl;
}
for (map<perm_string,const VType*>::const_iterator cur = cur_types_.begin()
@ -64,6 +70,11 @@ void Package::write_to_stream(ostream&fd) const
const VTypeDef*def = dynamic_cast<const VTypeDef*> (cur->second);
if (def == 0)
continue;
// Do not include global types in types dump
if (is_global_type(cur->first))
continue;
fd << "type " << cur->first << ";" << endl;
}

View File

@ -40,6 +40,7 @@
# include "vsignal.h"
# include "vtype.h"
# include "std_funcs.h"
# include "std_types.h"
# include <cstdarg>
# include <cstring>
# include <list>
@ -1607,14 +1608,7 @@ mode_opt : mode {$$ = $1;} | {$$ = PORT_NONE;} ;
name /* IEEE 1076-2008 P8.1 */
: IDENTIFIER /* simple_name (IEEE 1076-2008 P8.2) */
{ Expression*tmp;
if(!strcasecmp($1, "true"))
tmp = new ExpBitstring("1");
else if(!strcasecmp($1, "false"))
tmp = new ExpBitstring("0");
else
tmp = new ExpName(lex_strings.make($1));
{ Expression*tmp = new ExpName(lex_strings.make($1));
FILE_NAME(tmp, @1);
delete[]$1;
$$ = tmp;

View File

@ -63,8 +63,4 @@ extern void library_import(const YYLTYPE&loc, const std::list<perm_string>*names
extern void library_use(const YYLTYPE&loc, ActiveScope*res, const char*libname, const char*pack, const char*ident);
extern void generate_global_types(ActiveScope*res);
extern bool is_global_type(perm_string type_name);
#endif /* IVL_parse_misc_H */

View File

@ -19,7 +19,7 @@
*/
#include "std_funcs.h"
#include "vtype.h"
#include "std_types.h"
#include "scope.h"
static std::map<perm_string,SubprogramHeader*> std_subprograms;
@ -160,7 +160,7 @@ void preload_std_funcs(void)
fn_rising_edge_args->push_back(new InterfacePort(&primitive_STDLOGIC));
fn_rising_edge = new SubprogramBuiltin(perm_string::literal("rising_edge"),
perm_string::literal("$ivlh_rising_edge"),
fn_rising_edge_args, &primitive_BOOLEAN);
fn_rising_edge_args, &type_BOOLEAN);
std_subprograms[fn_rising_edge->name()] = fn_rising_edge;
/* std_logic_1164 library
@ -170,7 +170,7 @@ void preload_std_funcs(void)
fn_falling_edge_args->push_back(new InterfacePort(&primitive_STDLOGIC));
fn_falling_edge = new SubprogramBuiltin(perm_string::literal("falling_edge"),
perm_string::literal("$ivlh_falling_edge"),
fn_falling_edge_args, &primitive_BOOLEAN);
fn_falling_edge_args, &type_BOOLEAN);
std_subprograms[fn_falling_edge->name()] = fn_falling_edge;
/* reduce_pack library

118
vhdlpp/std_types.cc Normal file
View File

@ -0,0 +1,118 @@
/*
* Copyright CERN 2015
* @author Maciej Suminski (maciej.suminski@cern.ch)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "std_types.h"
#include "scope.h"
static std::map<perm_string, VTypeDef*> std_types;
// this list contains enums used by typedefs in the std_types map
static std::list<const VTypeEnum*> std_enums;
const VTypePrimitive primitive_BIT(VTypePrimitive::BIT, true);
const VTypePrimitive primitive_INTEGER(VTypePrimitive::INTEGER);
const VTypePrimitive primitive_NATURAL(VTypePrimitive::NATURAL);
const VTypePrimitive primitive_REAL(VTypePrimitive::REAL);
const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC, true);
const VTypePrimitive primitive_CHARACTER(VTypePrimitive::CHARACTER);
const VTypePrimitive primitive_TIME(VTypePrimitive::TIME);
VTypeDef type_BOOLEAN(perm_string::literal("boolean"));
const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector<VTypeArray::range_t> (1));
const VTypeArray primitive_BOOL_VECTOR(&type_BOOLEAN, vector<VTypeArray::range_t> (1));
const VTypeArray primitive_STDLOGIC_VECTOR(&primitive_STDLOGIC, vector<VTypeArray::range_t> (1));
const VTypeArray primitive_STRING(&primitive_CHARACTER, vector<VTypeArray::range_t> (1));
const VTypeArray primitive_SIGNED(&primitive_STDLOGIC, vector<VTypeArray::range_t> (1), true);
const VTypeArray primitive_UNSIGNED(&primitive_STDLOGIC, vector<VTypeArray::range_t> (1), false);
void generate_global_types(ActiveScope*res)
{
// boolean
std::list<perm_string>*enum_BOOLEAN_vals = new std::list<perm_string>;
enum_BOOLEAN_vals->push_back(perm_string::literal("false"));
enum_BOOLEAN_vals->push_back(perm_string::literal("true"));
VTypeEnum*enum_BOOLEAN = new VTypeEnum(enum_BOOLEAN_vals);
type_BOOLEAN.set_definition(enum_BOOLEAN);
std_types[type_BOOLEAN.peek_name()] = &type_BOOLEAN;
res->use_name(type_BOOLEAN.peek_name(), &type_BOOLEAN);
res->use_name(perm_string::literal("bit"), &primitive_BIT);
res->use_name(perm_string::literal("bit_vector"), &primitive_BIT_VECTOR);
res->use_name(perm_string::literal("integer"), &primitive_INTEGER);
res->use_name(perm_string::literal("real"), &primitive_REAL);
res->use_name(perm_string::literal("std_logic"), &primitive_STDLOGIC);
res->use_name(perm_string::literal("character"), &primitive_CHARACTER);
res->use_name(perm_string::literal("string"), &primitive_STRING);
res->use_name(perm_string::literal("natural"), &primitive_NATURAL);
res->use_name(perm_string::literal("time"), &primitive_TIME);
}
void delete_global_types()
{
typedef_context_t typedef_ctx;
for(map<perm_string, VTypeDef*>::iterator cur = std_types.begin();
cur != std_types.end() ; ++ cur) {
delete cur->second->peek_definition();
delete cur->second;
}
}
const VTypeEnum*find_std_enum_name(perm_string name)
{
for(list<const VTypeEnum*>::iterator it = std_enums.begin();
it != std_enums.end(); ++it) {
if((*it)->has_name(name))
return *it;
}
return NULL;
}
void emit_std_types(ostream&fd)
{
fd << "`ifndef __VHDL_STD_TYPES" << endl;
fd << "`define __VHDL_STD_TYPES" << endl;
typedef_context_t typedef_ctx;
for(map<perm_string, VTypeDef*>::iterator cur = std_types.begin();
cur != std_types.end() ; ++ cur) {
cur->second->emit_typedef(fd, typedef_ctx);
}
fd << "`endif" << endl;
}
bool is_global_type(perm_string name)
{
if (name == "boolean") return true;
if (name == "bit") return true;
if (name == "bit_vector") return true;
if (name == "integer") return true;
if (name == "real") return true;
if (name == "std_logic") return true;
if (name == "std_logic_vector") return true;
if (name == "character") return true;
if (name == "string") return true;
if (name == "natural") return true;
if (name == "signed") return true;
if (name == "unsigned") return true;
if (name == "time") return true;
return std_types.count(name) > 0;
}

47
vhdlpp/std_types.h Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright CERN 2015
* @author Maciej Suminski (maciej.suminski@cern.ch)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "vtype.h"
class ActiveScope;
void emit_std_types(ostream&out);
int emit_packages(void);
void generate_global_types(ActiveScope*res);
bool is_global_type(perm_string type_name);
void delete_global_types();
extern const VTypePrimitive primitive_BOOLEAN;
extern const VTypePrimitive primitive_BIT;
extern const VTypePrimitive primitive_INTEGER;
extern const VTypePrimitive primitive_NATURAL;
extern const VTypePrimitive primitive_REAL;
extern const VTypePrimitive primitive_STDLOGIC;
extern const VTypePrimitive primitive_CHARACTER;
extern const VTypePrimitive primitive_TIME;
extern VTypeDef type_BOOLEAN;
extern const VTypeArray primitive_BIT_VECTOR;
extern const VTypeArray primitive_BOOL_VECTOR;
extern const VTypeArray primitive_STDLOGIC_VECTOR;
extern const VTypeArray primitive_STRING;
extern const VTypeArray primitive_SIGNED;
extern const VTypeArray primitive_UNSIGNED;

View File

@ -55,9 +55,6 @@ VTypePrimitive::~VTypePrimitive()
void VTypePrimitive::show(ostream&out) const
{
switch (type_) {
case BOOLEAN:
out << "BOOLEAN";
break;
case BIT:
out << "BIT";
break;
@ -85,7 +82,6 @@ void VTypePrimitive::show(ostream&out) const
int VTypePrimitive::get_width(ScopeBase*) const
{
switch(type_) {
case BOOLEAN:
case BIT:
case STDLOGIC:
return 1;

View File

@ -156,7 +156,7 @@ class VTypeERROR : public VType {
class VTypePrimitive : public VType {
public:
enum type_t { BOOLEAN, BIT, INTEGER, NATURAL, REAL, STDLOGIC, CHARACTER, TIME };
enum type_t { BIT, INTEGER, NATURAL, REAL, STDLOGIC, CHARACTER, TIME };
public:
VTypePrimitive(type_t tt, bool packed = false);
@ -256,6 +256,8 @@ class VTypeArray : public VType {
private:
int emit_with_dims_(std::ostream&out, bool packed, perm_string name) const;
// Handles a few special types of array (*_vector, string types).
bool write_special_case(std::ostream&out) const;
void write_range_to_stream_(std::ostream&fd) const;
const VType*etype_;
@ -382,18 +384,4 @@ class VTypeDef : public VType {
const VType*type_;
};
extern const VTypePrimitive primitive_BOOLEAN;
extern const VTypePrimitive primitive_BIT;
extern const VTypePrimitive primitive_INTEGER;
extern const VTypePrimitive primitive_NATURAL;
extern const VTypePrimitive primitive_REAL;
extern const VTypePrimitive primitive_STDLOGIC;
extern const VTypePrimitive primitive_CHARACTER;
extern const VTypePrimitive primitive_TIME;
extern const VTypeArray primitive_BIT_VECTOR;
extern const VTypeArray primitive_BOOL_VECTOR;
extern const VTypeArray primitive_STDLOGIC_VECTOR;
extern const VTypeArray primitive_STRING;
#endif /* IVL_vtype_H */

View File

@ -148,9 +148,6 @@ int VTypePrimitive::emit_primitive_type(ostream&out) const
{
int errors = 0;
switch (type_) {
case BOOLEAN:
out << "boolean";
break;
case BIT:
out << "bit";
break;

View File

@ -18,7 +18,7 @@
*/
# define __STDC_LIMIT_MACROS
# include "vtype.h"
# include "std_types.h"
# include "expression.h"
# include <typeinfo>
# include <stdint.h>
@ -38,20 +38,8 @@ void VType::write_type_to_stream(ostream&fd) const
void VTypeArray::write_to_stream(ostream&fd) const
{
// Special cases: std_logic_vector & string
if (etype_ == &primitive_STDLOGIC) {
fd << "std_logic_vector";
if (!ranges_.empty() && !ranges_[0].is_box()) {
write_range_to_stream_(fd);
}
return;
} else if (etype_ == &primitive_CHARACTER) {
fd << "string";
if (!ranges_.empty() && !ranges_[0].is_box()) {
write_range_to_stream_(fd);
}
return;
}
if(write_special_case(fd))
return;
bool typedefed = false;
if(const VTypeDef*tdef = dynamic_cast<const VTypeDef*>(etype_)) {
@ -96,26 +84,37 @@ void VTypeArray::write_range_to_stream_(std::ostream&fd) const
fd << ") ";
}
bool VTypeArray::write_special_case(std::ostream&fd) const
{
if(this == &primitive_SIGNED) {
fd << "signed";
} else if(this == &primitive_UNSIGNED) {
fd << "unsigned";
} else if(etype_ == &primitive_STDLOGIC) {
fd << "std_logic_vector";
} else if(etype_ == &primitive_BIT) {
fd << "bit_vector";
} else if(etype_ == &primitive_CHARACTER) {
fd << "string";
} else {
return false;
}
if(!ranges_.empty() && !ranges_[0].is_box()) {
write_range_to_stream_(fd);
}
return true;
}
void VTypeArray::write_type_to_stream(ostream&fd) const
{
// Special case: std_logic_vector
if (etype_ == &primitive_STDLOGIC) {
fd << "std_logic_vector";
if (! ranges_.empty() && ! ranges_[0].is_box()) {
write_range_to_stream_(fd);
}
return;
}
else if (etype_ == &primitive_CHARACTER) {
fd << "string";
if (! ranges_.empty() && ! ranges_[0].is_box()) {
write_range_to_stream_(fd);
}
return;
}
if(write_special_case(fd))
return;
fd << "array ";
// Unbounded array
if (! ranges_.empty()) {
assert(ranges_.size() < 2);
if (ranges_[0].is_box()) {
@ -165,9 +164,6 @@ void VTypePrimitive::write_to_stream(ostream&fd) const
case CHARACTER:
fd << "character";
break;
case BOOLEAN:
fd << "boolean";
break;
case TIME:
fd << "time";
break;
@ -183,7 +179,7 @@ void VTypeRange::write_to_stream(ostream&fd) const
// Detect some special cases that can be written as ieee or
// standard types.
if (const VTypePrimitive*tmp = dynamic_cast<const VTypePrimitive*> (base_)) {
if (start_==0 && end_==INT64_MAX && tmp->type()==VTypePrimitive::INTEGER) {
if (tmp->type()==VTypePrimitive::NATURAL) {
fd << "natural";
return;
}