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 =
|
||||
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);
|
||||
}
|
||||
|
|
@ -137,7 +138,29 @@ static void udp_logic(vhdl_arch *arch, ivl_net_logic_t log)
|
|||
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));
|
||||
|
||||
// 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)
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue