diff --git a/tgt-vvp/draw_net_input.c b/tgt-vvp/draw_net_input.c index dc2f14e54..6d527077d 100644 --- a/tgt-vvp/draw_net_input.c +++ b/tgt-vvp/draw_net_input.c @@ -388,10 +388,11 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) number_is_immediate(d_fall, 64, 0) && number_is_immediate(d_decay, 64, 0)) { - fprintf(vvp_out, "L_%p .delay (%lu,%lu,%lu) L_%p/d;\n", - cptr, get_number_immediate(d_rise), - get_number_immediate(d_rise), - get_number_immediate(d_rise), cptr); + fprintf(vvp_out, "L_%p .delay " + "(%" PRIu64 ",%" PRIu64 ",%" PRIu64 ") L_%p/d;\n", + cptr, get_number_immediate64(d_rise), + get_number_immediate64(d_rise), + get_number_immediate64(d_rise), cptr); } else { ivl_signal_t sig; diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 87c4201ca..12fb4abbd 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -131,6 +131,41 @@ long get_number_immediate(ivl_expr_t ex) return imm; } +uint64_t get_number_immediate64(ivl_expr_t ex) +{ + uint64_t imm = 0; + unsigned idx; + + switch (ivl_expr_type(ex)) { + case IVL_EX_ULONG: + imm = ivl_expr_uvalue(ex); + break; + + case IVL_EX_NUMBER: { + const char*bits = ivl_expr_bits(ex); + unsigned nbits = ivl_expr_width(ex); + for (idx = 0 ; idx < nbits ; idx += 1) switch (bits[idx]){ + case '0': + break; + case '1': + assert(idx < 64); + imm |= UINT64_C(1) << idx; + break; + default: + assert(0); + } + if (ivl_expr_signed(ex) && bits[nbits-1]=='1' && nbits < 64) + imm |= -UINT64_C(1) << nbits; + break; + } + + default: + assert(0); + } + + return imm; +} + static void eval_logic_into_integer(ivl_expr_t expr, unsigned ix) { switch (ivl_expr_type(expr)) { diff --git a/tgt-vvp/vvp_priv.h b/tgt-vvp/vvp_priv.h index b3ca6efd8..fda6bb5ad 100644 --- a/tgt-vvp/vvp_priv.h +++ b/tgt-vvp/vvp_priv.h @@ -271,6 +271,7 @@ extern unsigned allocate_vector_exp(ivl_expr_t exp, unsigned wid, extern int number_is_unknown(ivl_expr_t ex); extern int number_is_immediate(ivl_expr_t ex, unsigned lim_wid, int negative_is_ok); extern long get_number_immediate(ivl_expr_t ex); +extern uint64_t get_number_immediate64(ivl_expr_t ex); /* * draw_eval_real evaluates real value expressions. The return code diff --git a/vvp/README.txt b/vvp/README.txt index 8c209b6a7..9c35a1c06 100644 --- a/vvp/README.txt +++ b/vvp/README.txt @@ -89,6 +89,10 @@ There are some special symbols that in certain contexts have special meanings. As inputs to functors, the symbols "C<0>", "C<1>", "C" and "C" represent a constant driver of the given value. +NUMBERS: + +decimal number tokens are limited to 64bits, and are unsigned. Some +contexts may constrain the number size further. SCOPE STATEMENTS: @@ -375,10 +379,10 @@ times that are used for delay. .delay ( , , ) ; .delay , , , ; -The first form above takes three constant numbers as the initial -delay, and takes a single input. The second form takes 4 net inputs, -with the first being the value to delay, and the remaining to be the -delay values to use. +The first form above takes three constant (64bit) numbers as the +initial delay, and takes a single input. The second form takes 4 net +inputs, with the first being the value to delay, and the remaining to +be the delay values to use. MODULE PATH DELAY STATEMENTS: diff --git a/vvp/lexor.lex b/vvp/lexor.lex index 42f3c3a58..94d454115 100644 --- a/vvp/lexor.lex +++ b/vvp/lexor.lex @@ -32,6 +32,15 @@ static char* strdupnew(char const *str) { return str ? strcpy(new char [strlen(str)+1], str) : 0; } + + inline uint64_t strtouint64(const char*str, char**endptr, int base) +{ + if (sizeof(unsigned long) >= sizeof(uint64_t)) + return strtoul(str, endptr, base); + else + return strtoull(str, endptr, base); +} + %} %% @@ -204,11 +213,11 @@ static char* strdupnew(char const *str) return T_INSTR; } [0-9][0-9]* { - yylval.numb = strtoul(yytext, 0, 0); + yylval.numb = strtouint64(yytext, 0, 0); return T_NUMBER; } "0x"[0-9a-fA-F]+ { - yylval.numb = strtoul(yytext, 0, 0); + yylval.numb = strtouint64(yytext, 0, 0); return T_NUMBER; } /* Handle some specialized constant/literals as symbols. */ diff --git a/vvp/parse.y b/vvp/parse.y index d2a296b74..ae2454891 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -47,7 +47,7 @@ static struct __vpiModPath*modpath_dst = 0; %union { char*text; char **table; - unsigned long numb; + uint64_t numb; bool flag; comp_operands_t opa;