Add support for constants and package types.
Significant rework of scope management to unify the handling of types in the ieee library and types/constants/components in packages. This involved adjusting the parser rules to manage a stack of scopes and rewriting the IEEE library support to not use global maps for the loaded types.
This commit is contained in:
parent
303f057de1
commit
3ff7a8f7b0
|
|
@ -23,12 +23,10 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
Architecture::Architecture(perm_string name, map<perm_string,Signal*>&sigs,
|
||||
map<perm_string,ComponentBase*>&comps,
|
||||
Architecture::Architecture(perm_string name, const ScopeBase&ref,
|
||||
list<Architecture::Statement*>&s)
|
||||
: Scope(comps), name_(name)
|
||||
: Scope(ref), name_(name)
|
||||
{
|
||||
signals_ = sigs;
|
||||
statements_.splice(statements_.end(), s);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,8 +60,7 @@ class Architecture : public Scope, public LineInfo {
|
|||
public:
|
||||
// Create an architecture from its name and its statements.
|
||||
// NOTE: The statement list passed in is emptied.
|
||||
Architecture(perm_string name, std::map<perm_string,Signal*>&sigs,
|
||||
std::map<perm_string,ComponentBase*>&comps,
|
||||
Architecture(perm_string name, const ScopeBase&ref,
|
||||
std::list<Architecture::Statement*>&s);
|
||||
~Architecture();
|
||||
|
||||
|
|
@ -81,8 +80,6 @@ class Architecture : public Scope, public LineInfo {
|
|||
|
||||
private:
|
||||
perm_string name_;
|
||||
// Signals declared local to this architecture
|
||||
std::map<perm_string,Signal*> signals_;
|
||||
// Concurrent statements local to this architecture
|
||||
std::list<Architecture::Statement*> statements_;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,16 +25,33 @@
|
|||
# include <typeinfo>
|
||||
# include <cassert>
|
||||
|
||||
int Architecture::emit(ostream&out, Entity*entity)
|
||||
int Scope::emit_signals(ostream&out, Entity*entity, Architecture*arc)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
for (map<perm_string,Signal*>::iterator cur = signals_.begin()
|
||||
; cur != signals_.end() ; ++cur) {
|
||||
|
||||
errors += cur->second->emit(out, entity, this);
|
||||
errors += cur->second->emit(out, entity, arc);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int Architecture::emit(ostream&out, Entity*entity)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
for (map<perm_string,struct const_t>::iterator cur = constants_.begin()
|
||||
; cur != constants_.end() ; ++cur) {
|
||||
|
||||
out << "localparam " << cur->first << " = ";
|
||||
errors += cur->second.val->emit(out, entity, this);
|
||||
out << ";" << endl;
|
||||
}
|
||||
|
||||
errors += emit_signals(out, entity, this);
|
||||
|
||||
for (list<Architecture::Statement*>::iterator cur = statements_.begin()
|
||||
; cur != statements_.end() ; ++cur) {
|
||||
|
||||
|
|
|
|||
|
|
@ -46,9 +46,8 @@ static ostream& operator << (ostream&out, port_mode_t that)
|
|||
return out;
|
||||
}
|
||||
|
||||
void dump_design_entities(const char*path)
|
||||
void dump_design_entities(ostream&file)
|
||||
{
|
||||
ofstream file (path);
|
||||
for (map<perm_string,Entity*>::iterator cur = design_entities.begin()
|
||||
; cur != design_entities.end() ; ++cur) {
|
||||
cur->second->dump(file);
|
||||
|
|
@ -78,6 +77,30 @@ void ComponentBase::dump_ports(ostream&out, int indent) const
|
|||
|
||||
void Scope::dump_scope(ostream&out) const
|
||||
{
|
||||
// Dump types
|
||||
for (map<perm_string,const VType*>::const_iterator cur = types_.begin()
|
||||
; cur != types_.end() ; ++cur) {
|
||||
out << " " << cur->first << ": ";
|
||||
cur->second->show(out);
|
||||
out << endl;
|
||||
}
|
||||
|
||||
// Dump constants
|
||||
for (map<perm_string,const_t>::const_iterator cur = constants_.begin()
|
||||
; cur != constants_.end() ; ++cur) {
|
||||
out << " constant " << cur->first << " = ";
|
||||
out << endl;
|
||||
}
|
||||
|
||||
// Dump signal declarations
|
||||
for (map<perm_string,Signal*>::const_iterator cur = signals_.begin()
|
||||
; cur != signals_.end() ; ++cur) {
|
||||
if (cur->second)
|
||||
cur->second->dump(out, 3);
|
||||
else
|
||||
out << " signal " << cur->first.str() << ": ???" << endl;
|
||||
}
|
||||
|
||||
// Dump component declarations
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = components_.begin()
|
||||
; cur != components_.end() ; ++cur) {
|
||||
|
|
@ -105,12 +128,6 @@ void Architecture::dump(ostream&out, perm_string of_entity, int indent) const
|
|||
<< " of entity " << of_entity
|
||||
<< " file=" << get_fileline() << endl;
|
||||
|
||||
// Dump signal declarations
|
||||
for (map<perm_string,Signal*>::const_iterator cur = signals_.begin()
|
||||
; cur != signals_.end() ; ++cur) {
|
||||
cur->second->dump(out, indent+3);
|
||||
}
|
||||
|
||||
dump_scope(out);
|
||||
|
||||
for (list<Architecture::Statement*>::const_iterator cur = statements_.begin()
|
||||
|
|
@ -126,7 +143,12 @@ void Architecture::Statement::dump(ostream&out, int indent) const
|
|||
|
||||
void Signal::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "signal " << name_ << " is " << *type_ << endl;
|
||||
out << setw(indent) << "" << "signal " << name_ << " is ";
|
||||
if (type_)
|
||||
out << *type_;
|
||||
else
|
||||
out << "?NO TYPE?";
|
||||
out << endl;
|
||||
}
|
||||
|
||||
void SignalAssignment::dump(ostream&out, int indent) const
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
# include <map>
|
||||
# include <list>
|
||||
# include <vector>
|
||||
# include <iostream>
|
||||
# include "StringHeap.h"
|
||||
# include "LineInfo.h"
|
||||
# include "vtype.h"
|
||||
|
|
@ -123,6 +124,6 @@ extern int emit_entities(void);
|
|||
* Use this function to dump a description of the design entities to a
|
||||
* file. This is for debug, not for any useful purpose.
|
||||
*/
|
||||
extern void dump_design_entities(const char*path);
|
||||
extern void dump_design_entities(ostream&file);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,7 +17,11 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "expression.h"
|
||||
# include "expression.h"
|
||||
# include "scope.h"
|
||||
# include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
Expression::Expression()
|
||||
{
|
||||
|
|
@ -27,7 +31,7 @@ Expression::~Expression()
|
|||
{
|
||||
}
|
||||
|
||||
bool Expression::evaluate(int64_t&) const
|
||||
bool Expression::evaluate(ScopeBase*, int64_t&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -43,6 +47,16 @@ ExpBinary::~ExpBinary()
|
|||
delete operand2_;
|
||||
}
|
||||
|
||||
bool ExpBinary::eval_operand1(ScopeBase*scope, int64_t&val) const
|
||||
{
|
||||
return operand1_->evaluate(scope, val);
|
||||
}
|
||||
|
||||
bool ExpBinary::eval_operand2(ScopeBase*scope, int64_t&val) const
|
||||
{
|
||||
return operand2_->evaluate(scope, val);
|
||||
}
|
||||
|
||||
ExpUnary::ExpUnary(Expression*op1)
|
||||
: operand1_(op1)
|
||||
{
|
||||
|
|
@ -62,6 +76,48 @@ ExpArithmetic::~ExpArithmetic()
|
|||
{
|
||||
}
|
||||
|
||||
bool ExpArithmetic::evaluate(ScopeBase*scope, int64_t&val) const
|
||||
{
|
||||
int64_t val1, val2;
|
||||
bool rc;
|
||||
|
||||
rc = eval_operand1(scope, val1);
|
||||
if (rc == false)
|
||||
return false;
|
||||
|
||||
rc = eval_operand2(scope, val2);
|
||||
if (rc == false)
|
||||
return false;
|
||||
|
||||
switch (fun_) {
|
||||
case PLUS:
|
||||
val = val1 + val2;
|
||||
break;
|
||||
case MINUS:
|
||||
val = val1 - val2;
|
||||
break;
|
||||
case MULT:
|
||||
val = val1 * val2;
|
||||
break;
|
||||
case DIV:
|
||||
if (val2 == 0)
|
||||
return false;
|
||||
val = val1 / val2;
|
||||
break;
|
||||
case MOD:
|
||||
if (val2 == 0)
|
||||
return false;
|
||||
val = val1 % val2;
|
||||
break;
|
||||
case REM:
|
||||
return false;
|
||||
case POW:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ExpInteger::ExpInteger(int64_t val)
|
||||
: value_(val)
|
||||
{
|
||||
|
|
@ -71,7 +127,7 @@ ExpInteger::~ExpInteger()
|
|||
{
|
||||
}
|
||||
|
||||
bool ExpInteger::evaluate(int64_t&val) const
|
||||
bool ExpInteger::evaluate(ScopeBase*, int64_t&val) const
|
||||
{
|
||||
val = value_;
|
||||
return true;
|
||||
|
|
@ -106,6 +162,20 @@ const char* ExpName::name() const
|
|||
return name_;
|
||||
}
|
||||
|
||||
bool ExpName::evaluate(ScopeBase*scope, int64_t&val) const
|
||||
{
|
||||
const VType*type;
|
||||
Expression*exp;
|
||||
|
||||
bool rc = scope->find_constant(name_, type, exp);
|
||||
if (rc == false) {
|
||||
cerr << "XXXX Unable to evaluate name " << name_ << "." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return exp->evaluate(scope, val);
|
||||
}
|
||||
|
||||
ExpUAbs::ExpUAbs(Expression*op1)
|
||||
: ExpUnary(op1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
class Entity;
|
||||
class Architecture;
|
||||
class ScopeBase;
|
||||
|
||||
/*
|
||||
* The Expression class represents parsed expressions from the parsed
|
||||
|
|
@ -46,7 +47,7 @@ class Expression : public LineInfo {
|
|||
// to constant literal values. Return true and set the val
|
||||
// argument if the evaluation works, or return false if it
|
||||
// cannot be done.
|
||||
virtual bool evaluate(int64_t&val) const;
|
||||
virtual bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
|
||||
// This method returns true if the drawn Verilog for this
|
||||
// expression is a primary. A containing expression can use
|
||||
|
|
@ -94,6 +95,9 @@ class ExpBinary : public Expression {
|
|||
int emit_operand1(ostream&out, Entity*ent, Architecture*arc);
|
||||
int emit_operand2(ostream&out, Entity*ent, Architecture*arc);
|
||||
|
||||
bool eval_operand1(ScopeBase*scope, int64_t&val) const;
|
||||
bool eval_operand2(ScopeBase*scope, int64_t&val) const;
|
||||
|
||||
void dump_operands(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
|
|
@ -111,6 +115,7 @@ class ExpArithmetic : public ExpBinary {
|
|||
~ExpArithmetic();
|
||||
|
||||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||
virtual bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
|
|
@ -125,7 +130,7 @@ class ExpInteger : public Expression {
|
|||
|
||||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||
bool is_primary(void) const;
|
||||
bool evaluate(int64_t&val) const;
|
||||
bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
|
||||
private:
|
||||
|
|
@ -162,6 +167,7 @@ class ExpName : public Expression {
|
|||
public: // Base methods
|
||||
int emit(ostream&out, Entity*ent, Architecture*arc);
|
||||
bool is_primary(void) const;
|
||||
bool evaluate(ScopeBase*scope, int64_t&val) const;
|
||||
void dump(ostream&out, int indent = 0) const;
|
||||
const char* name() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,38 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
|
||||
struct library_contents {
|
||||
map<perm_string,Package*> packages;
|
||||
};
|
||||
|
||||
static void import_ieee(void);
|
||||
static void import_ieee_use(ActiveScope*res, perm_string package, perm_string name);
|
||||
|
||||
static map<perm_string,struct library_contents> libraries;
|
||||
|
||||
static void dump_library_package(ostream&file, perm_string lname, perm_string pname, Package*pack)
|
||||
{
|
||||
file << "package " << lname << "." << pname << endl;
|
||||
pack->dump_scope(file);
|
||||
file << "end package " << lname << "." << pname << endl;
|
||||
}
|
||||
|
||||
static void dump_library_packages(ostream&file, perm_string lname, map<perm_string,Package*>packages)
|
||||
{
|
||||
for (map<perm_string,Package*>::iterator cur = packages.begin()
|
||||
; cur != packages.end() ; ++cur) {
|
||||
dump_library_package(file, lname, cur->first, cur->second);
|
||||
}
|
||||
}
|
||||
|
||||
void dump_libraries(ostream&file)
|
||||
{
|
||||
for (map<perm_string,struct library_contents>::iterator cur = libraries.begin()
|
||||
; cur != libraries.end() ; ++cur) {
|
||||
dump_library_packages(file, cur->first, cur->second.packages);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function saves a package into the named library. Create the
|
||||
* library if necessary.
|
||||
|
|
@ -60,7 +85,7 @@ void library_import(const YYLTYPE&loc, const std::list<perm_string>*names)
|
|||
}
|
||||
}
|
||||
|
||||
void library_use(const YYLTYPE&loc, struct library_results&res,
|
||||
void library_use(const YYLTYPE&loc, ActiveScope*res,
|
||||
const char*libname, const char*package, const char*name)
|
||||
{
|
||||
if (libname == 0) {
|
||||
|
|
@ -74,7 +99,7 @@ void library_use(const YYLTYPE&loc, struct library_results&res,
|
|||
|
||||
// Special case handling for the IEEE library.
|
||||
if (use_library == "ieee") {
|
||||
import_ieee_use(use_package, use_name);
|
||||
import_ieee_use(res, use_package, use_name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -91,15 +116,98 @@ void library_use(const YYLTYPE&loc, struct library_results&res,
|
|||
// results into the "res" members.
|
||||
|
||||
if (use_name == "all") {
|
||||
pack->collect_components(res.components);
|
||||
res->use_from(pack);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ComponentBase*cur = pack->find_component(use_name)) {
|
||||
res.components.push_back(cur);
|
||||
res->bind_name(use_name, cur);
|
||||
return;
|
||||
}
|
||||
|
||||
errormsg(loc, "No such name %s in package %s\n",
|
||||
use_name.str(), pack->name().str());
|
||||
}
|
||||
|
||||
static void import_ieee(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void import_ieee_use_std_logic_1164(ActiveScope*res, perm_string name)
|
||||
{
|
||||
bool all_flag = name=="all";
|
||||
|
||||
if (all_flag || name == "std_logic_vector") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
res->bind_name(perm_string::literal("std_logic_vector"),
|
||||
new VTypeArray(&primitive_STDLOGIC, dims, false));
|
||||
}
|
||||
}
|
||||
|
||||
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->bind_name(perm_string::literal("signed"),
|
||||
new VTypeArray(&primitive_STDLOGIC, dims, true));
|
||||
}
|
||||
if (all_flag || name == "unsigned") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
res->bind_name(perm_string::literal("unsigned"),
|
||||
new VTypeArray(&primitive_BIT, dims, false));
|
||||
}
|
||||
}
|
||||
|
||||
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->bind_name(perm_string::literal("signed"),
|
||||
new VTypeArray(&primitive_STDLOGIC, dims, true));
|
||||
}
|
||||
if (all_flag || name == "unsigned") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
res->bind_name(perm_string::literal("unsigned"),
|
||||
new VTypeArray(&primitive_STDLOGIC, dims, false));
|
||||
}
|
||||
}
|
||||
|
||||
static void import_ieee_use(ActiveScope*res, perm_string package, perm_string name)
|
||||
{
|
||||
if (package == "std_logic_1164") {
|
||||
import_ieee_use_std_logic_1164(res, name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (package == "numeric_bit") {
|
||||
import_ieee_use_numeric_bit(res, name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (package == "numeric_std") {
|
||||
import_ieee_use_numeric_std(res, name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const VTypePrimitive primitive_BOOLEAN (VTypePrimitive::BOOLEAN);
|
||||
const VTypePrimitive primitive_BIT (VTypePrimitive::BIT);
|
||||
const VTypePrimitive primitive_INTEGER (VTypePrimitive::INTEGER);
|
||||
const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC);
|
||||
|
||||
const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector<VTypeArray::range_t> (1));
|
||||
const VTypeArray primitive_BOOL_VECTOR(&primitive_BOOLEAN, vector<VTypeArray::range_t> (1));
|
||||
|
||||
void generate_global_types(ActiveScope*res)
|
||||
{
|
||||
res->bind_name(perm_string::literal("boolean"), &primitive_BOOLEAN);
|
||||
res->bind_name(perm_string::literal("bit"), &primitive_BIT);
|
||||
res->bind_name(perm_string::literal("integer"), &primitive_INTEGER);
|
||||
res->bind_name(perm_string::literal("std_logic"), &primitive_STDLOGIC);
|
||||
res->bind_name(perm_string::literal("bit_vector"),&primitive_BOOL_VECTOR);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ const char NOTICE[] =
|
|||
# include "compiler.h"
|
||||
# include "parse_api.h"
|
||||
# include "vtype.h"
|
||||
# include <fstream>
|
||||
# include <cstdio>
|
||||
# include <cstdlib>
|
||||
# include <cstring>
|
||||
|
|
@ -52,6 +53,9 @@ const char NOTICE[] =
|
|||
bool verbose_flag = false;
|
||||
// Where to dump design entities
|
||||
const char*dump_design_entities_path = 0;
|
||||
const char*dump_libraries_path = 0;
|
||||
|
||||
extern void dump_libraries(ostream&file);
|
||||
|
||||
static void process_debug_token(const char*word)
|
||||
{
|
||||
|
|
@ -61,6 +65,8 @@ static void process_debug_token(const char*word)
|
|||
yydebug = 0;
|
||||
} else if (strncmp(word, "entities=", 9) == 0) {
|
||||
dump_design_entities_path = strdup(word+9);
|
||||
} else if (strncmp(word, "libraries=", 10) == 0) {
|
||||
dump_libraries_path = strdup(word+10);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,8 +131,15 @@ int main(int argc, char*argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if (dump_design_entities_path)
|
||||
dump_design_entities(dump_design_entities_path);
|
||||
if (dump_libraries_path) {
|
||||
ofstream file(dump_libraries_path);
|
||||
dump_libraries(file);
|
||||
}
|
||||
|
||||
if (dump_design_entities_path) {
|
||||
ofstream file(dump_design_entities_path);
|
||||
dump_design_entities(file);
|
||||
}
|
||||
|
||||
if (errors > 0)
|
||||
return 2;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
# include "package.h"
|
||||
|
||||
Package::Package(perm_string n, map<perm_string,ComponentBase*>&comps)
|
||||
: Scope(comps), name_(n)
|
||||
Package::Package(perm_string n, const ScopeBase&ref)
|
||||
: Scope(ref), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
class Package : public Scope, public LineInfo {
|
||||
|
||||
public:
|
||||
Package(perm_string name, std::map<perm_string,ComponentBase*>&comps);
|
||||
Package(perm_string name, const ScopeBase&ref);
|
||||
~Package();
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
|
|
|
|||
180
vhdlpp/parse.y
180
vhdlpp/parse.y
|
|
@ -61,31 +61,46 @@ static void yyerror(const char*msg);
|
|||
int parse_errors = 0;
|
||||
int parse_sorrys = 0;
|
||||
|
||||
/*
|
||||
* This map accumulates signals that are matched in the declarations
|
||||
* section of a block. When the declarations are over, these are
|
||||
* transferred to a map for the block proper.
|
||||
*/
|
||||
static map<perm_string, Signal*> block_signals;
|
||||
|
||||
/*
|
||||
* This map accumulates component declarations. This variable is used
|
||||
* by rules that build up package, architectures, whatever objects
|
||||
* can contain component declarations.
|
||||
* Create an initial scope that collects all the global
|
||||
* declarations. Also save a stack of previous scopes, as a way to
|
||||
* manage lexical scopes.
|
||||
*/
|
||||
static map<perm_string, ComponentBase*> block_components;
|
||||
static ActiveScope*active_scope = new ActiveScope;
|
||||
static list<ActiveScope*> scope_stack;
|
||||
|
||||
/*
|
||||
* Calls to library_use return a collections of declation objects that
|
||||
* belong in the scope that is being worked on. This is a convenience
|
||||
* function for collecting those results into the parser variables.
|
||||
* When a scope boundary starts, call the push_scope function to push
|
||||
* a scope context. Preload this scope context with the contents of
|
||||
* the parent scope, then make this the current scope. When the scope
|
||||
* is done, the pop_scope function pops the scope off the stack and
|
||||
* resumes the scope that was the parent.
|
||||
*/
|
||||
static void collect_library_results(struct library_results&res)
|
||||
static void push_scope(void)
|
||||
{
|
||||
for (list<ComponentBase*>::iterator cur = res.components.begin()
|
||||
; cur != res.components.end() ; ++cur) {
|
||||
block_components[(*cur)->get_name()] = *cur;
|
||||
}
|
||||
assert(active_scope);
|
||||
scope_stack.push_front(active_scope);
|
||||
active_scope = new ActiveScope (active_scope);
|
||||
}
|
||||
|
||||
static void pop_scope(void)
|
||||
{
|
||||
delete active_scope;
|
||||
assert(scope_stack.size() > 0);
|
||||
active_scope = scope_stack.front();
|
||||
scope_stack.pop_front();
|
||||
}
|
||||
|
||||
|
||||
void preload_global_types(void)
|
||||
{
|
||||
generate_global_types(active_scope);
|
||||
}
|
||||
|
||||
const VType*parse_type_by_name(perm_string name)
|
||||
{
|
||||
return active_scope->find_type(name);
|
||||
}
|
||||
|
||||
%}
|
||||
|
|
@ -182,6 +197,7 @@ static void collect_library_results(struct library_results&res)
|
|||
|
||||
%type <vtype> subtype_indication
|
||||
|
||||
%type <text> architecture_body_start package_declaration_start
|
||||
%type <text> identifier_opt logical_name suffix
|
||||
%type <name_list> logical_name_list identifier_list
|
||||
%type <compound_name> prefix selected_name
|
||||
|
|
@ -193,33 +209,38 @@ static void collect_library_results(struct library_results&res)
|
|||
design_file : design_units ;
|
||||
|
||||
architecture_body
|
||||
: K_architecture IDENTIFIER
|
||||
: architecture_body_start
|
||||
K_of IDENTIFIER
|
||||
K_is block_declarative_items_opt
|
||||
K_begin architecture_statement_part K_end K_architecture_opt identifier_opt ';'
|
||||
{ Architecture*tmp = new Architecture(lex_strings.make($2),
|
||||
block_signals,
|
||||
block_components, *$8);
|
||||
{ Architecture*tmp = new Architecture(lex_strings.make($1),
|
||||
*active_scope, *$7);
|
||||
FILE_NAME(tmp, @1);
|
||||
bind_architecture_to_entity($4, tmp);
|
||||
if ($11 && tmp->get_name() != $11)
|
||||
errormsg(@2, "Architecture name doesn't match closing name.\n");
|
||||
delete[]$2;
|
||||
delete[]$4;
|
||||
delete $8;
|
||||
block_signals.clear();
|
||||
block_components.clear();
|
||||
if ($11) delete[]$11;
|
||||
bind_architecture_to_entity($3, tmp);
|
||||
if ($10 && tmp->get_name() != $10)
|
||||
errormsg(@1, "Architecture name doesn't match closing name.\n");
|
||||
delete[]$1;
|
||||
delete[]$3;
|
||||
delete $7;
|
||||
pop_scope();
|
||||
if ($10) delete[]$10;
|
||||
}
|
||||
| K_architecture IDENTIFIER
|
||||
| architecture_body_start
|
||||
K_of IDENTIFIER
|
||||
K_is block_declarative_items_opt
|
||||
K_begin error K_end K_architecture_opt identifier_opt ';'
|
||||
{ errormsg(@8, "Errors in architecture statements.\n"); yyerrok; }
|
||||
| K_architecture error ';'
|
||||
{ errormsg(@2, "Errors in architecture body.\n"); yyerrok; }
|
||||
{ errormsg(@8, "Errors in architecture statements.\n");
|
||||
yyerrok;
|
||||
pop_scope();
|
||||
}
|
||||
;
|
||||
|
||||
architecture_body_start
|
||||
: K_architecture IDENTIFIER
|
||||
{ $$ = $2;
|
||||
push_scope();
|
||||
}
|
||||
;
|
||||
/*
|
||||
* The architecture_statement_part is a list of concurrent
|
||||
* statements.
|
||||
|
|
@ -298,13 +319,15 @@ block_declarative_item
|
|||
; cur != $2->end() ; ++cur) {
|
||||
Signal*sig = new Signal(*cur, $4);
|
||||
FILE_NAME(sig, @1);
|
||||
block_signals[*cur] = sig;
|
||||
active_scope->bind_name(*cur, sig);
|
||||
}
|
||||
delete $2;
|
||||
}
|
||||
|
||||
| component_declaration
|
||||
|
||||
| constant_declaration
|
||||
{ sorrymsg(@1, "constant declarations not supported here.\n"); }
|
||||
| use_clause_lib
|
||||
|
||||
/* Various error handling rules for block_declarative_item... */
|
||||
|
|
@ -360,7 +383,7 @@ component_declaration
|
|||
|
||||
ComponentBase*comp = new ComponentBase(name);
|
||||
if ($4) comp->set_interface($4);
|
||||
block_components[name] = comp;
|
||||
active_scope->bind_name(name, comp);
|
||||
delete[]$2;
|
||||
if ($7) delete[] $7;
|
||||
}
|
||||
|
|
@ -470,6 +493,21 @@ configuration_items_opt
|
|||
|
|
||||
;
|
||||
|
||||
constant_declaration
|
||||
: K_constant identifier_list ':' subtype_indication VASSIGN expression ';'
|
||||
{ // The syntax allows mutliple names to have the same type/value.
|
||||
for (std::list<perm_string>::iterator cur = $2->begin()
|
||||
; cur != $2->end() ; ++cur) {
|
||||
active_scope->bind_name(*cur, $4, $6);
|
||||
}
|
||||
delete $2;
|
||||
}
|
||||
| K_constant identifier_list ':' subtype_indication ';'
|
||||
{ sorrymsg(@1, "Deferred constant declarations not supported\n");
|
||||
delete $2;
|
||||
}
|
||||
;
|
||||
|
||||
context_clause : context_items | ;
|
||||
|
||||
context_item
|
||||
|
|
@ -807,28 +845,36 @@ name
|
|||
;
|
||||
|
||||
package_declaration
|
||||
: K_package IDENTIFIER K_is
|
||||
: package_declaration_start K_is
|
||||
package_declarative_part_opt
|
||||
K_end K_package_opt identifier_opt ';'
|
||||
{ perm_string name = lex_strings.make($2);
|
||||
if($7 && name != $7) {
|
||||
{ perm_string name = lex_strings.make($1);
|
||||
if($6 && name != $6) {
|
||||
errormsg(@1, "Identifier %s doesn't match package name %s.\n",
|
||||
$7, name.str());
|
||||
$6, name.str());
|
||||
}
|
||||
Package*tmp = new Package(name, block_components);
|
||||
Package*tmp = new Package(name, *active_scope);
|
||||
FILE_NAME(tmp, @1);
|
||||
delete[]$2;
|
||||
if ($7) delete[]$7;
|
||||
block_components.clear();
|
||||
delete[]$1;
|
||||
if ($6) delete[]$6;
|
||||
pop_scope();
|
||||
/* Put this package into the work library. */
|
||||
library_save_package(0, tmp);
|
||||
}
|
||||
| K_package IDENTIFIER K_is error K_end K_package_opt identifier_opt ';'
|
||||
{ errormsg(@4, "Syntax error in package clause.\n");
|
||||
| package_declaration_start K_is error K_end K_package_opt identifier_opt ';'
|
||||
{ errormsg(@3, "Syntax error in package clause.\n");
|
||||
yyerrok;
|
||||
pop_scope();
|
||||
}
|
||||
;
|
||||
|
||||
package_declaration_start
|
||||
: K_package IDENTIFIER
|
||||
{ push_scope();
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
/* TODO: this list must be extended in the future
|
||||
presently it is only a sketch */
|
||||
package_body_declarative_item
|
||||
|
|
@ -846,6 +892,8 @@ package_body_declarative_part_opt
|
|||
|
||||
package_declarative_item
|
||||
: component_declaration
|
||||
| constant_declaration
|
||||
| subtype_declaration
|
||||
| use_clause
|
||||
;
|
||||
|
||||
|
|
@ -980,22 +1028,16 @@ selected_names
|
|||
rules, but is a convenient place to attach use_clause actions. */
|
||||
selected_name_use
|
||||
: IDENTIFIER '.' K_all
|
||||
{ struct library_results res;
|
||||
library_use(@1, res, 0, $1, 0);
|
||||
collect_library_results(res);
|
||||
{ library_use(@1, active_scope, 0, $1, 0);
|
||||
delete[]$1;
|
||||
}
|
||||
| IDENTIFIER '.' IDENTIFIER '.' K_all
|
||||
{ struct library_results res;
|
||||
library_use(@1, res, $1, $3, 0);
|
||||
collect_library_results(res);
|
||||
{ library_use(@1, active_scope, $1, $3, 0);
|
||||
delete[]$1;
|
||||
delete[]$3;
|
||||
}
|
||||
| IDENTIFIER '.' IDENTIFIER '.' IDENTIFIER
|
||||
{ struct library_results res;
|
||||
library_use(@1, res, $1, $3, $5);
|
||||
collect_library_results(res);
|
||||
{ library_use(@1, active_scope, $1, $3, $5);
|
||||
delete[]$1;
|
||||
delete[]$3;
|
||||
delete[]$5;
|
||||
|
|
@ -1024,14 +1066,36 @@ simple_expression
|
|||
}
|
||||
;
|
||||
|
||||
subtype_declaration
|
||||
: K_subtype IDENTIFIER K_is subtype_indication ';'
|
||||
{ perm_string name = lex_strings.make($2);
|
||||
if ($4 == 0) {
|
||||
errormsg(@1, "Failed to declare type name %s.\n", name.str());
|
||||
} else {
|
||||
active_scope->bind_name(name, $4);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
subtype_indication
|
||||
: IDENTIFIER
|
||||
{ const VType*tmp = global_types[lex_strings.make($1)];
|
||||
{ const VType*tmp = parse_type_by_name(lex_strings.make($1));
|
||||
delete[]$1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| IDENTIFIER '(' simple_expression direction simple_expression ')'
|
||||
{ const VType*tmp = calculate_subtype($1, $3, $4, $5);
|
||||
{ const VType*tmp = calculate_subtype_array(@1, $1, active_scope, $3, $4, $5);
|
||||
if (tmp == 0) {
|
||||
errormsg(@1, "Unable to calculate bounds for array of %s.\n", $1);
|
||||
}
|
||||
delete[]$1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| IDENTIFIER K_range simple_expression direction simple_expression
|
||||
{ const VType*tmp = calculate_subtype_range(@1, $1, active_scope, $3, $4, $5);
|
||||
if (tmp == 0) {
|
||||
errormsg(@1, "Unable to calculate bounds for range of %s.\n", $1);
|
||||
}
|
||||
delete[]$1;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,12 +54,18 @@ void bind_architecture_to_entity(const char*ename, Architecture*arch)
|
|||
}
|
||||
}
|
||||
|
||||
const VType* calculate_subtype(const char*base_name,
|
||||
Expression*array_left,
|
||||
bool downto,
|
||||
Expression*array_right)
|
||||
const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name,
|
||||
ScopeBase*scope,
|
||||
Expression*array_left,
|
||||
bool downto,
|
||||
Expression*array_right)
|
||||
{
|
||||
const VType*base_type = global_types[lex_strings.make(base_name)];
|
||||
const VType*base_type = parse_type_by_name(lex_strings.make(base_name));
|
||||
|
||||
if (base_type == 0) {
|
||||
errormsg(loc, "Unable to find base type %s of array.\n", base_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(array_left==0 || array_right!=0);
|
||||
|
||||
|
|
@ -74,11 +80,13 @@ const VType* calculate_subtype(const char*base_name,
|
|||
|
||||
int64_t left_val;
|
||||
int64_t right_val;
|
||||
bool rc = array_left->evaluate(left_val);
|
||||
assert(rc);
|
||||
bool rc = array_left->evaluate(scope, left_val);
|
||||
if (rc == false)
|
||||
return 0;
|
||||
|
||||
rc = array_right->evaluate(right_val);
|
||||
assert(rc);
|
||||
rc = array_right->evaluate(scope, right_val);
|
||||
if (rc == false)
|
||||
return 0;
|
||||
|
||||
range[0] = VTypeArray::range_t(left_val, right_val);
|
||||
|
||||
|
|
@ -88,3 +96,32 @@ const VType* calculate_subtype(const char*base_name,
|
|||
|
||||
return base_type;
|
||||
}
|
||||
|
||||
const VType* calculate_subtype_range(const YYLTYPE&loc, const char*base_name,
|
||||
ScopeBase*scope,
|
||||
Expression*range_left,
|
||||
bool downto,
|
||||
Expression*range_right)
|
||||
{
|
||||
const VType*base_type = parse_type_by_name(lex_strings.make(base_name));
|
||||
|
||||
if (base_type == 0) {
|
||||
errormsg(loc, "Unable to find base type %s of range.\n", base_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(range_left && range_right);
|
||||
|
||||
int64_t left_val, right_val;
|
||||
bool rc = range_left->evaluate(scope, left_val);
|
||||
if (rc == false)
|
||||
return 0;
|
||||
|
||||
rc = range_right->evaluate(scope, right_val);
|
||||
if (rc == false)
|
||||
return 0;
|
||||
|
||||
VTypeRange*sub_type = new VTypeRange(base_type, left_val, right_val);
|
||||
|
||||
return sub_type;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,31 +21,38 @@
|
|||
|
||||
# include "parse_api.h"
|
||||
|
||||
class ActiveScope;
|
||||
class Architecture;
|
||||
class Expression;
|
||||
class Package;
|
||||
class ScopeBase;
|
||||
class VType;
|
||||
|
||||
extern void bind_architecture_to_entity(const char*ename, Architecture*arch);
|
||||
|
||||
extern const VType* calculate_subtype(const char*base_name,
|
||||
Expression*array_left,
|
||||
bool downto,
|
||||
Expression*array_right);
|
||||
extern const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name,
|
||||
ScopeBase*scope,
|
||||
Expression*array_left,
|
||||
bool downto,
|
||||
Expression*array_right);
|
||||
extern const VType* calculate_subtype_range(const YYLTYPE&loc, const char*base_name,
|
||||
ScopeBase*scope,
|
||||
Expression*range_left,
|
||||
bool downto,
|
||||
Expression*range_right);
|
||||
|
||||
/*
|
||||
* This function searches the currently active scope, or the global
|
||||
* scope, for the named type.
|
||||
*/
|
||||
extern const VType* parse_type_by_name(perm_string name);
|
||||
|
||||
extern void library_save_package(const char*libname, Package*pack);
|
||||
|
||||
extern void library_import(const YYLTYPE&loc, const std::list<perm_string>*names);
|
||||
|
||||
struct library_results {
|
||||
std::list<ComponentBase*> components;
|
||||
std::list<const VType*> types;
|
||||
extern void library_use(const YYLTYPE&loc, ActiveScope*res, const char*libname, const char*pack, const char*ident);
|
||||
|
||||
void clear() {
|
||||
components.clear();
|
||||
types.clear();
|
||||
}
|
||||
};
|
||||
extern void generate_global_types(ActiveScope*res);
|
||||
|
||||
extern void library_use(const YYLTYPE&loc, struct library_results&res, const char*libname, const char*pack, const char*ident);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,12 +18,67 @@
|
|||
*/
|
||||
|
||||
# include "scope.h"
|
||||
# include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
Scope::Scope(map<perm_string,ComponentBase*>&comps)
|
||||
ScopeBase::ScopeBase(const ScopeBase&ref)
|
||||
{
|
||||
constants_ = ref.constants_;
|
||||
signals_ = ref.signals_;
|
||||
components_ = ref.components_;
|
||||
types_ = ref.types_;
|
||||
}
|
||||
|
||||
ScopeBase::~ScopeBase()
|
||||
{
|
||||
}
|
||||
|
||||
const VType*ScopeBase::find_type(perm_string by_name)
|
||||
{
|
||||
map<perm_string,const VType*>::const_iterator cur = types_.find(by_name);
|
||||
if (cur == types_.end())
|
||||
return 0;
|
||||
else
|
||||
return cur->second;
|
||||
}
|
||||
|
||||
bool ScopeBase::find_constant(perm_string by_name, const VType*&typ, Expression*&exp)
|
||||
{
|
||||
map<perm_string,const_t>::const_iterator cur = constants_.find(by_name);
|
||||
if (cur == constants_.end())
|
||||
return false;
|
||||
|
||||
typ = cur->second.typ;
|
||||
exp = cur->second.val;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScopeBase::do_use_from(const ScopeBase*that)
|
||||
{
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = that->components_.begin()
|
||||
; cur != that->components_.end() ; ++ cur) {
|
||||
if (cur->second == 0)
|
||||
continue;
|
||||
components_[cur->first] = cur->second;
|
||||
}
|
||||
|
||||
for (map<perm_string,const VType*>::const_iterator cur = that->types_.begin()
|
||||
; cur != that->types_.end() ; ++ cur) {
|
||||
if (cur->second == 0)
|
||||
continue;
|
||||
types_[cur->first] = cur->second;
|
||||
}
|
||||
|
||||
for (map<perm_string,const_t>::const_iterator cur = that->constants_.begin()
|
||||
; cur != that->constants_.end() ; ++ cur) {
|
||||
constants_[cur->first] = cur->second;
|
||||
}
|
||||
}
|
||||
|
||||
Scope::Scope(const ScopeBase&ref)
|
||||
: ScopeBase(ref)
|
||||
{
|
||||
components_ = comps;
|
||||
}
|
||||
|
||||
Scope::~Scope()
|
||||
|
|
@ -38,13 +93,3 @@ ComponentBase* Scope::find_component(perm_string by_name)
|
|||
else
|
||||
return cur->second;
|
||||
}
|
||||
|
||||
void Scope::collect_components(list<ComponentBase*>&res)
|
||||
{
|
||||
for (map<perm_string,ComponentBase*>::const_iterator cur = components_.begin()
|
||||
; cur != components_.end() ; ++cur) {
|
||||
if (cur->second == 0)
|
||||
continue;
|
||||
res.push_back(cur->second);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,26 +23,86 @@
|
|||
# include <map>
|
||||
# include "StringHeap.h"
|
||||
|
||||
class Architecture;
|
||||
class ComponentBase;
|
||||
class Entity;
|
||||
class Expression;
|
||||
class Signal;
|
||||
class VType;
|
||||
|
||||
class Scope {
|
||||
class ScopeBase {
|
||||
|
||||
public:
|
||||
Scope(std::map<perm_string,ComponentBase*>&comps);
|
||||
~Scope();
|
||||
ScopeBase() { }
|
||||
explicit ScopeBase(const ScopeBase&ref);
|
||||
virtual ~ScopeBase() =0;
|
||||
|
||||
ComponentBase* find_component(perm_string by_name);
|
||||
|
||||
void collect_components(std::list<ComponentBase*>&res);
|
||||
|
||||
void dump_scope(ostream&out) const;
|
||||
|
||||
private:
|
||||
const VType* find_type(perm_string by_name);
|
||||
bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp);
|
||||
protected:
|
||||
// Signal declarations...
|
||||
std::map<perm_string,Signal*> signals_;
|
||||
// Component declarations...
|
||||
std::map<perm_string,ComponentBase*> components_;
|
||||
// Type declarations...
|
||||
std::map<perm_string,const VType*> types_;
|
||||
// Constant declarations...
|
||||
struct const_t {
|
||||
const VType*typ;
|
||||
Expression*val;
|
||||
};
|
||||
std::map<perm_string, struct const_t> constants_;
|
||||
|
||||
void do_use_from(const ScopeBase*that);
|
||||
};
|
||||
|
||||
class Scope : public ScopeBase {
|
||||
|
||||
public:
|
||||
Scope(const ScopeBase&ref);
|
||||
~Scope();
|
||||
|
||||
ComponentBase* find_component(perm_string by_name);
|
||||
|
||||
public:
|
||||
void dump_scope(ostream&out) const;
|
||||
|
||||
protected:
|
||||
// Helper method for emitting signals in the scope.
|
||||
int emit_signals(ostream&out, Entity*ent, Architecture*arc);
|
||||
};
|
||||
|
||||
/*
|
||||
* The active_scope object accumulates declarations for the scope that
|
||||
* is in the process of being parsed. When the declarations are over,
|
||||
* they are transferred over to the specific scope. The ActiveScope is
|
||||
* used by the parser to build up scopes.
|
||||
*/
|
||||
class ActiveScope : public ScopeBase {
|
||||
|
||||
public:
|
||||
ActiveScope() { }
|
||||
ActiveScope(ActiveScope*par) : ScopeBase(*par) { }
|
||||
|
||||
~ActiveScope() { }
|
||||
|
||||
void use_from(const ScopeBase*that) { do_use_from(that); }
|
||||
|
||||
void bind_name(perm_string name, Signal*obj)
|
||||
{ signals_[name] = obj; }
|
||||
|
||||
void bind_name(perm_string name, ComponentBase*obj)
|
||||
{ components_[name] = obj; }
|
||||
|
||||
void bind_name(perm_string name, const VType*obj)
|
||||
{ types_[name] = obj; }
|
||||
|
||||
void bind_name(perm_string name, const VType*obj, Expression*val)
|
||||
{
|
||||
const_t&tmp = constants_[name];
|
||||
tmp.typ = obj;
|
||||
tmp.val = val;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,88 +18,11 @@
|
|||
*/
|
||||
|
||||
# include "vtype.h"
|
||||
# include <map>
|
||||
# include <typeinfo>
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::map<perm_string, const VType*> global_types;
|
||||
|
||||
const VTypePrimitive primitive_BOOLEAN (VTypePrimitive::BOOLEAN);
|
||||
const VTypePrimitive primitive_BIT (VTypePrimitive::BIT);;
|
||||
const VTypePrimitive primitive_INTEGER (VTypePrimitive::INTEGER);;
|
||||
const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC);;
|
||||
|
||||
const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector<VTypeArray::range_t> (1));
|
||||
const VTypeArray primitive_BOOL_VECTOR(&primitive_BOOLEAN, vector<VTypeArray::range_t> (1));
|
||||
|
||||
void preload_global_types(void)
|
||||
{
|
||||
global_types[perm_string::literal("boolean")] = &primitive_BOOLEAN;
|
||||
global_types[perm_string::literal("bit")] = &primitive_BIT;
|
||||
global_types[perm_string::literal("integer")] = &primitive_INTEGER;
|
||||
global_types[perm_string::literal("std_logic")] = &primitive_STDLOGIC;
|
||||
global_types[perm_string::literal("bit_vector")]= &primitive_BOOL_VECTOR;
|
||||
}
|
||||
|
||||
void import_ieee(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void import_ieee_use_std_logic_1164(perm_string name)
|
||||
{
|
||||
bool all_flag = name=="all";
|
||||
|
||||
if (all_flag || name == "std_logic_vector") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
global_types[perm_string::literal("std_logic_vector")] = new VTypeArray(&primitive_STDLOGIC, dims, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void import_ieee_use_numeric_bit(perm_string name)
|
||||
{
|
||||
bool all_flag = name=="all";
|
||||
|
||||
if (all_flag || name == "signed") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
global_types[perm_string::literal("signed")] = new VTypeArray(&primitive_STDLOGIC, dims, true);
|
||||
}
|
||||
if (all_flag || name == "unsigned") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
global_types[perm_string::literal("unsigned")] = new VTypeArray(&primitive_BIT, dims, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void import_ieee_use_numeric_std(perm_string name)
|
||||
{
|
||||
bool all_flag = name=="all";
|
||||
|
||||
if (all_flag || name == "signed") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
global_types[perm_string::literal("signed")] = new VTypeArray(&primitive_STDLOGIC, dims, true);
|
||||
}
|
||||
if (all_flag || name == "unsigned") {
|
||||
vector<VTypeArray::range_t> dims (1);
|
||||
global_types[perm_string::literal("unsigned")] = new VTypeArray(&primitive_STDLOGIC, dims, false);
|
||||
}
|
||||
}
|
||||
|
||||
void import_ieee_use(perm_string package, perm_string name)
|
||||
{
|
||||
if (package == "std_logic_1164") {
|
||||
import_ieee_use_std_logic_1164(name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (package == "numeric_bit") {
|
||||
import_ieee_use_numeric_bit(name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (package == "numeric_std") {
|
||||
import_ieee_use_numeric_std(name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
VType::~VType()
|
||||
{
|
||||
|
|
@ -171,3 +94,14 @@ void VTypeArray::show(ostream&out) const
|
|||
else
|
||||
out << "<nil>";
|
||||
}
|
||||
|
||||
VTypeRange::VTypeRange(const VType*base, int64_t max_val, int64_t min_val)
|
||||
: base_(base)
|
||||
{
|
||||
max_ = max_val;
|
||||
min_ = min_val;
|
||||
}
|
||||
|
||||
VTypeRange::~VTypeRange()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@
|
|||
*/
|
||||
|
||||
# include <iostream>
|
||||
# include <map>
|
||||
# include <vector>
|
||||
# include <climits>
|
||||
# include <inttypes.h>
|
||||
# include "StringHeap.h"
|
||||
|
||||
/*
|
||||
|
|
@ -58,18 +58,8 @@ inline std::ostream&operator << (std::ostream&out, const VType&item)
|
|||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
* The global_types variable maps type names to a type
|
||||
* definition. This is after the "use" statements bring in the types
|
||||
* in included packages.
|
||||
*/
|
||||
extern std::map<perm_string, const VType*> global_types;
|
||||
|
||||
extern void preload_global_types(void);
|
||||
|
||||
extern void import_ieee(void);
|
||||
extern void import_ieee_use(perm_string package, perm_string name);
|
||||
|
||||
/*
|
||||
* This class represents the primative types that are available to the
|
||||
* type subsystem.
|
||||
|
|
@ -143,4 +133,17 @@ class VTypeArray : public VType {
|
|||
bool signed_flag_;
|
||||
};
|
||||
|
||||
class VTypeRange : public VType {
|
||||
|
||||
public:
|
||||
VTypeRange(const VType*base, int64_t max_val, int64_t min_val);
|
||||
~VTypeRange();
|
||||
|
||||
virtual void elaborate(decl_t&decl) const;
|
||||
|
||||
private:
|
||||
const VType*base_;
|
||||
int64_t max_, min_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -58,3 +58,8 @@ void VTypePrimitive::elaborate(VType::decl_t&decl) const
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VTypeRange::elaborate(VType::decl_t&decl) const
|
||||
{
|
||||
base_->elaborate(decl);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue