3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-07 01:54:10 +00:00

Added $shift and $shiftx cell types (needed for correct part select behavior)

This commit is contained in:
Clifford Wolf 2014-07-29 14:42:33 +02:00
parent 48822e79a3
commit 397b00252d
12 changed files with 214 additions and 40 deletions

View file

@ -123,6 +123,8 @@ Things to do right away:
- Add to kernel/celltypes.h (incl. eval() handling for non-mem cells) - Add to kernel/celltypes.h (incl. eval() handling for non-mem cells)
- Add to InternalCellChecker::check() in kernel/rtlil.cc - Add to InternalCellChecker::check() in kernel/rtlil.cc
- Add to techlibs/common/simlib.v
- Add to techlibs/common/stdcells.v
Things to do after finalizing the cell interface: Things to do after finalizing the cell interface:

View file

@ -111,6 +111,8 @@ struct BtorDumper
cell_type_translation["$shl"] = "sll"; cell_type_translation["$shl"] = "sll";
cell_type_translation["$sshr"] = "sra"; cell_type_translation["$sshr"] = "sra";
cell_type_translation["$sshl"] = "sll"; cell_type_translation["$sshl"] = "sll";
cell_type_translation["$shift"] = "srl";
cell_type_translation["$shiftx"] = "srl";
cell_type_translation["$lt"] = "ult"; cell_type_translation["$lt"] = "ult";
cell_type_translation["$le"] = "ulte"; cell_type_translation["$le"] = "ulte";
cell_type_translation["$gt"] = "ugt"; cell_type_translation["$gt"] = "ugt";
@ -540,7 +542,7 @@ struct BtorDumper
} }
line_ref[cell->name]=line_num; line_ref[cell->name]=line_num;
} }
else if(cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl") else if(cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl" || cell->type == "$shift" || cell->type == "$shiftx")
{ {
log("writing binary cell - %s\n", cstr(cell->type)); log("writing binary cell - %s\n", cstr(cell->type));
int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int();

View file

@ -917,11 +917,17 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
children[0]->children[1]->clone() : children[0]->children[0]->clone()); children[0]->children[1]->clone() : children[0]->children[0]->clone());
fake_ast->children[0]->delete_children(); fake_ast->children[0]->delete_children();
RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL(); RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL();
if (id2ast->range_right != 0) if (id2ast->range_right != 0) {
shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right); shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right, fake_ast->children[1]->is_signed);
if (id2ast->range_swapped) fake_ast->children[1]->is_signed = true;
shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val); }
RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shr", width, fake_ast->children[0]->genRTLIL(), shift_val); if (id2ast->range_swapped) {
shift_val = current_module->Sub(NEW_ID, RTLIL::SigSpec(source_width - width), shift_val, fake_ast->children[1]->is_signed);
fake_ast->children[1]->is_signed = true;
}
if (SIZE(shift_val) >= 32)
fake_ast->children[1]->is_signed = true;
RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shiftx", width, fake_ast->children[0]->genRTLIL(), shift_val);
delete left_at_zero_ast; delete left_at_zero_ast;
delete right_at_zero_ast; delete right_at_zero_ast;
delete fake_ast; delete fake_ast;

View file

@ -276,7 +276,7 @@ RTLIL::Const RTLIL::const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const
return result; 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; int undef_bit_pos = -1;
BigInteger offset = const2big(arg2, false, undef_bit_pos) * direction; 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; RTLIL::Const arg1_ext = arg1;
extend_u0(arg1_ext, result_len, signed1); 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 RTLIL::const_shr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool, int result_len)
{ {
RTLIL::Const arg1_ext = arg1; RTLIL::Const arg1_ext = arg1;
extend_u0(arg1_ext, result_len, signed1); 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) RTLIL::Const RTLIL::const_sshl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
{ {
if (!signed1) if (!signed1)
return const_shl(arg1, arg2, signed1, signed2, result_len); 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) RTLIL::Const RTLIL::const_sshr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
{ {
if (!signed1) if (!signed1)
return const_shr(arg1, arg2, signed1, signed2, result_len); 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) RTLIL::Const RTLIL::const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)

View file

@ -75,6 +75,8 @@ struct CellTypes
cell_types.insert("$shr"); cell_types.insert("$shr");
cell_types.insert("$sshl"); cell_types.insert("$sshl");
cell_types.insert("$sshr"); cell_types.insert("$sshr");
cell_types.insert("$shift");
cell_types.insert("$shiftx");
cell_types.insert("$lt"); cell_types.insert("$lt");
cell_types.insert("$le"); cell_types.insert("$le");
cell_types.insert("$eq"); cell_types.insert("$eq");
@ -224,7 +226,7 @@ struct CellTypes
if (type == "$sshl" && !signed1) if (type == "$sshl" && !signed1)
type = "$shl"; 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") { type != "$pos" && type != "$neg" && type != "$not" && type != "$bu0") {
if (!signed1 || !signed2) if (!signed1 || !signed2)
signed1 = false, signed2 = false; signed1 = false, signed2 = false;
@ -248,6 +250,8 @@ struct CellTypes
HANDLE_CELL_TYPE(shr) HANDLE_CELL_TYPE(shr)
HANDLE_CELL_TYPE(sshl) HANDLE_CELL_TYPE(sshl)
HANDLE_CELL_TYPE(sshr) HANDLE_CELL_TYPE(sshr)
HANDLE_CELL_TYPE(shift)
HANDLE_CELL_TYPE(shiftx)
HANDLE_CELL_TYPE(lt) HANDLE_CELL_TYPE(lt)
HANDLE_CELL_TYPE(le) HANDLE_CELL_TYPE(le)
HANDLE_CELL_TYPE(eq) HANDLE_CELL_TYPE(eq)

View file

@ -474,7 +474,8 @@ namespace {
return; 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("\\A_SIGNED");
param_bool("\\B_SIGNED"); param_bool("\\B_SIGNED");
port("\\A", param("\\A_WIDTH")); 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(Shr, sig_a.size(), "$shr")
DEF_METHOD(Sshl, sig_a.size(), "$sshl") DEF_METHOD(Sshl, sig_a.size(), "$sshl")
DEF_METHOD(Sshr, sig_a.size(), "$sshr") 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(Lt, 1, "$lt")
DEF_METHOD(Le, 1, "$le") DEF_METHOD(Le, 1, "$le")
DEF_METHOD(Eq, 1, "$eq") DEF_METHOD(Eq, 1, "$eq")

View file

@ -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_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_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_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_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); 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* 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* 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* 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* 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* 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* 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* 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); 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 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 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 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 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 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 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 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); RTLIL::SigSpec Le (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false);

View file

@ -597,7 +597,7 @@ struct SatGen
return true; 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> a = importDefSigSpec(cell->get("\\A"), timestep);
std::vector<int> b = importDefSigSpec(cell->get("\\B"), 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"; char shift_left = cell->type == "$shl" || cell->type == "$sshl";
bool sign_extend = cell->type == "$sshr" && cell->parameters["\\A_SIGNED"].as_bool(); 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()) while (y.size() < a.size())
y.push_back(ez->literal()); y.push_back(ez->literal());
@ -616,9 +617,13 @@ struct SatGen
std::vector<int> tmp = a; std::vector<int> tmp = a;
for (size_t i = 0; i < b.size(); i++) 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()); std::vector<int> tmp_shifted(tmp.size());
for (size_t j = 0; j < tmp.size(); j++) { 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_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); tmp = ez->vec_ite(b.at(i), tmp_shifted, tmp);
@ -639,10 +644,15 @@ struct SatGen
tmp = undef_a; tmp = undef_a;
for (size_t i = 0; i < b.size(); i++) 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()); std::vector<int> tmp_shifted(tmp.size());
for (size_t j = 0; j < tmp.size(); j++) { 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_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); tmp = ez->vec_ite(b.at(i), tmp_shifted, tmp);
} }

View file

@ -695,6 +695,8 @@ struct MemoryShareWorker
cone_ct.cell_types.erase("$shr"); cone_ct.cell_types.erase("$shr");
cone_ct.cell_types.erase("$sshl"); cone_ct.cell_types.erase("$sshl");
cone_ct.cell_types.erase("$sshr"); cone_ct.cell_types.erase("$sshr");
cone_ct.cell_types.erase("$shift");
cone_ct.cell_types.erase("$shiftx");
modwalker.setup(design, module, &cone_ct); modwalker.setup(design, module, &cone_ct);

View file

@ -338,7 +338,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo
goto next_cell; goto next_cell;
} }
if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || cell->type == "$shift" || cell->type == "$shiftx" ||
cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" ||
cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt" || cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt" ||
cell->type == "$neg" || cell->type == "$add" || cell->type == "$sub" || cell->type == "$neg" || cell->type == "$add" || cell->type == "$sub" ||
@ -347,7 +347,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo
RTLIL::SigSpec sig_a = assign_map(cell->get("\\A")); RTLIL::SigSpec sig_a = assign_map(cell->get("\\A"));
RTLIL::SigSpec sig_b = cell->has("\\B") ? assign_map(cell->get("\\B")) : RTLIL::SigSpec(); RTLIL::SigSpec sig_b = cell->has("\\B") ? assign_map(cell->get("\\B")) : RTLIL::SigSpec();
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")
sig_a = RTLIL::SigSpec(); sig_a = RTLIL::SigSpec();
for (auto &bit : sig_a.to_sigbit_vector()) for (auto &bit : sig_a.to_sigbit_vector())
@ -360,8 +360,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo
if (0) { if (0) {
found_the_x_bit: found_the_x_bit:
cover_list("opt.opt_const.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$lt", "$le", "$ge", "$gt", cover_list("opt.opt_const.xbit", "$reduce_xor", "$reduce_xnor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
"$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type); "$lt", "$le", "$ge", "$gt", "$neg", "$add", "$sub", "$mul", "$div", "$mod", "$pow", cell->type);
if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" || if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor" ||
cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt") cell->type == "$lt" || cell->type == "$le" || cell->type == "$ge" || cell->type == "$gt")
replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx); replace_cell(assign_map, module, cell, "x-bit in input", "\\Y", RTLIL::State::Sx);
@ -572,7 +572,7 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo
identity_wrt_a = true; identity_wrt_a = 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")
{ {
RTLIL::SigSpec b = assign_map(cell->get("\\B")); RTLIL::SigSpec b = assign_map(cell->get("\\B"));
@ -603,9 +603,9 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo
if (identity_wrt_a || identity_wrt_b) if (identity_wrt_a || identity_wrt_b)
{ {
if (identity_wrt_a) if (identity_wrt_a)
cover_list("opt.opt_const.identwrt.a", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$mul", "$div", cell->type); cover_list("opt.opt_const.identwrt.a", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type);
if (identity_wrt_b) if (identity_wrt_b)
cover_list("opt.opt_const.identwrt.b", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$mul", "$div", cell->type); cover_list("opt.opt_const.identwrt.b", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type);
log("Replacing %s cell `%s' in module `%s' with identity for port %c.\n", log("Replacing %s cell `%s' in module `%s' with identity for port %c.\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B');
@ -792,6 +792,8 @@ static void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bo
FOLD_2ARG_CELL(shr) FOLD_2ARG_CELL(shr)
FOLD_2ARG_CELL(sshl) FOLD_2ARG_CELL(sshl)
FOLD_2ARG_CELL(sshr) FOLD_2ARG_CELL(sshr)
FOLD_2ARG_CELL(shift)
FOLD_2ARG_CELL(shiftx)
FOLD_2ARG_CELL(lt) FOLD_2ARG_CELL(lt)
FOLD_2ARG_CELL(le) FOLD_2ARG_CELL(le)

View file

@ -418,6 +418,54 @@ endmodule
// -------------------------------------------------------- // --------------------------------------------------------
module \$shift (A, B, Y);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 0;
parameter B_WIDTH = 0;
parameter Y_WIDTH = 0;
input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
output [Y_WIDTH-1:0] Y;
generate
if (B_SIGNED) begin:BLOCK1
assign Y = $signed(B) < 0 ? A << -B : A >> B;
end else begin:BLOCK2
assign Y = A >> B;
end
endgenerate
endmodule
// --------------------------------------------------------
module \$shiftx (A, B, Y);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 0;
parameter B_WIDTH = 0;
parameter Y_WIDTH = 0;
input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
output [Y_WIDTH-1:0] Y;
generate
if (B_SIGNED) begin:BLOCK1
assign Y = A[$signed(B) +: Y_WIDTH];
end else begin:BLOCK2
assign Y = A[B +: Y_WIDTH];
end
endgenerate
endmodule
// --------------------------------------------------------
module \$lt (A, B, Y); module \$lt (A, B, Y);
parameter A_SIGNED = 0; parameter A_SIGNED = 0;

View file

@ -129,12 +129,12 @@ endmodule
// -------------------------------------------------------- // --------------------------------------------------------
module \$__shift (X, A, Y); module \$__shift (XL, XR, A, Y);
parameter WIDTH = 1; parameter WIDTH = 1;
parameter SHIFT = 0; parameter SHIFT = 0;
input X; input XL, XR;
input [WIDTH-1:0] A; input [WIDTH-1:0] A;
output [WIDTH-1:0] Y; output [WIDTH-1:0] Y;
@ -142,12 +142,12 @@ genvar i;
generate generate
for (i = 0; i < WIDTH; i = i + 1) begin:V for (i = 0; i < WIDTH; i = i + 1) begin:V
if (i+SHIFT < 0) begin if (i+SHIFT < 0) begin
assign Y[i] = 0; assign Y[i] = XR;
end else end else
if (i+SHIFT < WIDTH) begin if (i+SHIFT < WIDTH) begin
assign Y[i] = A[i+SHIFT]; assign Y[i] = A[i+SHIFT];
end else begin end else begin
assign Y[i] = X; assign Y[i] = XL;
end end
end end
endgenerate endgenerate
@ -196,7 +196,8 @@ generate
.WIDTH(WIDTH), .WIDTH(WIDTH),
.SHIFT(0 - (2 ** (i > 30 ? 30 : i))) .SHIFT(0 - (2 ** (i > 30 ? 30 : i)))
) sh ( ) sh (
.X(0), .XL(1'b0),
.XR(1'b0),
.A(unshifted), .A(unshifted),
.Y(shifted) .Y(shifted)
); );
@ -255,7 +256,8 @@ generate
.WIDTH(WIDTH), .WIDTH(WIDTH),
.SHIFT(2 ** (i > 30 ? 30 : i)) .SHIFT(2 ** (i > 30 ? 30 : i))
) sh ( ) sh (
.X(0), .XL(1'b0),
.XR(1'b0),
.A(unshifted), .A(unshifted),
.Y(shifted) .Y(shifted)
); );
@ -314,7 +316,8 @@ generate
.WIDTH(WIDTH), .WIDTH(WIDTH),
.SHIFT(0 - (2 ** (i > 30 ? 30 : i))) .SHIFT(0 - (2 ** (i > 30 ? 30 : i)))
) sh ( ) sh (
.X(0), .XL(1'b0),
.XR(1'b0),
.A(unshifted), .A(unshifted),
.Y(shifted) .Y(shifted)
); );
@ -382,7 +385,8 @@ generate
.WIDTH(WIDTH), .WIDTH(WIDTH),
.SHIFT(2 ** (i > 30 ? 30 : i)) .SHIFT(2 ** (i > 30 ? 30 : i))
) sh ( ) sh (
.X(A_SIGNED && A[A_WIDTH-1]), .XL(A_SIGNED && A[A_WIDTH-1]),
.XR(1'b0),
.A(unshifted), .A(unshifted),
.Y(shifted) .Y(shifted)
); );
@ -401,6 +405,58 @@ endmodule
// -------------------------------------------------------- // --------------------------------------------------------
module \$shift (A, B, Y);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 1;
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
output [Y_WIDTH-1:0] Y;
generate
if (B_SIGNED) begin:BLOCK1
assign Y = $signed(B) < 0 ? A << -B : A >> B;
end else begin:BLOCK2
assign Y = A >> B;
end
endgenerate
endmodule
// --------------------------------------------------------
module \$shiftx (A, B, Y);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 1;
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
output [Y_WIDTH-1:0] Y;
\$shift #(
.A_SIGNED(A_SIGNED),
.B_SIGNED(B_SIGNED),
.A_WIDTH(A_WIDTH),
.B_WIDTH(B_WIDTH),
.Y_WIDTH(Y_WIDTH),
) sh (
.A(A),
.B(B),
.Y(Y)
);
endmodule
// --------------------------------------------------------
module \$__fulladd (A, B, C, X, Y); module \$__fulladd (A, B, C, X, Y);
// {X, Y} = A + B + C // {X, Y} = A + B + C