Add uwire support to VHDL backend

Implemented as std_ulogic which behaves almost identically.
This commit is contained in:
Nick Gasson 2010-08-24 22:51:19 +01:00
parent 419ea8c9ea
commit 43f904f793
5 changed files with 53 additions and 12 deletions

View File

@ -28,10 +28,12 @@
vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
{
//std::cout << "Cast: from=" << type_->get_string()
// << " (" << type_->get_width() << ") "
// << " to=" << to->get_string() << " ("
// << to->get_width() << ")" << std::endl;
#if 0
std::cout << "Cast: from=" << type_->get_string()
<< " (" << type_->get_width() << ") "
<< " to=" << to->get_string() << " ("
<< to->get_width() << ")" << std::endl;
#endif
// If this expression hasn't been given a type then
// we can't generate any type conversion code
@ -58,6 +60,8 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
return to_std_logic();
case VHDL_TYPE_STRING:
return to_string();
case VHDL_TYPE_STD_ULOGIC:
return to_std_ulogic();
default:
assert(false);
}
@ -206,6 +210,17 @@ vhdl_expr *vhdl_expr::to_std_logic()
return NULL;
}
vhdl_expr *vhdl_expr::to_std_ulogic()
{
if (type_->get_name() == VHDL_TYPE_STD_LOGIC) {
vhdl_fcall *f = new vhdl_fcall("std_logic", vhdl_type::std_logic());
f->add_expr(this);
return f;
}
else
assert(false);
}
/*
* Change the width of a signed/unsigned type.
*/
@ -325,6 +340,11 @@ vhdl_expr *vhdl_const_bit::to_boolean()
return new vhdl_const_bool(bit_ == '1');
}
vhdl_expr *vhdl_const_bit::to_std_ulogic()
{
return this;
}
vhdl_expr *vhdl_const_bit::to_vector(vhdl_type_name_t name, int w)
{
// Zero-extend this bit to the correct width

View File

@ -277,6 +277,7 @@ void draw_nexus(ivl_nexus_t nexus)
switch (signal_type_of_nexus(nexus, width)) {
case IVL_SIT_TRI:
case IVL_SIT_UWIRE:
def = 'Z';
break;
case IVL_SIT_TRI0:
@ -556,9 +557,13 @@ static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig,
sig_type = new vhdl_type(*array_type);
}
else
sig_type =
vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0);
else {
sig_type = vhdl_type::type_for(ivl_signal_width(sig),
ivl_signal_signed(sig) != 0,
0, ivl_signal_type(sig) == IVL_SIT_UWIRE);
}
ivl_signal_port_t mode = ivl_signal_port(sig);
switch (mode) {

View File

@ -50,6 +50,7 @@ public:
virtual vhdl_expr *to_boolean();
virtual vhdl_expr *to_integer();
virtual vhdl_expr *to_std_logic();
virtual vhdl_expr *to_std_ulogic();
virtual vhdl_expr *to_vector(vhdl_type_name_t name, int w);
virtual vhdl_expr *to_string();
virtual void find_vars(vhdl_var_set_t& read) {}
@ -211,6 +212,7 @@ public:
vhdl_expr *to_boolean();
vhdl_expr *to_integer();
vhdl_expr *to_vector(vhdl_type_name_t name, int w);
vhdl_expr *to_std_ulogic();
private:
char bit_;
};

View File

@ -24,12 +24,16 @@
#include <sstream>
#include <iostream>
vhdl_type *vhdl_type::std_logic()
{
return new vhdl_type(VHDL_TYPE_STD_LOGIC);
}
vhdl_type *vhdl_type::std_ulogic()
{
return new vhdl_type(VHDL_TYPE_STD_ULOGIC);
}
vhdl_type *vhdl_type::string()
{
return new vhdl_type(VHDL_TYPE_STRING);
@ -79,6 +83,8 @@ std::string vhdl_type::get_string() const
switch (name_) {
case VHDL_TYPE_STD_LOGIC:
return std::string("std_logic");
case VHDL_TYPE_STD_ULOGIC:
return std::string("std_ulogic");
case VHDL_TYPE_STD_LOGIC_VECTOR:
return std::string("std_logic_vector");
case VHDL_TYPE_STRING:
@ -167,10 +173,15 @@ vhdl_type *vhdl_type::std_logic_vector(int msb, int lsb)
return new vhdl_type(VHDL_TYPE_STD_LOGIC_VECTOR, msb, lsb);
}
vhdl_type *vhdl_type::type_for(int width, bool issigned, int lsb)
vhdl_type *vhdl_type::type_for(int width, bool issigned,
int lsb, bool unresolved)
{
if (width == 1)
return vhdl_type::std_logic();
if (width == 1) {
if (unresolved)
return vhdl_type::std_ulogic();
else
return vhdl_type::std_logic();
}
else if (issigned)
return vhdl_type::nsigned(width, lsb);
else

View File

@ -25,6 +25,7 @@
enum vhdl_type_name_t {
VHDL_TYPE_STD_LOGIC,
VHDL_TYPE_STD_ULOGIC,
VHDL_TYPE_STD_LOGIC_VECTOR,
VHDL_TYPE_STRING,
VHDL_TYPE_LINE,
@ -71,6 +72,7 @@ public:
// Common types
static vhdl_type *std_logic();
static vhdl_type *std_ulogic();
static vhdl_type *string();
static vhdl_type *line();
static vhdl_type *std_logic_vector(int msb, int lsb);
@ -80,7 +82,8 @@ public:
static vhdl_type *boolean();
static vhdl_type *time();
static vhdl_type *type_for(int width, bool issigned, int lsb=0);
static vhdl_type *type_for(int width, bool issigned,
int lsb=0, bool unresolved=false);
static vhdl_type *array_of(vhdl_type *b, std::string &n, int m, int l);
protected:
vhdl_type_name_t name_;