Generate signed comparisons independent of the signedness of the expression

The signedness of comparison expressions is typically unsigned, even if
the comparison to be performed is signed. The comparison (and particularly
the expr_synth of the comparison) needs to account for this explicitly.
This commit is contained in:
Stephen Williams 2008-10-13 19:43:02 -07:00
parent 55b8ff4441
commit 25f6282a54
4 changed files with 43 additions and 53 deletions

View File

@ -343,7 +343,9 @@ void NetCLShift::dump_node(ostream&o, unsigned ind) const
void NetCompare::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_COMPARE (NetCompare): " << name() << endl;
o << setw(ind) << "" << "LPM_COMPARE (NetCompare "
<< (get_signed()? "signed" : "unsigned") << "): "
<< name() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}

View File

@ -245,7 +245,18 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope)
osig->local_flag(true);
osig->data_type(IVL_VT_LOGIC);
bool signed_compare = lsig->get_signed() && rsig->get_signed();
// Test if the comparison is signed.
//
// Note 1: This is not the same as asking if the result is
// signed. In fact, the result will typically be UNsigned. The
// decision to make the comparison signed depends on the
// operand expressions.
//
// Note 2: The operand expressions may be signed even if the
// sig that comes out of synthesis is unsigned. The $signed()
// function markes the expression but doesn't change the
// underlying signals.
bool signed_compare = left_->has_sign() && right_->has_sign();
if (debug_elaborate) {
cerr << get_fileline() << ": debug: Comparison (" << op_ << ")"
<< " is " << (signed_compare? "signed" : "unsigned")

View File

@ -1276,19 +1276,17 @@ const Link& NetCLShift::pin_Distance() const
}
NetCompare::NetCompare(NetScope*s, perm_string n, unsigned wi)
: NetNode(s, n, 10), width_(wi)
: NetNode(s, n, 8), width_(wi)
{
signed_flag_ = false;
pin(0).set_dir(Link::INPUT); // Aclr
pin(1).set_dir(Link::INPUT); // Clock
pin(2).set_dir(Link::OUTPUT); // AGB
pin(3).set_dir(Link::OUTPUT); // AGEB
pin(4).set_dir(Link::OUTPUT); // AEB
pin(5).set_dir(Link::OUTPUT); // ANEB
pin(6).set_dir(Link::OUTPUT); // ALB
pin(7).set_dir(Link::OUTPUT); // ALEB
pin(8).set_dir(Link::INPUT); // DataA
pin(9).set_dir(Link::INPUT); // DataB
pin(0).set_dir(Link::OUTPUT); // AGB
pin(1).set_dir(Link::OUTPUT); // AGEB
pin(2).set_dir(Link::OUTPUT); // AEB
pin(3).set_dir(Link::OUTPUT); // ANEB
pin(4).set_dir(Link::OUTPUT); // ALB
pin(5).set_dir(Link::OUTPUT); // ALEB
pin(6).set_dir(Link::INPUT); // DataA
pin(7).set_dir(Link::INPUT); // DataB
}
NetCompare::~NetCompare()
@ -1311,104 +1309,84 @@ void NetCompare::set_signed(bool flag)
}
Link& NetCompare::pin_Aclr()
{
return pin(0);
}
const Link& NetCompare::pin_Aclr() const
{
return pin(0);
}
Link& NetCompare::pin_Clock()
{
return pin(1);
}
const Link& NetCompare::pin_Clock() const
{
return pin(1);
}
Link& NetCompare::pin_AGB()
{
return pin(2);
return pin(0);
}
const Link& NetCompare::pin_AGB() const
{
return pin(2);
return pin(0);
}
Link& NetCompare::pin_AGEB()
{
return pin(3);
return pin(1);
}
const Link& NetCompare::pin_AGEB() const
{
return pin(3);
return pin(1);
}
Link& NetCompare::pin_AEB()
{
return pin(4);
return pin(2);
}
const Link& NetCompare::pin_AEB() const
{
return pin(4);
return pin(2);
}
Link& NetCompare::pin_ANEB()
{
return pin(5);
return pin(3);
}
const Link& NetCompare::pin_ANEB() const
{
return pin(5);
return pin(3);
}
Link& NetCompare::pin_ALB()
{
return pin(6);
return pin(4);
}
const Link& NetCompare::pin_ALB() const
{
return pin(6);
return pin(4);
}
Link& NetCompare::pin_ALEB()
{
return pin(7);
return pin(5);
}
const Link& NetCompare::pin_ALEB() const
{
return pin(7);
return pin(5);
}
Link& NetCompare::pin_DataA()
{
return pin(8);
return pin(6);
}
const Link& NetCompare::pin_DataA() const
{
return pin(8);
return pin(6);
}
Link& NetCompare::pin_DataB()
{
return pin(9);
return pin(7);
}
const Link& NetCompare::pin_DataB() const
{
return pin(9);
return pin(7);
}
NetDivide::NetDivide(NetScope*sc, perm_string n, unsigned wr,

View File

@ -1040,6 +1040,9 @@ class NetCLShift : public NetNode {
* inputs is narrower then the other, it is up to the generator to
* make sure all the data pins are properly driven.
*
* The signed() property is true if the comparison is to be done to
* signed arguments. The result is always UNsigned.
*
* NOTE: This is not the same as the device used to support case
* compare. Case comparisons handle Vx and Vz values, whereas this
* device need not.
@ -1055,8 +1058,6 @@ class NetCompare : public NetNode {
bool get_signed() const;
void set_signed(bool);
Link& pin_Aclr();
Link& pin_Clock();
Link& pin_AGB();
Link& pin_AGEB();
Link& pin_AEB();
@ -1067,8 +1068,6 @@ class NetCompare : public NetNode {
Link& pin_DataA();
Link& pin_DataB();
const Link& pin_Aclr() const;
const Link& pin_Clock() const;
const Link& pin_AGB() const;
const Link& pin_AGEB() const;
const Link& pin_AEB() const;