Warn that a signed part select may not work for signals < 32 bits.
If a signed signal is driving a part select in a CA and the width is less than 32 bits. the value will be zero extended and will not work for negative values. This patch adds a warning that this could happen. This will be fixed in development.
This commit is contained in:
parent
09fa57742a
commit
e1af002a32
|
|
@ -1089,7 +1089,8 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
|||
if (base_ != 0) {
|
||||
off = base_->synthesize(des, scope, root);
|
||||
|
||||
NetPartSelect*sel = new NetPartSelect(sub, off, expr_width());
|
||||
NetPartSelect*sel = new NetPartSelect(sub, off, expr_width(),
|
||||
base_->has_sign());
|
||||
sel->set_line(*this);
|
||||
des->add_node(sel);
|
||||
|
||||
|
|
|
|||
|
|
@ -885,7 +885,7 @@ const NetDelaySrc* NetNet::delay_path(unsigned idx) const
|
|||
NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid,
|
||||
NetPartSelect::dir_t dir__)
|
||||
: NetNode(sig->scope(), sig->scope()->local_symbol(), 2),
|
||||
off_(off), wid_(wid), dir_(dir__)
|
||||
off_(off), wid_(wid), dir_(dir__), signed_flag_(false)
|
||||
{
|
||||
set_line(*sig);
|
||||
|
||||
|
|
@ -904,9 +904,9 @@ NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid,
|
|||
}
|
||||
|
||||
NetPartSelect::NetPartSelect(NetNet*sig, NetNet*sel,
|
||||
unsigned wid)
|
||||
unsigned wid, bool signed_flag)
|
||||
: NetNode(sig->scope(), sig->scope()->local_symbol(), 3),
|
||||
off_(0), wid_(wid), dir_(VP)
|
||||
off_(0), wid_(wid), dir_(VP), signed_flag_(signed_flag)
|
||||
{
|
||||
switch (dir_) {
|
||||
case NetPartSelect::VP:
|
||||
|
|
|
|||
|
|
@ -1795,12 +1795,14 @@ class NetPartSelect : public NetNode {
|
|||
explicit NetPartSelect(NetNet*sig,
|
||||
unsigned off, unsigned wid, dir_t dir);
|
||||
explicit NetPartSelect(NetNet*sig, NetNet*sel,
|
||||
unsigned wid);
|
||||
unsigned wid, bool signed_flag = false);
|
||||
~NetPartSelect();
|
||||
|
||||
unsigned base() const;
|
||||
unsigned width() const;
|
||||
dir_t dir() const;
|
||||
/* Is the select signal signed? */
|
||||
bool signed_flag() const { return signed_flag_; }
|
||||
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
bool emit_node(struct target_t*tgt) const;
|
||||
|
|
@ -1809,6 +1811,7 @@ class NetPartSelect : public NetNode {
|
|||
unsigned off_;
|
||||
unsigned wid_;
|
||||
dir_t dir_;
|
||||
bool signed_flag_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
8
t-dll.cc
8
t-dll.cc
|
|
@ -2153,8 +2153,12 @@ bool dll_target::part_select(const NetPartSelect*net)
|
|||
obj->scope = find_scope(des_, net->scope());
|
||||
assert(obj->scope);
|
||||
|
||||
/* Part selects are always unsigned. */
|
||||
obj->u_.part.signed_flag = 0;
|
||||
/* Part selects are always unsigned, so we use this to indicate
|
||||
* if the part select base signal is signed or not. */
|
||||
if (net->signed_flag())
|
||||
obj->u_.part.signed_flag = 1;
|
||||
else
|
||||
obj->u_.part.signed_flag = 0;
|
||||
|
||||
/* Choose the width of the part select. */
|
||||
obj->width = net->width();
|
||||
|
|
|
|||
|
|
@ -1654,6 +1654,14 @@ static void draw_lpm_part(ivl_lpm_t net)
|
|||
fprintf(vvp_out, ", %u, %u;\n", base, width);
|
||||
} else {
|
||||
const char*sel_symbol = draw_net_input(sel);
|
||||
/* We need to enhance .part/v to support a signed index. */
|
||||
if (ivl_lpm_signed(net) && width_of_nexus(sel) < 8*sizeof(int)) {
|
||||
fprintf(stderr, "%s:%u: tgt-vvp warning: V0.9 may give "
|
||||
"incorrect results for a select with a "
|
||||
"signed index less than %zu bits.\n",
|
||||
ivl_lpm_file(net), ivl_lpm_lineno(net),
|
||||
8*sizeof(int));
|
||||
}
|
||||
fprintf(vvp_out, "L_%p%s .part/v %s",
|
||||
net, dly, draw_net_input(ivl_lpm_data(net,0)));
|
||||
fprintf(vvp_out, ", %s", sel_symbol);
|
||||
|
|
|
|||
Loading…
Reference in New Issue