diff --git a/ivtest/gold/br_gh889-vlog95.gold b/ivtest/gold/br_gh889-vlog95.gold new file mode 100644 index 000000000..d914ee6c7 --- /dev/null +++ b/ivtest/gold/br_gh889-vlog95.gold @@ -0,0 +1,6 @@ +SDF WARNING: ivltests/br_gh889.sdf:18: loaded from vlog95.v:17: Wildcard cell instance specification (*) currently not supported. + 0 A=x, B=x, Q=x + 10 A=1, B=1, Q=x + 11 A=1, B=1, Q=0 + 20 A=1, B=0, Q=0 + 21 A=1, B=0, Q=1 diff --git a/ivtest/gold/br_gh889.gold b/ivtest/gold/br_gh889.gold new file mode 100644 index 000000000..fda02b9fb --- /dev/null +++ b/ivtest/gold/br_gh889.gold @@ -0,0 +1,6 @@ +SDF WARNING: ivltests/br_gh889.sdf:18: loaded from ./ivltests/br_gh889.v:21: Wildcard cell instance specification (*) currently not supported. + 0 A=x, B=x, Q=x + 10 A=1, B=1, Q=x + 11 A=1, B=1, Q=0 + 20 A=1, B=0, Q=0 + 21 A=1, B=0, Q=1 diff --git a/ivtest/ivltests/br_gh889.sdf b/ivtest/ivltests/br_gh889.sdf new file mode 100644 index 000000000..708e7a192 --- /dev/null +++ b/ivtest/ivltests/br_gh889.sdf @@ -0,0 +1,27 @@ + /* C-style comments. */ + +(DELAYFILE +(SDFVERSION "OVI 2.1") +(DESIGN "xor_rtl") +(DATE "Sun Apr 1 11:57:01 2007") +(VENDOR "Icarus Test") +(PROGRAM "Hand Coded") +(VERSION "0.0") +(DIVIDER /) +(VOLTAGE 3.30:3.30:3.30) +(PROCESS "nom_pvt") +(TEMPERATURE 25.00:25.00:25.00) +(TIMESCALE 1ns) + +(CELL // C++ style comment + (CELLTYPE "XOR20") + (INSTANCE *) + (DELAY + (ABSOLUTE + (IOPATH A Q (3.0:3.0:3.0) (3.0:3.0:3.0)) + (IOPATH B Q (3.0:3.0:3.0) (3.0:3.0:3.0)) + ) + ) +) + +) diff --git a/ivtest/ivltests/br_gh889.v b/ivtest/ivltests/br_gh889.v new file mode 100644 index 000000000..d2e1e8f10 --- /dev/null +++ b/ivtest/ivltests/br_gh889.v @@ -0,0 +1,31 @@ +`celldefine +module XOR20 (input A, input B, output Q); + xor (Q,B,A); + + specify + (A => Q) = (1,1); + (B => Q) = (1,1); + endspecify +endmodule + +`endcelldefine + +module tb; + + reg a, b; + wire q; + XOR20 dut(.A(a), .B(b), .Q(q)); + + initial begin + $monitor($time,, "A=%b, B=%b, Q=%b", a, b, q); + $sdf_annotate("ivltests/br_gh889.sdf"); + + #10 ; + a = 1; + b = 1; + #10 ; + b = 0; + #10 $finish(0); + end + +endmodule // tb diff --git a/ivtest/regress-vlg.list b/ivtest/regress-vlg.list index 858dc4bc9..9fa169012 100644 --- a/ivtest/regress-vlg.list +++ b/ivtest/regress-vlg.list @@ -356,6 +356,7 @@ br_gh782f normal ivltests br_gh788 normal,-gno-io-range-error,-Wno-anachronisms ivltests gold=br_gh788.gold br_gh793 normal ivltests br_gh827 normal ivltests gold=br_gh827.gold +br_gh889 normal,-gspecify ivltests gold=br_gh889.gold br_ml20150315 normal ivltests gold=br_ml_20150315.gold br_ml20150321 CE ivltests br_mw20171108 normal ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index e901d8115..810fb91ad 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -818,6 +818,7 @@ br1003c normal,-g2009 ivltests gold=br1003c-vlog95.gold br1003d normal,-g2009 ivltests gold=br1003d-vlog95.gold br1007 normal,-Wselect-range ivltests gold=br1007-vlog95.gold br_gh230 RE ivltests gold=br_gh230-vlog95.gold +br_gh889 normal,-gspecify ivltests gold=br_gh889-vlog95.gold eofmt_percent normal ivltests gold=eofmt_percent-vlog95.gold fatal_et_al normal ivltests gold=fatal_et_al-vlog95.gold fdisplay3 RE ivltests gold=fdisplay3-vlog95.gold diff --git a/vpi/sdf_parse.y b/vpi/sdf_parse.y index 588fe3b69..a1fefcb81 100644 --- a/vpi/sdf_parse.y +++ b/vpi/sdf_parse.y @@ -1,7 +1,7 @@ %{ /* - * Copyright (c) 1998-2019 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2023 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -227,7 +227,7 @@ cell_list cell : '(' K_CELL celltype cell_instance - { sdf_select_instance($3, $4); /* find the instance in the design */} + { sdf_select_instance($3, $4, @4.first_line); /* find the instance in the design */} timing_spec_list_opt ')' { free($3); @@ -296,7 +296,7 @@ del_def_list del_def : '(' K_IOPATH port_spec port_instance delval_list ')' - { sdf_iopath_delays($3.vpi_edge, $3.string_val, $4, &$5); + { sdf_iopath_delays($3.vpi_edge, $3.string_val, $4, &$5, @2.first_line); free($3.string_val); free($4); } diff --git a/vpi/sdf_priv.h b/vpi/sdf_priv.h index 9a0dc9882..8baa386d3 100644 --- a/vpi/sdf_priv.h +++ b/vpi/sdf_priv.h @@ -1,7 +1,7 @@ #ifndef IVL_sdf_priv_h #define IVL_sdf_priv_h /* - * Copyright (c) 2007-2014 Stephen Williams (steve@icarus.com) + * Copyright (c) 2007-2023 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -48,8 +48,10 @@ struct sdf_delval_list_s { struct sdf_delay_s val[12]; }; -extern void sdf_select_instance(const char*celltype, const char*inst); +extern void sdf_select_instance(const char*celltype, const char*inst, + const int sdf_lineno); extern void sdf_iopath_delays(int vpi_edge, const char*src, const char*dst, - const struct sdf_delval_list_s*delval); + const struct sdf_delval_list_s*delval, + const int sdf_lineno); #endif /* IVL_sdf_priv_h */ diff --git a/vpi/sys_sdf.c b/vpi/sys_sdf.c index 36fa3c723..85bc491d7 100644 --- a/vpi/sys_sdf.c +++ b/vpi/sys_sdf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2021 Stephen Williams (steve@icarus.com) + * Copyright (c) 2007-2023 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -36,6 +36,7 @@ static vpiHandle sdf_scope; static vpiHandle sdf_callh = 0; /* The cell in process. */ static vpiHandle sdf_cur_cell; +static char* sdf_fname = NULL; static vpiHandle find_scope(vpiHandle scope, const char*name) { @@ -56,23 +57,29 @@ static vpiHandle find_scope(vpiHandle scope, const char*name) return 0; } +void sdf_warn_file_line(const int sdf_lineno) +{ + vpi_printf("SDF WARNING: %s:%d: loaded from %s:%d: ", + sdf_fname, sdf_lineno, + vpi_get_str(vpiFile, sdf_callh), + (int)vpi_get(vpiLineNo, sdf_callh)); +} + /* * These functions are called by the SDF parser during parsing to * handling items discovered in the parse. */ -void sdf_select_instance(const char*celltype, const char*cellinst) +void sdf_select_instance(const char*celltype, const char*cellinst, const int sdf_lineno) { char buffer[128]; /* Test for wildcard character */ if (cellinst == NULL) { - vpi_printf("SDF WARNING: %s:%d: ", - vpi_get_str(vpiFile, sdf_callh), - (int)vpi_get(vpiLineNo, sdf_callh)); - vpi_printf("Wildcard cell instance specification (*) currently not supported.\n"); - sdf_cur_cell = 0; - return; + sdf_warn_file_line(sdf_lineno); + vpi_printf("Wildcard cell instance specification (*) currently not supported.\n"); + sdf_cur_cell = 0; + return; } /* First follow the hierarchical parts of the cellinst name to @@ -89,9 +96,7 @@ void sdf_select_instance(const char*celltype, const char*cellinst) vpiHandle tmp_scope = find_scope(scope, buffer); if (tmp_scope == 0) { - vpi_printf("SDF WARNING: %s:%d: ", - vpi_get_str(vpiFile, sdf_callh), - (int)vpi_get(vpiLineNo, sdf_callh)); + sdf_warn_file_line(sdf_lineno); vpi_printf("Cannot find %s in scope %s.\n", buffer, vpi_get_str(vpiFullName, scope)); break; @@ -108,8 +113,7 @@ void sdf_select_instance(const char*celltype, const char*cellinst) else sdf_cur_cell = find_scope(scope, src); if (sdf_cur_cell == 0) { - vpi_printf("SDF WARNING: %s:%d: ", vpi_get_str(vpiFile, sdf_callh), - (int)vpi_get(vpiLineNo, sdf_callh)); + sdf_warn_file_line(sdf_lineno); vpi_printf("Unable to find %s in scope %s.\n", src, vpi_get_str(vpiFullName, scope)); return; @@ -117,16 +121,14 @@ void sdf_select_instance(const char*celltype, const char*cellinst) /* The scope that matches should be a module. */ if (vpi_get(vpiType,sdf_cur_cell) != vpiModule) { - vpi_printf("SDF WARNING: %s:%d: ", vpi_get_str(vpiFile, sdf_callh), - (int)vpi_get(vpiLineNo, sdf_callh)); + sdf_warn_file_line(sdf_lineno); vpi_printf("Scope %s in %s is not a module.\n", src, vpi_get_str(vpiFullName, scope)); } /* The matching scope (a module) should have the expected type. */ if (strcmp(celltype,vpi_get_str(vpiDefName,sdf_cur_cell)) != 0) { - vpi_printf("SDF WARNING: %s:%d: ", vpi_get_str(vpiFile, sdf_callh), - (int)vpi_get(vpiLineNo, sdf_callh)); + sdf_warn_file_line(sdf_lineno); vpi_printf("Module %s in %s is not a %s; it is a ", src, vpi_get_str(vpiFullName, scope), celltype); vpi_printf("%s\n", vpi_get_str(vpiDefName, sdf_cur_cell)); @@ -146,7 +148,8 @@ static const char*edge_str(int vpi_edge) } void sdf_iopath_delays(int vpi_edge, const char*src, const char*dst, - const struct sdf_delval_list_s*delval_list) + const struct sdf_delval_list_s*delval_list, + const int sdf_lineno) { vpiHandle iter, path; int match_count = 0; @@ -211,8 +214,7 @@ void sdf_iopath_delays(int vpi_edge, const char*src, const char*dst, } if (match_count == 0) { - vpi_printf("SDF WARNING: %s:%d: ", vpi_get_str(vpiFile, sdf_callh), - (int)vpi_get(vpiLineNo, sdf_callh)); + sdf_warn_file_line(sdf_lineno); vpi_printf("Unable to match ModPath %s%s -> %s in %s\n", edge_str(vpi_edge), src, dst, vpi_get_str(vpiFullName, sdf_cur_cell)); @@ -317,6 +319,7 @@ static PLI_INT32 sys_sdf_annotate_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) free(fname); return 0; } + sdf_fname = fname; /* The optional second argument is the scope to annotate. */ sdf_scope = vpi_scan(argv); @@ -332,6 +335,7 @@ static PLI_INT32 sys_sdf_annotate_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) sdf_callh = 0; fclose(sdf_fd); + sdf_fname = NULL; free(fname); return 0; }