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:
Nick Gasson 2008-08-11 12:58:46 +01:00
parent 8e0bf3ebff
commit 6dcf936807
3 changed files with 47 additions and 7 deletions

View File

@ -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;

View File

@ -22,6 +22,7 @@
#include "vhdl_element.hh"
#include <cassert>
#include <sstream>
#include <iostream>
@ -107,6 +108,36 @@ static void udp_logic(vhdl_arch *arch, ivl_net_logic_t log)
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)

View File

@ -737,6 +737,7 @@ void vhdl_binop_expr::emit(std::ostream &of, int level) const
vhdl_bit_spec_expr::~vhdl_bit_spec_expr()
{
if (others_)
delete others_;
std::list<bit_map>::iterator 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);
if (++it != bits_.end())
of << ", ";
}
of << "others => ";
if (others_) {
of << ", others => ";
others_->emit(of, level);
}
of << ")";
}