3
0
Fork 0
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:
Miodrag Milanovic 2019-05-27 11:42:10 +02:00
parent 2058c7c53b
commit 34417ce55f
5 changed files with 45 additions and 13 deletions

View file

@ -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;