From fa2712a3eecc549a2a70c381d1f80c7cd3131874 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sat, 15 Dec 2007 13:57:22 +0000 Subject: [PATCH] Fix for pr1851310. This patch fixes a bug in the compiler which prevented array words from being correctly selected when used in the RHS of a continuous assignment. --- expr_synth.cc | 64 ++++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/expr_synth.cc b/expr_synth.cc index 2e08cab5f..6ec25e820 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -840,36 +840,42 @@ NetNet* NetETernary::synthesize(Design *des) /* * When synthesizing a signal expression, it is usually fine to simply - * return the NetNet that it refers to. If this is a part select, - * though, a bit more work needs to be done. Return a temporary that - * represents the connections to the selected bits. - * - * For example, if there is a reg foo, like so: - * reg [5:0] foo; - * and this expression node represents a part select foo[3:2], then - * create a temporary like so: - * - * foo - * +---+ - * | 5 | - * +---+ - * tmp | 4 | - * +---+ +---+ - * | 1 | <---> | 3 | - * +---+ +---+ - * | 0 | <---> | 2 | - * +---+ +---+ - * | 1 | - * +---+ - * | 0 | - * +---+ - * The temporary is marked as a temporary and returned to the - * caller. This causes the caller to get only the selected part of the - * signal, and when it hooks up to tmp, it hooks up to the right parts - * of foo. + * return the NetNet that it refers to. If this is an array word though, + * a bit more work needs to be done. Return a temporary that represents + * the selected word. */ NetNet* NetESignal::synthesize(Design*des) { - return net_; -} + if (word_ == 0) + return net_; + NetScope*scope = net_->scope(); + + NetNet*tmp = new NetNet(scope, scope->local_symbol(), + NetNet::IMPLICIT, net_->vector_width()); + tmp->set_line(*this); + tmp->local_flag(true); + tmp->data_type(net_->data_type()); + + if (NetEConst*index_co = dynamic_cast (word_)) { + long index = index_co->value().as_long(); + + assert(net_->array_index_is_valid(index)); + index = net_->array_index_to_address(index); + + connect(tmp->pin(0), net_->pin(index)); + } else { + unsigned selwid = word_->expr_width(); + + NetArrayDq*mux = new NetArrayDq(scope, scope->local_symbol(), + net_, selwid); + mux->set_line(*this); + des->add_node(mux); + + NetNet*index_net = word_->synthesize(des); + connect(mux->pin_Address(), index_net->pin(0)); + + connect(tmp->pin(0), mux->pin_Result()); + } + return tmp; +}