Fix VHDL bug where constant is assigned to input
This fixes a bug where the VHDL target would not map ports in cases where the port was driven by a constant.
This commit is contained in:
parent
babc9c1352
commit
3dadedf9b5
|
|
@ -589,39 +589,49 @@ static void map_signal(ivl_signal_t to, vhdl_entity *parent,
|
||||||
nexus_private_t *priv =
|
nexus_private_t *priv =
|
||||||
static_cast<nexus_private_t*>(ivl_nexus_get_private(nexus));
|
static_cast<nexus_private_t*>(ivl_nexus_get_private(nexus));
|
||||||
assert(priv);
|
assert(priv);
|
||||||
if (!visible_nexus(priv, arch_scope)) {
|
|
||||||
|
vhdl_expr *map_to = NULL;
|
||||||
|
const string name(make_safe_name(to));
|
||||||
|
|
||||||
|
// We can only map ports to signals or constants
|
||||||
|
if (visible_nexus(priv, arch_scope)) {
|
||||||
|
vhdl_var_ref *ref = nexus_to_var_ref(parent->get_arch()->get_scope(), nexus);
|
||||||
|
|
||||||
|
// If we're mapping an output of this entity to an output of
|
||||||
|
// the child entity, then VHDL will not let us read the value
|
||||||
|
// of the signal (i.e. it must pass straight through).
|
||||||
|
// However, Verilog allows the signal to be read in the parent.
|
||||||
|
// The solution used here is to create an intermediate signal
|
||||||
|
// and connect it to both ports.
|
||||||
|
vhdl_decl* from_decl =
|
||||||
|
parent->get_arch()->get_scope()->get_decl(ref->get_name());
|
||||||
|
if (!from_decl->is_readable()
|
||||||
|
&& !arch_scope->have_declared(name + "_Readable")) {
|
||||||
|
vhdl_decl* tmp_decl =
|
||||||
|
new vhdl_signal_decl(name + "_Readable", ref->get_type());
|
||||||
|
|
||||||
|
// Add a comment to explain what this is for
|
||||||
|
tmp_decl->set_comment("Needed to connect outputs");
|
||||||
|
|
||||||
|
arch_scope->add_decl(tmp_decl);
|
||||||
|
parent->get_arch()->add_stmt
|
||||||
|
(new vhdl_cassign_stmt(from_decl->make_ref(), tmp_decl->make_ref()));
|
||||||
|
|
||||||
|
map_to = tmp_decl->make_ref();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
map_to = ref;
|
||||||
|
}
|
||||||
|
else if (priv->const_driver && ivl_signal_port(to) == IVL_SIP_INPUT) {
|
||||||
|
map_to = priv->const_driver;
|
||||||
|
priv->const_driver = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
// This nexus isn't attached to anything in the parent
|
// This nexus isn't attached to anything in the parent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vhdl_var_ref *ref = nexus_to_var_ref(parent->get_arch()->get_scope(), nexus);
|
inst->map_port(name, map_to);
|
||||||
|
|
||||||
string name = make_safe_name(to);
|
|
||||||
|
|
||||||
// If we're mapping an output of this entity to an output of
|
|
||||||
// the child entity, then VHDL will not let us read the value
|
|
||||||
// of the signal (i.e. it must pass straight through).
|
|
||||||
// However, Verilog allows the signal to be read in the parent.
|
|
||||||
// The solution used here is to create an intermediate signal
|
|
||||||
// and connect it to both ports.
|
|
||||||
vhdl_decl* from_decl =
|
|
||||||
parent->get_arch()->get_scope()->get_decl(ref->get_name());
|
|
||||||
if (!from_decl->is_readable()
|
|
||||||
&& !arch_scope->have_declared(name + "_Readable")) {
|
|
||||||
vhdl_decl* tmp_decl =
|
|
||||||
new vhdl_signal_decl(name + "_Readable", ref->get_type());
|
|
||||||
|
|
||||||
// Add a comment to explain what this is for
|
|
||||||
tmp_decl->set_comment("Needed to connect outputs");
|
|
||||||
|
|
||||||
arch_scope->add_decl(tmp_decl);
|
|
||||||
parent->get_arch()->add_stmt
|
|
||||||
(new vhdl_cassign_stmt(from_decl->make_ref(), tmp_decl->make_ref()));
|
|
||||||
|
|
||||||
ref = tmp_decl->make_ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
inst->map_port(name.c_str(), ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ vhdl_comp_inst::~vhdl_comp_inst()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vhdl_comp_inst::map_port(const char *name, vhdl_expr *expr)
|
void vhdl_comp_inst::map_port(const string& name, vhdl_expr *expr)
|
||||||
{
|
{
|
||||||
port_map_t pmap = { name, expr };
|
port_map_t pmap = { name, expr };
|
||||||
mapping_.push_back(pmap);
|
mapping_.push_back(pmap);
|
||||||
|
|
|
||||||
|
|
@ -695,7 +695,7 @@ public:
|
||||||
~vhdl_comp_inst();
|
~vhdl_comp_inst();
|
||||||
|
|
||||||
void emit(std::ostream &of, int level) const;
|
void emit(std::ostream &of, int level) const;
|
||||||
void map_port(const char *name, vhdl_expr *expr);
|
void map_port(const string& name, vhdl_expr *expr);
|
||||||
|
|
||||||
const std::string &get_comp_name() const { return comp_name_; }
|
const std::string &get_comp_name() const { return comp_name_; }
|
||||||
const std::string &get_inst_name() const { return inst_name_; }
|
const std::string &get_inst_name() const { return inst_name_; }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue