From 1c17412223b483b4cdad9fed92fc0475b5020c85 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 24 Feb 2009 13:50:18 -0800 Subject: [PATCH] Allow constant delay literals to be handled as 64bits. This is mostly a minor definition change in the parsing of literal numbers by the vvp lexor. Allow for 64bit numbers in the .delay records, and have the code generator also able to cope with the situation. --- tgt-vvp/draw_net_input.c | 9 +++++---- tgt-vvp/eval_expr.c | 35 +++++++++++++++++++++++++++++++++++ tgt-vvp/vvp_priv.h | 1 + vvp/README.txt | 12 ++++++++---- vvp/lexor.lex | 13 +++++++++++-- vvp/parse.y | 2 +- 6 files changed, 61 insertions(+), 11 deletions(-) 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;