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;
|
||||
}
|
||||
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) {
|
||||
|
||||
vhdl_expr *others = to->get_width() == 1 ? NULL : new vhdl_const_bit('0');
|
||||
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);
|
||||
|
||||
return bs;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "vhdl_element.hh"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
|
|
@ -106,6 +107,36 @@ static void udp_logic(vhdl_arch *arch, ivl_net_logic_t log)
|
|||
error("Sequential UDP devices not supported yet");
|
||||
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));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -737,7 +737,8 @@ void vhdl_binop_expr::emit(std::ostream &of, int level) const
|
|||
|
||||
vhdl_bit_spec_expr::~vhdl_bit_spec_expr()
|
||||
{
|
||||
delete others_;
|
||||
if (others_)
|
||||
delete others_;
|
||||
|
||||
std::list<bit_map>::iterator it;
|
||||
for (it = bits_.begin(); it != bits_.end(); ++it)
|
||||
|
|
@ -755,14 +756,19 @@ void vhdl_bit_spec_expr::emit(std::ostream &of, int level) const
|
|||
of << "(";
|
||||
|
||||
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 << " => ";
|
||||
(*it).e->emit(of, level);
|
||||
of << ", ";
|
||||
if (++it != bits_.end())
|
||||
of << ", ";
|
||||
}
|
||||
|
||||
of << "others => ";
|
||||
others_->emit(of, level);
|
||||
if (others_) {
|
||||
of << ", others => ";
|
||||
others_->emit(of, level);
|
||||
}
|
||||
|
||||
of << ")";
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue