Generate combined input for UDP devices
Combinatorial UDPs will be implemented with a `with ... select' statemetnt. However the input to this must be "locally static". This patch joins the inputs into a vector which can be used as the select expression.
This commit is contained in:
parent
8e0bf3ebff
commit
6dcf936807
|
|
@ -84,10 +84,13 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to)
|
||||||
return conv;
|
return conv;
|
||||||
}
|
}
|
||||||
else if ((to->get_name() == VHDL_TYPE_UNSIGNED
|
else if ((to->get_name() == VHDL_TYPE_UNSIGNED
|
||||||
|| to->get_name() == VHDL_TYPE_SIGNED) &&
|
|| to->get_name() == VHDL_TYPE_SIGNED
|
||||||
|
|| to->get_name() == VHDL_TYPE_STD_LOGIC_VECTOR) &&
|
||||||
type_->get_name() == VHDL_TYPE_STD_LOGIC) {
|
type_->get_name() == VHDL_TYPE_STD_LOGIC) {
|
||||||
|
|
||||||
|
vhdl_expr *others = to->get_width() == 1 ? NULL : new vhdl_const_bit('0');
|
||||||
vhdl_bit_spec_expr *bs =
|
vhdl_bit_spec_expr *bs =
|
||||||
new vhdl_bit_spec_expr(new vhdl_type(*to), new vhdl_const_bit('0'));
|
new vhdl_bit_spec_expr(new vhdl_type(*to), others);
|
||||||
bs->add_bit(0, this);
|
bs->add_bit(0, this);
|
||||||
|
|
||||||
return bs;
|
return bs;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include "vhdl_element.hh"
|
#include "vhdl_element.hh"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -107,6 +108,36 @@ static void udp_logic(vhdl_arch *arch, ivl_net_logic_t log)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As with regular case statements, the expression in a
|
||||||
|
// `with .. select' statement must be "locally static".
|
||||||
|
// This is achieved by first combining the inputs into
|
||||||
|
// a temporary
|
||||||
|
|
||||||
|
ostringstream ss;
|
||||||
|
ss << ivl_logic_basename(log) << "_Tmp";
|
||||||
|
int msb = ivl_udp_nin(udp) - 1;
|
||||||
|
vhdl_type *tmp_type = vhdl_type::std_logic_vector(msb, 0);
|
||||||
|
vhdl_signal_decl *tmp_decl =
|
||||||
|
new vhdl_signal_decl(ss.str().c_str(), tmp_type);
|
||||||
|
arch->get_scope()->add_decl(tmp_decl);
|
||||||
|
|
||||||
|
vhdl_expr *tmp_rhs;
|
||||||
|
if (ivl_udp_nin(udp) == 1) {
|
||||||
|
tmp_rhs = nexus_to_var_ref(arch->get_scope(), ivl_logic_pin(log, 1));
|
||||||
|
tmp_rhs = tmp_rhs->cast(tmp_type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tmp_rhs = inputs_to_expr(arch->get_scope(), VHDL_BINOP_CONCAT, log);
|
||||||
|
|
||||||
|
ss.str("");
|
||||||
|
ss << "Input to " << ivl_logic_basename(log) << " "
|
||||||
|
<< ivl_udp_name(udp) << " UDP";
|
||||||
|
tmp_decl->set_comment(ss.str());
|
||||||
|
|
||||||
|
vhdl_var_ref *tmp_ref =
|
||||||
|
new vhdl_var_ref(tmp_decl->get_name().c_str(), NULL);
|
||||||
|
arch->add_stmt(new vhdl_cassign_stmt(tmp_ref, tmp_rhs));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static vhdl_expr *translate_logic_inputs(vhdl_scope *scope, ivl_net_logic_t log)
|
static vhdl_expr *translate_logic_inputs(vhdl_scope *scope, ivl_net_logic_t log)
|
||||||
|
|
|
||||||
|
|
@ -737,6 +737,7 @@ void vhdl_binop_expr::emit(std::ostream &of, int level) const
|
||||||
|
|
||||||
vhdl_bit_spec_expr::~vhdl_bit_spec_expr()
|
vhdl_bit_spec_expr::~vhdl_bit_spec_expr()
|
||||||
{
|
{
|
||||||
|
if (others_)
|
||||||
delete others_;
|
delete others_;
|
||||||
|
|
||||||
std::list<bit_map>::iterator it;
|
std::list<bit_map>::iterator it;
|
||||||
|
|
@ -755,14 +756,19 @@ void vhdl_bit_spec_expr::emit(std::ostream &of, int level) const
|
||||||
of << "(";
|
of << "(";
|
||||||
|
|
||||||
std::list<bit_map>::const_iterator it;
|
std::list<bit_map>::const_iterator it;
|
||||||
for (it = bits_.begin(); it != bits_.end(); ++it) {
|
it = bits_.begin();
|
||||||
|
while (it != bits_.end()) {
|
||||||
of << (*it).bit << " => ";
|
of << (*it).bit << " => ";
|
||||||
(*it).e->emit(of, level);
|
(*it).e->emit(of, level);
|
||||||
|
if (++it != bits_.end())
|
||||||
of << ", ";
|
of << ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
of << "others => ";
|
if (others_) {
|
||||||
|
of << ", others => ";
|
||||||
others_->emit(of, level);
|
others_->emit(of, level);
|
||||||
|
}
|
||||||
|
|
||||||
of << ")";
|
of << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue