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:
parent
55b8ff4441
commit
25f6282a54
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
72
netlist.cc
72
netlist.cc
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue