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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -59,6 +67,8 @@ vhdl_expr *translate_expr(ivl_expr_t e)
|
|||
return translate_string(e);
|
||||
case IVL_EX_SIGNAL:
|
||||
return translate_signal(e);
|
||||
case IVL_EX_NUMBER:
|
||||
return translate_number(e);
|
||||
default:
|
||||
error("No VHDL translation for expression at %s:%d (type = %d)",
|
||||
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);
|
||||
for (int i = 0; i < nsigs; 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 =
|
||||
new vhdl_signal_decl(ivl_signal_basename(sig), std_logic);
|
||||
new vhdl_signal_decl(ivl_signal_basename(sig), sig_type);
|
||||
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))) {
|
||||
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)
|
||||
return 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <typeinfo>
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -343,15 +344,6 @@ void vhdl_wait_stmt::emit(std::ofstream &of, int level) const
|
|||
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()
|
||||
{
|
||||
return new vhdl_scalar_type("std_logic");
|
||||
|
|
@ -372,6 +364,55 @@ void vhdl_scalar_type::emit(std::ofstream &of, int level) const
|
|||
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()
|
||||
{
|
||||
delete type_;
|
||||
|
|
@ -467,3 +508,27 @@ void vhdl_nbassign_stmt::emit(std::ofstream &of, int level) const
|
|||
rhs_->emit(of, level);
|
||||
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_arch;
|
||||
class vhdl_expr;
|
||||
|
||||
typedef std::list<std::string> string_list_t;
|
||||
|
||||
|
|
@ -54,7 +55,7 @@ public:
|
|||
vhdl_type(const char *name) : name_(name) {}
|
||||
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_; }
|
||||
protected:
|
||||
|
|
@ -72,14 +73,31 @@ public:
|
|||
: vhdl_type(name) {}
|
||||
|
||||
void emit(std::ofstream &of, int level) const;
|
||||
vhdl_type *clone() const;
|
||||
|
||||
vhdl_expr *cast(vhdl_expr *expr) const;
|
||||
|
||||
// Common types
|
||||
static vhdl_scalar_type *std_logic();
|
||||
static vhdl_scalar_type *string();
|
||||
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 {
|
||||
public:
|
||||
vhdl_expr(vhdl_type* type) : type_(type) {}
|
||||
|
|
@ -115,6 +133,23 @@ private:
|
|||
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 {
|
||||
public:
|
||||
|
|
|
|||
Loading…
Reference in New Issue