Implement combinatorial UDPs
Using a `with .. select' statement
This commit is contained in:
parent
bf3734110e
commit
01bf741983
|
|
@ -120,9 +120,10 @@ static void udp_logic(vhdl_arch *arch, ivl_net_logic_t log)
|
||||||
vhdl_signal_decl *tmp_decl =
|
vhdl_signal_decl *tmp_decl =
|
||||||
new vhdl_signal_decl(ss.str().c_str(), tmp_type);
|
new vhdl_signal_decl(ss.str().c_str(), tmp_type);
|
||||||
arch->get_scope()->add_decl(tmp_decl);
|
arch->get_scope()->add_decl(tmp_decl);
|
||||||
|
|
||||||
|
int nin = ivl_udp_nin(udp);
|
||||||
vhdl_expr *tmp_rhs;
|
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 = nexus_to_var_ref(arch->get_scope(), ivl_logic_pin(log, 1));
|
||||||
tmp_rhs = tmp_rhs->cast(tmp_type);
|
tmp_rhs = tmp_rhs->cast(tmp_type);
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +138,29 @@ static void udp_logic(vhdl_arch *arch, ivl_net_logic_t log)
|
||||||
vhdl_var_ref *tmp_ref =
|
vhdl_var_ref *tmp_ref =
|
||||||
new vhdl_var_ref(tmp_decl->get_name().c_str(), NULL);
|
new vhdl_var_ref(tmp_decl->get_name().c_str(), NULL);
|
||||||
arch->add_stmt(new vhdl_cassign_stmt(tmp_ref, tmp_rhs));
|
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)
|
static vhdl_expr *translate_logic_inputs(vhdl_scope *scope, ivl_net_logic_t log)
|
||||||
|
|
|
||||||
|
|
@ -892,6 +892,7 @@ void vhdl_param_decl::emit(std::ostream &of, int level) const
|
||||||
vhdl_with_select_stmt::~vhdl_with_select_stmt()
|
vhdl_with_select_stmt::~vhdl_with_select_stmt()
|
||||||
{
|
{
|
||||||
delete test_;
|
delete test_;
|
||||||
|
delete out_;
|
||||||
|
|
||||||
for (when_list_t::const_iterator it = whens_.begin();
|
for (when_list_t::const_iterator it = whens_.begin();
|
||||||
it != whens_.end();
|
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
|
void vhdl_with_select_stmt::emit(std::ostream &of, int level) const
|
||||||
{
|
{
|
||||||
emit_comment(of, level);
|
|
||||||
|
|
||||||
of << "with ";
|
of << "with ";
|
||||||
test_->emit(of, level);
|
test_->emit(of, level);
|
||||||
of << " select";
|
of << " select";
|
||||||
|
emit_comment(of, level, true);
|
||||||
newline(of, indent(level));
|
newline(of, indent(level));
|
||||||
|
|
||||||
|
out_->emit(of, level);
|
||||||
|
of << " <= ";
|
||||||
|
|
||||||
when_list_t::const_iterator it = whens_.begin();
|
when_list_t::const_iterator it = whens_.begin();
|
||||||
while (it != whens_.end()) {
|
while (it != whens_.end()) {
|
||||||
|
(*it).value->emit(of, level);
|
||||||
|
of << " when ";
|
||||||
|
(*it).cond->emit(of, level);
|
||||||
|
|
||||||
if (++it != whens_.end()) {
|
if (++it != whens_.end()) {
|
||||||
of << ",";
|
of << ",";
|
||||||
newline(of, indent(level));
|
newline(of, indent(level));
|
||||||
|
|
|
||||||
|
|
@ -288,13 +288,15 @@ private:
|
||||||
|
|
||||||
class vhdl_with_select_stmt : public vhdl_conc_stmt {
|
class vhdl_with_select_stmt : public vhdl_conc_stmt {
|
||||||
public:
|
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();
|
~vhdl_with_select_stmt();
|
||||||
|
|
||||||
void emit(std::ostream &of, int level) const;
|
void emit(std::ostream &of, int level) const;
|
||||||
void add_condition(vhdl_expr *value, vhdl_expr *cond);
|
void add_condition(vhdl_expr *value, vhdl_expr *cond);
|
||||||
private:
|
private:
|
||||||
vhdl_expr *test_;
|
vhdl_expr *test_;
|
||||||
|
vhdl_var_ref *out_;
|
||||||
when_list_t whens_;
|
when_list_t whens_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue