mirror of
https://github.com/YosysHQ/yosys
synced 2025-07-23 20:58:55 +00:00
Added $shift and $shiftx cell types (needed for correct part select behavior)
This commit is contained in:
parent
48822e79a3
commit
397b00252d
12 changed files with 214 additions and 40 deletions
|
@ -276,7 +276,7 @@ RTLIL::Const RTLIL::const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const
|
|||
return result;
|
||||
}
|
||||
|
||||
static RTLIL::Const const_shift(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool sign_ext, int direction, int result_len)
|
||||
static RTLIL::Const const_shift_worker(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool sign_ext, int direction, int result_len)
|
||||
{
|
||||
int undef_bit_pos = -1;
|
||||
BigInteger offset = const2big(arg2, false, undef_bit_pos) * direction;
|
||||
|
@ -305,28 +305,61 @@ RTLIL::Const RTLIL::const_shl(const RTLIL::Const &arg1, const RTLIL::Const &arg2
|
|||
{
|
||||
RTLIL::Const arg1_ext = arg1;
|
||||
extend_u0(arg1_ext, result_len, signed1);
|
||||
return const_shift(arg1_ext, arg2, false, -1, result_len);
|
||||
return const_shift_worker(arg1_ext, arg2, false, -1, result_len);
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_shr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len)
|
||||
{
|
||||
RTLIL::Const arg1_ext = arg1;
|
||||
extend_u0(arg1_ext, result_len, signed1);
|
||||
return const_shift(arg1_ext, arg2, false, +1, result_len);
|
||||
return const_shift_worker(arg1_ext, arg2, false, +1, result_len);
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_sshl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
|
||||
{
|
||||
if (!signed1)
|
||||
return const_shl(arg1, arg2, signed1, signed2, result_len);
|
||||
return const_shift(arg1, arg2, true, -1, result_len);
|
||||
return const_shift_worker(arg1, arg2, true, -1, result_len);
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_sshr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
|
||||
{
|
||||
if (!signed1)
|
||||
return const_shr(arg1, arg2, signed1, signed2, result_len);
|
||||
return const_shift(arg1, arg2, true, +1, result_len);
|
||||
return const_shift_worker(arg1, arg2, true, +1, result_len);
|
||||
}
|
||||
|
||||
static RTLIL::Const const_shift_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool, bool signed2, int result_len, RTLIL::State other_bits)
|
||||
{
|
||||
int undef_bit_pos = -1;
|
||||
BigInteger offset = const2big(arg2, signed2, undef_bit_pos);
|
||||
|
||||
if (result_len < 0)
|
||||
result_len = arg1.bits.size();
|
||||
|
||||
RTLIL::Const result(RTLIL::State::Sx, result_len);
|
||||
if (undef_bit_pos >= 0)
|
||||
return result;
|
||||
|
||||
for (int i = 0; i < result_len; i++) {
|
||||
BigInteger pos = BigInteger(i) + offset;
|
||||
if (pos < 0 || pos >= arg1.bits.size())
|
||||
result.bits[i] = other_bits;
|
||||
else
|
||||
result.bits[i] = arg1.bits[pos.toInt()];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_shift(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
|
||||
{
|
||||
return const_shift_shiftx(arg1, arg2, signed1, signed2, result_len, RTLIL::State::S0);
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_shiftx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
|
||||
{
|
||||
return const_shift_shiftx(arg1, arg2, signed1, signed2, result_len, RTLIL::State::Sx);
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
|
||||
|
|
|
@ -75,6 +75,8 @@ struct CellTypes
|
|||
cell_types.insert("$shr");
|
||||
cell_types.insert("$sshl");
|
||||
cell_types.insert("$sshr");
|
||||
cell_types.insert("$shift");
|
||||
cell_types.insert("$shiftx");
|
||||
cell_types.insert("$lt");
|
||||
cell_types.insert("$le");
|
||||
cell_types.insert("$eq");
|
||||
|
@ -224,7 +226,7 @@ struct CellTypes
|
|||
if (type == "$sshl" && !signed1)
|
||||
type = "$shl";
|
||||
|
||||
if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" &&
|
||||
if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && type != "$shift" && type != "$shiftx" &&
|
||||
type != "$pos" && type != "$neg" && type != "$not" && type != "$bu0") {
|
||||
if (!signed1 || !signed2)
|
||||
signed1 = false, signed2 = false;
|
||||
|
@ -248,6 +250,8 @@ struct CellTypes
|
|||
HANDLE_CELL_TYPE(shr)
|
||||
HANDLE_CELL_TYPE(sshl)
|
||||
HANDLE_CELL_TYPE(sshr)
|
||||
HANDLE_CELL_TYPE(shift)
|
||||
HANDLE_CELL_TYPE(shiftx)
|
||||
HANDLE_CELL_TYPE(lt)
|
||||
HANDLE_CELL_TYPE(le)
|
||||
HANDLE_CELL_TYPE(eq)
|
||||
|
|
|
@ -474,7 +474,8 @@ namespace {
|
|||
return;
|
||||
}
|
||||
|
||||
if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr") {
|
||||
if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" ||
|
||||
cell->type == "$shift" || cell->type == "$shiftx") {
|
||||
param_bool("\\A_SIGNED");
|
||||
param_bool("\\B_SIGNED");
|
||||
port("\\A", param("\\A_WIDTH"));
|
||||
|
@ -1101,6 +1102,8 @@ DEF_METHOD(Shl, sig_a.size(), "$shl")
|
|||
DEF_METHOD(Shr, sig_a.size(), "$shr")
|
||||
DEF_METHOD(Sshl, sig_a.size(), "$sshl")
|
||||
DEF_METHOD(Sshr, sig_a.size(), "$sshr")
|
||||
DEF_METHOD(Shift, sig_a.size(), "$shift")
|
||||
DEF_METHOD(Shiftx, sig_a.size(), "$shiftx")
|
||||
DEF_METHOD(Lt, 1, "$lt")
|
||||
DEF_METHOD(Le, 1, "$le")
|
||||
DEF_METHOD(Eq, 1, "$eq")
|
||||
|
|
|
@ -172,6 +172,8 @@ namespace RTLIL
|
|||
RTLIL::Const const_shr (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
||||
RTLIL::Const const_sshl (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
||||
RTLIL::Const const_sshr (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
||||
RTLIL::Const const_shift (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
||||
RTLIL::Const const_shiftx (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
||||
|
||||
RTLIL::Const const_lt (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
||||
RTLIL::Const const_le (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
||||
|
@ -474,10 +476,12 @@ public:
|
|||
RTLIL::Cell* addReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
|
||||
RTLIL::Cell* addShl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addShr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addSshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addSshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addShl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addShr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addSshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addSshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addShift (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addShiftx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
|
||||
RTLIL::Cell* addLt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
RTLIL::Cell* addLe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false);
|
||||
|
@ -551,10 +555,12 @@ public:
|
|||
RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false);
|
||||
RTLIL::SigSpec ReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false);
|
||||
|
||||
RTLIL::SigSpec Shl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
RTLIL::SigSpec Shr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
RTLIL::SigSpec Sshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
RTLIL::SigSpec Sshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
RTLIL::SigSpec Shl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
RTLIL::SigSpec Shr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
RTLIL::SigSpec Sshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
RTLIL::SigSpec Sshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
RTLIL::SigSpec Shift (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
RTLIL::SigSpec Shiftx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
|
||||
RTLIL::SigSpec Lt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
RTLIL::SigSpec Le (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);
|
||||
|
|
|
@ -597,7 +597,7 @@ struct SatGen
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr")
|
||||
if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx")
|
||||
{
|
||||
std::vector<int> a = importDefSigSpec(cell->get("\\A"), timestep);
|
||||
std::vector<int> b = importDefSigSpec(cell->get("\\B"), timestep);
|
||||
|
@ -605,6 +605,7 @@ struct SatGen
|
|||
|
||||
char shift_left = cell->type == "$shl" || cell->type == "$sshl";
|
||||
bool sign_extend = cell->type == "$sshr" && cell->parameters["\\A_SIGNED"].as_bool();
|
||||
bool shift_shiftx = cell->type == "$shift" || cell->type == "$shiftx";
|
||||
|
||||
while (y.size() < a.size())
|
||||
y.push_back(ez->literal());
|
||||
|
@ -616,9 +617,13 @@ struct SatGen
|
|||
std::vector<int> tmp = a;
|
||||
for (size_t i = 0; i < b.size(); i++)
|
||||
{
|
||||
bool shift_left_this = shift_left;
|
||||
if (shift_shiftx && i == b.size()-1 && cell->parameters["\\B_SIGNED"].as_bool())
|
||||
shift_left_this = true;
|
||||
|
||||
std::vector<int> tmp_shifted(tmp.size());
|
||||
for (size_t j = 0; j < tmp.size(); j++) {
|
||||
int idx = j + (1 << (i > 30 ? 30 : i)) * (shift_left ? -1 : +1);
|
||||
int idx = j + (1 << (i > 30 ? 30 : i)) * (shift_left_this ? -1 : +1);
|
||||
tmp_shifted.at(j) = (0 <= idx && idx < int(tmp.size())) ? tmp.at(idx) : sign_extend ? tmp.back() : ez->FALSE;
|
||||
}
|
||||
tmp = ez->vec_ite(b.at(i), tmp_shifted, tmp);
|
||||
|
@ -639,10 +644,15 @@ struct SatGen
|
|||
tmp = undef_a;
|
||||
for (size_t i = 0; i < b.size(); i++)
|
||||
{
|
||||
bool shift_left_this = shift_left;
|
||||
if (shift_shiftx && i == b.size()-1 && cell->parameters["\\B_SIGNED"].as_bool())
|
||||
shift_left_this = true;
|
||||
|
||||
std::vector<int> tmp_shifted(tmp.size());
|
||||
for (size_t j = 0; j < tmp.size(); j++) {
|
||||
int idx = j + (1 << (i > 30 ? 30 : i)) * (shift_left ? -1 : +1);
|
||||
tmp_shifted.at(j) = (0 <= idx && idx < int(tmp.size())) ? tmp.at(idx) : sign_extend ? tmp.back() : ez->FALSE;
|
||||
int idx = j + (1 << (i > 30 ? 30 : i)) * (shift_left_this ? -1 : +1);
|
||||
tmp_shifted.at(j) = (0 <= idx && idx < int(tmp.size())) ? tmp.at(idx) :
|
||||
sign_extend ? tmp.back() : cell->type == "$shiftx" ? ez->TRUE : ez->FALSE;
|
||||
}
|
||||
tmp = ez->vec_ite(b.at(i), tmp_shifted, tmp);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue