mirror of https://github.com/YosysHQ/yosys.git
Keep strings as strings in const ternary and concat
This commit is contained in:
parent
e935bb6eda
commit
891e4b5b0d
|
@ -171,6 +171,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2)
|
|||
is_output = false;
|
||||
is_reg = false;
|
||||
is_signed = false;
|
||||
is_string = false;
|
||||
range_valid = false;
|
||||
port_id = 0;
|
||||
range_left = -1;
|
||||
|
@ -591,6 +592,8 @@ bool AstNode::operator==(const AstNode &other) const
|
|||
return false;
|
||||
if (is_signed != other.is_signed)
|
||||
return false;
|
||||
if (is_string != other.is_string)
|
||||
return false;
|
||||
if (range_valid != other.range_valid)
|
||||
return false;
|
||||
if (port_id != other.port_id)
|
||||
|
@ -658,6 +661,14 @@ AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signe
|
|||
return node;
|
||||
}
|
||||
|
||||
// create an AST node for a constant (using a string in bit vector form as value)
|
||||
AstNode *AstNode::mkconst_str(const std::vector<RTLIL::State> &v)
|
||||
{
|
||||
AstNode *node = mkconst_str(RTLIL::Const(v).decode_string());
|
||||
log_assert(node->bits == v);
|
||||
return node;
|
||||
}
|
||||
|
||||
// create an AST node for a constant (using a string as value)
|
||||
AstNode *AstNode::mkconst_str(const std::string &str)
|
||||
{
|
||||
|
@ -671,6 +682,7 @@ AstNode *AstNode::mkconst_str(const std::string &str)
|
|||
}
|
||||
}
|
||||
AstNode *node = AstNode::mkconst_bits(data, false);
|
||||
node->is_string = true;
|
||||
node->str = str;
|
||||
return node;
|
||||
}
|
||||
|
@ -702,7 +714,7 @@ RTLIL::Const AstNode::asAttrConst()
|
|||
RTLIL::Const val;
|
||||
val.bits = bits;
|
||||
|
||||
if (!str.empty()) {
|
||||
if (is_string) {
|
||||
val.flags |= RTLIL::CONST_FLAG_STRING;
|
||||
log_assert(val.decode_string() == str);
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ namespace AST
|
|||
// node content - most of it is unused in most node types
|
||||
std::string str;
|
||||
std::vector<RTLIL::State> bits;
|
||||
bool is_input, is_output, is_reg, is_signed, range_valid;
|
||||
bool is_input, is_output, is_reg, is_signed, is_string, range_valid;
|
||||
int port_id, range_left, range_right;
|
||||
uint32_t integer;
|
||||
|
||||
|
@ -213,6 +213,7 @@ namespace AST
|
|||
// helper functions for creating AST nodes for constants
|
||||
static AstNode *mkconst_int(uint32_t v, bool is_signed, int width = 32);
|
||||
static AstNode *mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed);
|
||||
static AstNode *mkconst_str(const std::vector<RTLIL::State> &v);
|
||||
static AstNode *mkconst_str(const std::string &str);
|
||||
|
||||
// helper function for creating sign-extended const objects
|
||||
|
|
|
@ -1176,6 +1176,7 @@ skip_dynamic_range_lvalue_expansion:;
|
|||
// perform const folding when activated
|
||||
if (const_fold && newNode == NULL)
|
||||
{
|
||||
bool string_op;
|
||||
std::vector<RTLIL::State> tmp_bits;
|
||||
RTLIL::Const (*const_func)(const RTLIL::Const&, const RTLIL::Const&, bool, bool, int);
|
||||
RTLIL::Const dummy_arg;
|
||||
|
@ -1306,7 +1307,10 @@ skip_dynamic_range_lvalue_expansion:;
|
|||
choice = children[2];
|
||||
if (choice != NULL && choice->type == AST_CONSTANT) {
|
||||
RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint);
|
||||
newNode = mkconst_bits(y.bits, sign_hint);
|
||||
if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false)
|
||||
newNode = mkconst_str(y.bits);
|
||||
else
|
||||
newNode = mkconst_bits(y.bits, sign_hint);
|
||||
} else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) {
|
||||
RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint);
|
||||
RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint);
|
||||
|
@ -1319,19 +1323,22 @@ skip_dynamic_range_lvalue_expansion:;
|
|||
}
|
||||
break;
|
||||
case AST_CONCAT:
|
||||
string_op = !children.empty();
|
||||
for (auto it = children.begin(); it != children.end(); it++) {
|
||||
if ((*it)->type != AST_CONSTANT)
|
||||
goto not_const;
|
||||
if (!(*it)->is_string)
|
||||
string_op = false;
|
||||
tmp_bits.insert(tmp_bits.end(), (*it)->bits.begin(), (*it)->bits.end());
|
||||
}
|
||||
newNode = mkconst_bits(tmp_bits, false);
|
||||
newNode = string_op ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false);
|
||||
break;
|
||||
case AST_REPLICATE:
|
||||
if (children.at(0)->type != AST_CONSTANT || children.at(1)->type != AST_CONSTANT)
|
||||
goto not_const;
|
||||
for (int i = 0; i < children[0]->bitsAsConst().as_int(); i++)
|
||||
tmp_bits.insert(tmp_bits.end(), children.at(1)->bits.begin(), children.at(1)->bits.end());
|
||||
newNode = mkconst_bits(tmp_bits, false);
|
||||
newNode = children.at(1)->is_string ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false);
|
||||
break;
|
||||
default:
|
||||
not_const:
|
||||
|
|
Loading…
Reference in New Issue