Support converting bit strings to std_logic
This commit is contained in:
parent
1e4b96aa0a
commit
fbf85398da
|
|
@ -47,6 +47,14 @@ static vhdl_expr *translate_signal(ivl_expr_t e)
|
||||||
return new vhdl_var_ref(ivl_signal_basename(sig), type);
|
return new vhdl_var_ref(ivl_signal_basename(sig), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A numeric literal ends up as std_logic bit string.
|
||||||
|
*/
|
||||||
|
static vhdl_expr *translate_number(ivl_expr_t e)
|
||||||
|
{
|
||||||
|
return new vhdl_const_bits(ivl_expr_bits(e));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate a VHDL expression from a Verilog expression.
|
* Generate a VHDL expression from a Verilog expression.
|
||||||
*/
|
*/
|
||||||
|
|
@ -59,6 +67,8 @@ vhdl_expr *translate_expr(ivl_expr_t e)
|
||||||
return translate_string(e);
|
return translate_string(e);
|
||||||
case IVL_EX_SIGNAL:
|
case IVL_EX_SIGNAL:
|
||||||
return translate_signal(e);
|
return translate_signal(e);
|
||||||
|
case IVL_EX_NUMBER:
|
||||||
|
return translate_number(e);
|
||||||
default:
|
default:
|
||||||
error("No VHDL translation for expression at %s:%d (type = %d)",
|
error("No VHDL translation for expression at %s:%d (type = %d)",
|
||||||
ivl_expr_file(e), ivl_expr_lineno(e), type);
|
ivl_expr_file(e), ivl_expr_lineno(e), type);
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,15 @@ static void declare_signals(vhdl_arch *arch, ivl_scope_t scope)
|
||||||
int nsigs = ivl_scope_sigs(scope);
|
int nsigs = ivl_scope_sigs(scope);
|
||||||
for (int i = 0; i < nsigs; i++) {
|
for (int i = 0; i < nsigs; i++) {
|
||||||
ivl_signal_t sig = ivl_scope_sig(scope, i);
|
ivl_signal_t sig = ivl_scope_sig(scope, i);
|
||||||
vhdl_scalar_type *std_logic =
|
|
||||||
new vhdl_scalar_type("std_logic");
|
int width = ivl_signal_width(sig);
|
||||||
|
vhdl_type *sig_type;
|
||||||
|
if (width > 0)
|
||||||
|
sig_type = vhdl_scalar_type::std_logic();
|
||||||
|
else
|
||||||
|
sig_type = vhdl_vector_type::std_logic_vector(width-1, 0);
|
||||||
vhdl_signal_decl *decl =
|
vhdl_signal_decl *decl =
|
||||||
new vhdl_signal_decl(ivl_signal_basename(sig), std_logic);
|
new vhdl_signal_decl(ivl_signal_basename(sig), sig_type);
|
||||||
arch->add_decl(decl);
|
arch->add_decl(decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,11 @@ static int draw_nbassign(vhdl_process *proc, ivl_statement_t stmt)
|
||||||
if ((sig = ivl_lval_sig(lval))) {
|
if ((sig = ivl_lval_sig(lval))) {
|
||||||
const char *signame = ivl_signal_basename(sig);
|
const char *signame = ivl_signal_basename(sig);
|
||||||
|
|
||||||
vhdl_expr *rhs = translate_expr(ivl_stmt_rval(stmt));
|
vhdl_decl *decl = proc->get_parent()->get_decl(signame);
|
||||||
|
assert(decl);
|
||||||
|
|
||||||
|
vhdl_expr *rhs =
|
||||||
|
decl->get_type()->cast(translate_expr(ivl_stmt_rval(stmt)));
|
||||||
if (NULL == rhs)
|
if (NULL == rhs)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
@ -343,15 +344,6 @@ void vhdl_wait_stmt::emit(std::ofstream &of, int level) const
|
||||||
of << "wait;";
|
of << "wait;";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a deep copy of this type, so it can appear in more
|
|
||||||
* than one place in the AST.
|
|
||||||
*/
|
|
||||||
vhdl_type *vhdl_scalar_type::clone() const
|
|
||||||
{
|
|
||||||
return new vhdl_scalar_type(name_.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
vhdl_scalar_type *vhdl_scalar_type::std_logic()
|
vhdl_scalar_type *vhdl_scalar_type::std_logic()
|
||||||
{
|
{
|
||||||
return new vhdl_scalar_type("std_logic");
|
return new vhdl_scalar_type("std_logic");
|
||||||
|
|
@ -372,6 +364,55 @@ void vhdl_scalar_type::emit(std::ofstream &of, int level) const
|
||||||
of << name_;
|
of << name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cast something to a scalar type. There are a few ugly hacks here
|
||||||
|
* to handle special cases.
|
||||||
|
*/
|
||||||
|
vhdl_expr *vhdl_scalar_type::cast(vhdl_expr *expr) const
|
||||||
|
{
|
||||||
|
if (typeid(*expr) == typeid(vhdl_const_bits)
|
||||||
|
&& name_ == "std_logic") {
|
||||||
|
|
||||||
|
// Converting a literal bit string to std_logic is fairly
|
||||||
|
// common so this hack is justified by the increase in
|
||||||
|
// output readability :-)
|
||||||
|
|
||||||
|
const std::string &value =
|
||||||
|
dynamic_cast<vhdl_const_bits*>(expr)->get_value();
|
||||||
|
|
||||||
|
// Take the least significant bit
|
||||||
|
char lsb = value[0];
|
||||||
|
|
||||||
|
// Discard the given expression and return a brand new one
|
||||||
|
delete expr;
|
||||||
|
return new vhdl_const_bit(lsb);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Otherwise just assume there's a pre-defined conversion
|
||||||
|
const char *c_name = name_.c_str();
|
||||||
|
vhdl_fcall *conv =
|
||||||
|
new vhdl_fcall(c_name, new vhdl_scalar_type(c_name));
|
||||||
|
conv->add_expr(expr);
|
||||||
|
|
||||||
|
return conv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vhdl_vector_type *vhdl_vector_type::std_logic_vector(int msb, int lsb)
|
||||||
|
{
|
||||||
|
return new vhdl_vector_type("std_logic_vector", msb, lsb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vhdl_vector_type::emit(std::ofstream &of, int level) const
|
||||||
|
{
|
||||||
|
of << name_ << "(" << msb_ << " downto " << lsb_ << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
vhdl_expr *vhdl_vector_type::cast(vhdl_expr *expr) const
|
||||||
|
{
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
vhdl_var_decl::~vhdl_var_decl()
|
vhdl_var_decl::~vhdl_var_decl()
|
||||||
{
|
{
|
||||||
delete type_;
|
delete type_;
|
||||||
|
|
@ -467,3 +508,27 @@ void vhdl_nbassign_stmt::emit(std::ofstream &of, int level) const
|
||||||
rhs_->emit(of, level);
|
rhs_->emit(of, level);
|
||||||
of << ";";
|
of << ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vhdl_const_bits::vhdl_const_bits(const char *value)
|
||||||
|
: vhdl_expr(vhdl_vector_type::std_logic_vector(strlen(value)-1, 0)),
|
||||||
|
value_(value)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void vhdl_const_bits::emit(std::ofstream &of, int level) const
|
||||||
|
{
|
||||||
|
of << "std_logic_vector'(\"";
|
||||||
|
|
||||||
|
// The bits appear to be in reverse order
|
||||||
|
std::string::const_reverse_iterator it;
|
||||||
|
for (it = value_.rbegin(); it != value_.rend(); ++it)
|
||||||
|
of << *it;
|
||||||
|
|
||||||
|
of << "\")";
|
||||||
|
}
|
||||||
|
|
||||||
|
void vhdl_const_bit::emit(std::ofstream &of, int level) const
|
||||||
|
{
|
||||||
|
of << "'" << bit_ << "'";
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
class vhdl_entity;
|
class vhdl_entity;
|
||||||
class vhdl_arch;
|
class vhdl_arch;
|
||||||
|
class vhdl_expr;
|
||||||
|
|
||||||
typedef std::list<std::string> string_list_t;
|
typedef std::list<std::string> string_list_t;
|
||||||
|
|
||||||
|
|
@ -54,7 +55,7 @@ public:
|
||||||
vhdl_type(const char *name) : name_(name) {}
|
vhdl_type(const char *name) : name_(name) {}
|
||||||
virtual ~vhdl_type() {}
|
virtual ~vhdl_type() {}
|
||||||
|
|
||||||
virtual vhdl_type *clone() const = 0;
|
virtual vhdl_expr *cast(vhdl_expr *expr) const = 0;
|
||||||
|
|
||||||
const std::string &get_name() const { return name_; }
|
const std::string &get_name() const { return name_; }
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -72,7 +73,7 @@ public:
|
||||||
: vhdl_type(name) {}
|
: vhdl_type(name) {}
|
||||||
|
|
||||||
void emit(std::ofstream &of, int level) const;
|
void emit(std::ofstream &of, int level) const;
|
||||||
vhdl_type *clone() const;
|
vhdl_expr *cast(vhdl_expr *expr) const;
|
||||||
|
|
||||||
// Common types
|
// Common types
|
||||||
static vhdl_scalar_type *std_logic();
|
static vhdl_scalar_type *std_logic();
|
||||||
|
|
@ -80,6 +81,23 @@ public:
|
||||||
static vhdl_scalar_type *line();
|
static vhdl_scalar_type *line();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A vector type like std_logic_vector.
|
||||||
|
*/
|
||||||
|
class vhdl_vector_type : public vhdl_type {
|
||||||
|
public:
|
||||||
|
vhdl_vector_type(const char *name, int msb, int lsb)
|
||||||
|
: vhdl_type(name), msb_(msb), lsb_(lsb) {}
|
||||||
|
|
||||||
|
void emit(std::ofstream &of, int level) const;
|
||||||
|
vhdl_expr *cast(vhdl_expr *expr) const;
|
||||||
|
|
||||||
|
// Common types
|
||||||
|
static vhdl_vector_type *std_logic_vector(int msb, int lsb);
|
||||||
|
private:
|
||||||
|
int msb_, lsb_;
|
||||||
|
};
|
||||||
|
|
||||||
class vhdl_expr : public vhdl_element {
|
class vhdl_expr : public vhdl_element {
|
||||||
public:
|
public:
|
||||||
vhdl_expr(vhdl_type* type) : type_(type) {}
|
vhdl_expr(vhdl_type* type) : type_(type) {}
|
||||||
|
|
@ -115,6 +133,23 @@ private:
|
||||||
std::string value_;
|
std::string value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class vhdl_const_bits : public vhdl_expr {
|
||||||
|
public:
|
||||||
|
vhdl_const_bits(const char *value);
|
||||||
|
void emit(std::ofstream &of, int level) const;
|
||||||
|
const std::string &get_value() const { return value_; }
|
||||||
|
private:
|
||||||
|
std::string value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class vhdl_const_bit : public vhdl_expr {
|
||||||
|
public:
|
||||||
|
vhdl_const_bit(char bit)
|
||||||
|
: vhdl_expr(vhdl_scalar_type::std_logic()), bit_(bit) {}
|
||||||
|
void emit(std::ofstream &of, int level) const;
|
||||||
|
private:
|
||||||
|
char bit_;
|
||||||
|
};
|
||||||
|
|
||||||
class vhdl_expr_list : public vhdl_element {
|
class vhdl_expr_list : public vhdl_element {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue