Implement combinatorial UDPs

Using a `with .. select' statement
This commit is contained in:
Nick Gasson 2008-08-11 13:23:50 +01:00
parent bf3734110e
commit 01bf741983
3 changed files with 37 additions and 5 deletions

View File

@ -121,8 +121,9 @@ static void udp_logic(vhdl_arch *arch, ivl_net_logic_t log)
new vhdl_signal_decl(ss.str().c_str(), tmp_type);
arch->get_scope()->add_decl(tmp_decl);
int nin = ivl_udp_nin(udp);
vhdl_expr *tmp_rhs;
if (ivl_udp_nin(udp) == 1) {
if (nin == 1) {
tmp_rhs = nexus_to_var_ref(arch->get_scope(), ivl_logic_pin(log, 1));
tmp_rhs = tmp_rhs->cast(tmp_type);
}
@ -138,6 +139,28 @@ static void udp_logic(vhdl_arch *arch, ivl_net_logic_t log)
new vhdl_var_ref(tmp_decl->get_name().c_str(), NULL);
arch->add_stmt(new vhdl_cassign_stmt(tmp_ref, tmp_rhs));
// Now we can implement the UDP as a `with .. select' statement
// by reading values out of the table
ivl_nexus_t output_nex = ivl_logic_pin(log, 0);
vhdl_var_ref *out = nexus_to_var_ref(arch->get_scope(), output_nex);
vhdl_with_select_stmt *ws =
new vhdl_with_select_stmt(new vhdl_var_ref(*tmp_ref), out);
int nrows = ivl_udp_rows(udp);
for (int i = 0; i < nrows; i++) {
const char *row = ivl_udp_row(udp, i);
vhdl_expr *value = new vhdl_const_bit(row[nin]);
vhdl_expr *cond = new vhdl_const_bits(row, nin, false);
ws->add_condition(value, cond);
}
ss.str("");
ss << "UDP " << ivl_udp_name(udp);
ws->set_comment(ss.str());
arch->add_stmt(ws);
}
static vhdl_expr *translate_logic_inputs(vhdl_scope *scope, ivl_net_logic_t log)

View File

@ -892,6 +892,7 @@ void vhdl_param_decl::emit(std::ostream &of, int level) const
vhdl_with_select_stmt::~vhdl_with_select_stmt()
{
delete test_;
delete out_;
for (when_list_t::const_iterator it = whens_.begin();
it != whens_.end();
@ -903,15 +904,21 @@ vhdl_with_select_stmt::~vhdl_with_select_stmt()
void vhdl_with_select_stmt::emit(std::ostream &of, int level) const
{
emit_comment(of, level);
of << "with ";
test_->emit(of, level);
of << " select";
emit_comment(of, level, true);
newline(of, indent(level));
out_->emit(of, level);
of << " <= ";
when_list_t::const_iterator it = whens_.begin();
while (it != whens_.end()) {
(*it).value->emit(of, level);
of << " when ";
(*it).cond->emit(of, level);
if (++it != whens_.end()) {
of << ",";
newline(of, indent(level));

View File

@ -288,13 +288,15 @@ private:
class vhdl_with_select_stmt : public vhdl_conc_stmt {
public:
vhdl_with_select_stmt(vhdl_expr *test) : test_(test) {}
vhdl_with_select_stmt(vhdl_expr *test, vhdl_var_ref *out)
: test_(test), out_(out) {}
~vhdl_with_select_stmt();
void emit(std::ostream &of, int level) const;
void add_condition(vhdl_expr *value, vhdl_expr *cond);
private:
vhdl_expr *test_;
vhdl_var_ref *out_;
when_list_t whens_;
};