Merge pull request #1062 from larsclausen/replicate-for-concat-repeat

Use NetReplicate to implement replication for concat
This commit is contained in:
Cary R 2024-01-06 22:13:31 -08:00 committed by GitHub
commit c53b1c0101
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 21 deletions

View File

@ -776,23 +776,24 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
return 0;
}
/* Make a NetNet object to carry the output vector. */
perm_string path = scope->local_symbol();
netvector_t*osig_vec = new netvector_t(data_type, expr_width()-1, 0);
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, osig_vec);
osig->set_line(*this);
osig->local_flag(true);
NetNet *osig = nullptr;
NetConcat*cncat = new NetConcat(scope, scope->local_symbol(),
osig->vector_width(),
num_parms * repeat());
cncat->set_line(*this);
des->add_node(cncat);
connect(cncat->pin(0), osig->pin(0));
if (num_parms != 1) {
/* Make a NetNet object to carry the output vector. */
auto osig_vec = new netvector_t(data_type, expr_width() / repeat() - 1, 0);
osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT,
osig_vec);
osig->set_line(*this);
osig->local_flag(true);
unsigned count_input_width = 0;
unsigned cur_pin = 1;
for (unsigned rpt = 0; rpt < repeat(); rpt += 1) {
auto cncat = new NetConcat(scope, scope->local_symbol(),
osig->vector_width(), num_parms);
cncat->set_line(*this);
des->add_node(cncat);
connect(cncat->pin(0), osig->pin(0));
unsigned count_input_width = 0;
unsigned cur_pin = 1;
for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) {
unsigned concat_item = parms_.size()-idx-1;
if (tmp[concat_item] == 0) continue;
@ -800,14 +801,38 @@ NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root)
cur_pin += 1;
count_input_width += tmp[concat_item]->vector_width();
}
if (count_input_width != osig->vector_width()) {
cerr << get_fileline() << ": internal error: "
<< "NetEConcat input width = " << count_input_width
<< ", expecting " << osig->vector_width()
<< endl;
des->errors += 1;
}
} else {
/* There is exactly one input signal */
for (unsigned idx = 0; idx < parms_.size(); idx++) {
if (tmp[idx]) {
osig = tmp[idx];
break;
}
}
ivl_assert(*this, osig);
}
if (count_input_width != osig->vector_width()) {
cerr << get_fileline() << ": internal error: "
<< "NetEConcat input width = " << count_input_width
<< ", expecting " << osig->vector_width()
<< " (repeat=" << repeat() << ")" << endl;
des->errors += 1;
if (repeat() != 1) {
auto rep = new NetReplicate(scope, scope->local_symbol(),
expr_width(), repeat());
rep->set_line(*this);
des->add_node(rep);
connect(rep->pin(1), osig->pin(0));
auto osig_vec = new netvector_t(data_type, expr_width() - 1, 0);
osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT,
osig_vec);
osig->set_line(*this);
osig->local_flag(true);
connect(rep->pin(0), osig->pin(0));
}
delete[]tmp;

View File

@ -234,6 +234,13 @@ void vvp_fun_repeat::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
port.ptr()->send_vec4(val, 0);
}
void vvp_fun_repeat::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t &bit,
unsigned base, unsigned vwid,
vvp_context_t context)
{
recv_vec4_pv_(port, bit, base, vwid, context);
}
void compile_repeat(char*label, long width, long repeat, struct symb_s arg)
{
vvp_fun_repeat*fun = new vvp_fun_repeat(width, repeat);

View File

@ -1450,6 +1450,9 @@ class vvp_fun_repeat : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
vvp_context_t context);
void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
unsigned int base, unsigned int vwid,
vvp_context_t context) final;
private:
unsigned wid_;