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

View File

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

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() 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 << ")";
} }