/* GHDL Wavefile reader library. Copyright (C) 2005-2017 Tristan Gingold This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _LIBGHW_H_ #define _LIBGHW_H_ #include #include /* To be libraries friendly. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* The libghw uses the standard c99 int32_t and int64_t. They are declared in stdint.h. Header inttypes.h includes stdint.h and provides macro for printf and co specifiers. Use it if known to be available. */ #if defined(__cplusplus) || \ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ defined(HAVE_INTTYPES_H) /* Use C99 standard header. */ #include #define GHWPRI64 "%" PRId64 #define GHWPRI32 "%" PRId32 #else #include #define GHWPRI64 "%lld" #define GHWPRI32 "%d" #endif enum ghdl_rtik { ghdl_rtik_top, /* 0 */ ghdl_rtik_library, ghdl_rtik_package, ghdl_rtik_package_body, ghdl_rtik_entity, ghdl_rtik_architecture, /* 5 */ ghdl_rtik_process, ghdl_rtik_block, ghdl_rtik_if_generate, ghdl_rtik_for_generate, ghdl_rtik_instance, ghdl_rtik_constant, ghdl_rtik_iterator, ghdl_rtik_variable, ghdl_rtik_signal, ghdl_rtik_file, ghdl_rtik_port, ghdl_rtik_generic, ghdl_rtik_alias, ghdl_rtik_guard, ghdl_rtik_component, ghdl_rtik_attribute, ghdl_rtik_type_b2, /* 22 */ ghdl_rtik_type_e8, ghdl_rtik_type_e32, ghdl_rtik_type_i32, /* 25 */ ghdl_rtik_type_i64, ghdl_rtik_type_f64, ghdl_rtik_type_p32, ghdl_rtik_type_p64, ghdl_rtik_type_access, /* 30 */ ghdl_rtik_type_array, ghdl_rtik_type_record, ghdl_rtik_type_file, ghdl_rtik_subtype_scalar, ghdl_rtik_subtype_array, /* 35 */ ghdl_rtik_subtype_array_ptr, /* Obsolete. */ ghdl_rtik_subtype_unbounded_array, ghdl_rtik_subtype_record, ghdl_rtik_subtype_unbounded_record, #if 0 ghdl_rtik_subtype_access, /* 40 */ ghdl_rtik_type_protected, ghdl_rtik_element, ghdl_rtik_unit, ghdl_rtik_attribute_transaction, ghdl_rtik_attribute_quiet, ghdl_rtik_attribute_stable, #endif ghdl_rtik_error }; /* Well-known types. */ enum ghw_wkt_type { ghw_wkt_unknown, ghw_wkt_boolean, ghw_wkt_bit, ghw_wkt_std_ulogic }; struct ghw_range_b2 { enum ghdl_rtik kind:8; int dir:8; /* 0: to, !0: downto. */ unsigned char left; unsigned char right; }; struct ghw_range_e8 { enum ghdl_rtik kind:8; int dir:8; /* 0: to, !0: downto. */ unsigned char left; unsigned char right; }; struct ghw_range_i32 { enum ghdl_rtik kind:8; int dir:8; /* 0: to, !0: downto. */ int32_t left; int32_t right; }; struct ghw_range_i64 { enum ghdl_rtik kind:8; int dir:8; int64_t left; int64_t right; }; struct ghw_range_f64 { enum ghdl_rtik kind:8; int dir:8; double left; double right; }; union ghw_range { enum ghdl_rtik kind:8; struct ghw_range_b2 b2; struct ghw_range_e8 e8; struct ghw_range_i32 i32; struct ghw_range_i64 i64; struct ghw_range_f64 f64; }; /* Note: the first two fields must be kind and name. */ union ghw_type; struct ghw_type_common { enum ghdl_rtik kind; const char *name; }; struct ghw_type_enum { enum ghdl_rtik kind; const char *name; enum ghw_wkt_type wkt; unsigned int nbr; const char **lits; }; struct ghw_type_scalar { enum ghdl_rtik kind; const char *name; }; struct ghw_unit { const char *name; int64_t val; }; struct ghw_type_physical { enum ghdl_rtik kind; const char *name; uint32_t nbr_units; struct ghw_unit *units; }; struct ghw_type_array { enum ghdl_rtik kind; const char *name; unsigned int nbr_dim; union ghw_type *el; union ghw_type **dims; }; struct ghw_subtype_unbounded_array { enum ghdl_rtik kind; const char *name; union ghw_type *base; }; struct ghw_subtype_array { enum ghdl_rtik kind; const char *name; union ghw_type *base; int nbr_scalars; union ghw_range **rngs; union ghw_type *el; }; struct ghw_subtype_scalar { enum ghdl_rtik kind; const char *name; union ghw_type *base; union ghw_range *rng; }; struct ghw_record_element { const char *name; union ghw_type *type; }; struct ghw_type_record { enum ghdl_rtik kind; const char *name; unsigned int nbr_fields; int nbr_scalars; /* Number of scalar elements (ie nbr of signals). */ struct ghw_record_element *els; }; struct ghw_subtype_record { enum ghdl_rtik kind; const char *name; struct ghw_type_record *base; int nbr_scalars; /* Number of scalar elements (ie nbr of signals). */ struct ghw_record_element *els; }; struct ghw_subtype_unbounded_record { enum ghdl_rtik kind; const char *name; struct ghw_type_record *base; }; union ghw_type { enum ghdl_rtik kind; struct ghw_type_common common; struct ghw_type_enum en; struct ghw_type_scalar sc; struct ghw_type_physical ph; struct ghw_subtype_scalar ss; struct ghw_type_array ar; struct ghw_type_record rec; struct ghw_subtype_array sa; struct ghw_subtype_unbounded_array sua; struct ghw_subtype_record sr; struct ghw_subtype_unbounded_record sur; }; union ghw_val { unsigned char b2; unsigned char e8; int32_t i32; int64_t i64; double f64; }; /* A non-composite signal. */ struct ghw_sig { union ghw_type *type; union ghw_val *val; }; enum ghw_hie_kind { ghw_hie_eoh = 0, ghw_hie_design = 1, ghw_hie_block = 3, ghw_hie_generate_if = 4, ghw_hie_generate_for = 5, ghw_hie_instance = 6, ghw_hie_package = 7, ghw_hie_process = 13, ghw_hie_generic = 14, ghw_hie_eos = 15, ghw_hie_signal = 16, ghw_hie_port_in = 17, ghw_hie_port_out = 18, ghw_hie_port_inout = 19, ghw_hie_port_buffer = 20, ghw_hie_port_linkage = 21 }; #define GHW_NO_SIG 0 struct ghw_hie { enum ghw_hie_kind kind; struct ghw_hie *parent; const char *name; struct ghw_hie *brother; union { struct { struct ghw_hie *child; union ghw_type *iter_type; union ghw_val *iter_value; } blk; struct { union ghw_type *type; /* Array of signal elements. Last element is GHW_NO_SIG (0). */ unsigned int *sigs; } sig; } u; }; struct ghw_handler { FILE *stream; /* True if STREAM was popen, else was fopen. */ unsigned char stream_ispipe; /* True if words are big-endian. */ unsigned char word_be; unsigned char word_len; unsigned char off_len; /* Minor version. */ int version; /* Set by user. */ int flag_verbose; /* String table. */ /* Number of strings. */ unsigned nbr_str; /* Size of the strings (without nul). */ unsigned str_size; /* String table. */ char **str_table; /* Array containing strings. */ char *str_content; /* Type table. */ unsigned nbr_types; union ghw_type **types; /* Non-composite (or basic) signals. */ unsigned nbr_sigs; char *skip_sigs; int flag_full_names; struct ghw_sig *sigs; /* Hierarchy. */ struct ghw_hie *hie; /* Time of the next cycle. */ int64_t snap_time; }; /* Open a GHW file with H. Return < 0 in case of error. */ int ghw_open (struct ghw_handler *h, const char *filename); /* Return base type of T. */ union ghw_type *ghw_get_base_type (union ghw_type *t); /* Return length of RNG. */ int ghw_get_range_length (union ghw_range *rng); /* Put the ASCII representation of VAL into BUF, whose size if LEN. A NUL is always written to BUF. */ void ghw_get_value (char *buf, int len, union ghw_val *val, union ghw_type *type); const char *ghw_get_hie_name (struct ghw_hie *h); void ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top); int ghw_read_base (struct ghw_handler *h); void ghw_filter_signals (struct ghw_handler *h, int *signals_to_keep, int nb_signals_to_keep); void ghw_disp_values (struct ghw_handler *h); int ghw_read_cycle_start (struct ghw_handler *h); int ghw_read_cycle_cont (struct ghw_handler *h, int *list); int ghw_read_cycle_next (struct ghw_handler *h); int ghw_read_cycle_end (struct ghw_handler *h); enum ghw_sm_type { /* At init; Read section name. */ ghw_sm_init = 0, ghw_sm_sect = 1, ghw_sm_cycle = 2 }; enum ghw_res { ghw_res_error = -1, ghw_res_eof = -2, ghw_res_ok = 0, ghw_res_snapshot = 1, ghw_res_cycle = 2, ghw_res_other = 3 }; enum ghw_res ghw_read_sm_hdr (struct ghw_handler *h, int *list); int ghw_read_sm (struct ghw_handler *h, enum ghw_sm_type *sm); int ghw_read_dump (struct ghw_handler *h); struct ghw_section { const char name[4]; int (*handler) (struct ghw_handler * h); }; extern struct ghw_section ghw_sections[]; int ghw_read_section (struct ghw_handler *h); void ghw_close (struct ghw_handler *h); const char *ghw_get_dir (int is_downto); void ghw_disp_subtype_indication (struct ghw_handler *h, union ghw_type *t); /* Note: TYPE must be a base type (used only to display literals). */ void ghw_disp_range (union ghw_type *type, union ghw_range *rng); void ghw_disp_type (struct ghw_handler *h, union ghw_type *t); void ghw_disp_types (struct ghw_handler *h); #endif /* _LIBGHW_H_ */