mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-06 06:03:23 +00:00
Added support for unsized constants, fixes #1022
Includes work from @sumit0190 and @AaronKel
This commit is contained in:
parent
2058c7c53b
commit
34417ce55f
5 changed files with 45 additions and 13 deletions
|
@ -71,7 +71,7 @@ static int my_ilog2(int x)
|
|||
}
|
||||
|
||||
// parse a binary, decimal, hexadecimal or octal number with support for special bits ('x', 'z' and '?')
|
||||
static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int len_in_bits, int base, char case_type)
|
||||
static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int len_in_bits, int base, char case_type, bool is_unsized)
|
||||
{
|
||||
// all digits in string (MSB at index 0)
|
||||
std::vector<uint8_t> digits;
|
||||
|
@ -129,6 +129,9 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le
|
|||
return;
|
||||
}
|
||||
|
||||
if (is_unsized && (len > len_in_bits))
|
||||
log_file_error(current_filename, get_line_num(), "Unsized constant must have width of 1 bit, but have %d bits!\n", len);
|
||||
|
||||
for (len = len - 1; len >= 0; len--)
|
||||
if (data[len] == RTLIL::S1)
|
||||
break;
|
||||
|
@ -186,7 +189,7 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn
|
|||
// Simple base-10 integer
|
||||
if (*endptr == 0) {
|
||||
std::vector<RTLIL::State> data;
|
||||
my_strtobin(data, str, -1, 10, case_type);
|
||||
my_strtobin(data, str, -1, 10, case_type, false);
|
||||
if (data.back() == RTLIL::S1)
|
||||
data.push_back(RTLIL::S0);
|
||||
return AstNode::mkconst_bits(data, true);
|
||||
|
@ -201,6 +204,7 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn
|
|||
{
|
||||
std::vector<RTLIL::State> data;
|
||||
bool is_signed = false;
|
||||
bool is_unsized = false;
|
||||
if (*(endptr+1) == 's') {
|
||||
is_signed = true;
|
||||
endptr++;
|
||||
|
@ -209,28 +213,34 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type, bool warn
|
|||
{
|
||||
case 'b':
|
||||
case 'B':
|
||||
my_strtobin(data, endptr+2, len_in_bits, 2, case_type);
|
||||
my_strtobin(data, endptr+2, len_in_bits, 2, case_type, false);
|
||||
break;
|
||||
case 'o':
|
||||
case 'O':
|
||||
my_strtobin(data, endptr+2, len_in_bits, 8, case_type);
|
||||
my_strtobin(data, endptr+2, len_in_bits, 8, case_type, false);
|
||||
break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
my_strtobin(data, endptr+2, len_in_bits, 10, case_type);
|
||||
my_strtobin(data, endptr+2, len_in_bits, 10, case_type, false);
|
||||
break;
|
||||
case 'h':
|
||||
case 'H':
|
||||
my_strtobin(data, endptr+2, len_in_bits, 16, case_type);
|
||||
my_strtobin(data, endptr+2, len_in_bits, 16, case_type, false);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
char next_char = char(tolower(*(endptr+1)));
|
||||
if (next_char == '0' || next_char == '1' || next_char == 'x' || next_char == 'z') {
|
||||
my_strtobin(data, endptr+1, 1, 2, case_type, true);
|
||||
is_unsized = true;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (len_in_bits < 0) {
|
||||
if (is_signed && data.back() == RTLIL::S1)
|
||||
data.push_back(RTLIL::S0);
|
||||
}
|
||||
return AstNode::mkconst_bits(data, is_signed);
|
||||
return AstNode::mkconst_bits(data, is_signed, is_unsized);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue