From ba72f97bec50c15c0a39c71f941120b4a9ba3834 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 28 Mar 2024 19:03:20 +0000 Subject: [PATCH] Implement vhpi_get_real --- src/vhpi/vhpi-model.c | 77 ++++++++++++++++++++++++++++++++++--- test/regress/gold/vhpi1.txt | 4 +- test/regress/vhpi1.vhd | 3 +- test/vhpi/vhpi1.c | 19 +++++++++ 4 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/vhpi/vhpi-model.c b/src/vhpi/vhpi-model.c index 4ee749a5..0534073b 100644 --- a/src/vhpi/vhpi-model.c +++ b/src/vhpi/vhpi-model.c @@ -34,6 +34,7 @@ #include "vhpi/vhpi-util.h" #include +#include #include #include #include @@ -130,6 +131,14 @@ typedef struct { DEF_CLASS(intRange, vhpiIntRangeK, range.object); +typedef struct { + c_range range; + vhpiRealT FloatLeftBound; + vhpiRealT FloatRightBound; +} c_floatRange; + +DEF_CLASS(floatRange, vhpiFloatRangeK, range.object); + typedef struct tag_typeDecl c_typeDecl; typedef struct tag_typeDecl { @@ -183,6 +192,7 @@ DEF_CLASS(physTypeDecl, vhpiPhysTypeDeclK, scalar.typeDecl.decl.object); typedef struct { c_scalarTypeDecl scalar; + c_range *constraint; } c_floatTypeDecl; typedef struct { @@ -2485,9 +2495,37 @@ unsupported: DLLEXPORT vhpiRealT vhpi_get_real(vhpiRealPropertyT property, - vhpiHandleT object) + vhpiHandleT handle) { - VHPI_MISSING; + vhpi_clear_error(); + + VHPI_TRACE("property=%s handle=%s", vhpi_property_str(property), + handle_pp(handle)); + + c_vhpiObject *obj = from_handle(handle); + if (obj == NULL) + return NAN; + + switch (property) { + case vhpiFloatLeftBoundP: + case vhpiFloatRightBoundP: + { + c_floatRange *fr = cast_floatRange(obj); + if (fr == NULL) + return NAN; + + if (property == vhpiFloatLeftBoundP) + return fr->FloatLeftBound; + else + return fr->FloatRightBound; + } + + default: + vhpi_error(vhpiError, &(obj->loc), "invalid property %s in vhpi_get_real", + vhpi_property_str(property)); + } + + return NAN; } DLLEXPORT @@ -3143,6 +3181,28 @@ static c_physRange *build_phys_range(tree_t t) return pr; } +static c_floatRange *build_float_range(tree_t r) +{ + double left; + if (!folded_real(tree_left(r), &left)) + left = -INFINITY; + + double right; + if (!folded_real(tree_right(r), &right)) + right = +INFINITY; + + const range_kind_t dir = tree_subkind(r) == RANGE_TO; + const bool null = dir == RANGE_TO ? left > right : right > left; + + c_floatRange *fr = new_object(sizeof(c_floatRange), vhpiFloatRangeK); + init_range(&(fr->range), dir, null, true); + + fr->FloatLeftBound = left; + fr->FloatRightBound = right; + + return fr; +} + static c_intRange *build_int_range(tree_t r, type_t parent, int dim, c_vhpiObject *obj) { @@ -3410,8 +3470,9 @@ static c_typeDecl *build_typeDecl(type_t type, c_vhpiObject *obj) case T_REAL: { c_floatTypeDecl *td = - new_object(sizeof(c_intTypeDecl), vhpiFloatTypeDeclK); + new_object(sizeof(c_floatTypeDecl), vhpiFloatTypeDeclK); init_scalarTypeDecl(&(td->scalar), decl, type); + td->constraint = &(build_float_range(range_of(type, 0))->range); return &(td->scalar.typeDecl); } @@ -3475,8 +3536,14 @@ static c_typeDecl *build_typeDecl(type_t type, c_vhpiObject *obj) case C_RANGE: { tree_t r = tree_range(c, 0); - c_intRange *ir = build_int_range(r, NULL, 0, NULL); - APUSH(td->Constraints, &(ir->range.object)); + if (type_is_real(tree_type(r))) { + c_floatRange *fr = build_float_range(r); + APUSH(td->Constraints, &(fr->range.object)); + } + else { + c_intRange *ir = build_int_range(r, NULL, 0, NULL); + APUSH(td->Constraints, &(ir->range.object)); + } } break; case C_RECORD: diff --git a/test/regress/gold/vhpi1.txt b/test/regress/gold/vhpi1.txt index f1806482..58ccf590 100644 --- a/test/regress/gold/vhpi1.txt +++ b/test/regress/gold/vhpi1.txt @@ -28,8 +28,8 @@ VHPI printf y name Y VHPI printf y full name is :VHPI1:Y VHPI printf r handle VHPI printf r type handle -VHPI printf r type name is REAL -VHPI printf r type full name is @STD:STANDARD:REAL +VHPI printf r type name is ZERO_TO_ONE +VHPI printf r type full name is @WORK:VHPI1-TEST:ZERO_TO_ONE VHPI printf v handle VHPI printf v name is V VHPI printf v full name is :VHPI1:V diff --git a/test/regress/vhpi1.vhd b/test/regress/vhpi1.vhd index 888278b2..6c3a1718 100644 --- a/test/regress/vhpi1.vhd +++ b/test/regress/vhpi1.vhd @@ -5,9 +5,10 @@ entity vhpi1 is end entity; architecture test of vhpi1 is + subtype zero_to_one is real range 0.0 to 1.0; signal v : bit_vector(3 downto 0) := "0011"; signal b : bit; - signal r : real; + signal r : zero_to_one; signal i : integer := 42; signal A_name_with_MIXED_case : bit; begin diff --git a/test/vhpi/vhpi1.c b/test/vhpi/vhpi1.c index f8c5941c..1de1c5a9 100644 --- a/test/vhpi/vhpi1.c +++ b/test/vhpi/vhpi1.c @@ -469,6 +469,25 @@ static void end_of_init(const vhpiCbDataT *cb_data) vhpi_printf("r type name is %s", vhpi_get_str(vhpiNameP, r_type)); vhpi_printf("r type full name is %s", vhpi_get_str(vhpiFullNameP, r_type)); + vhpiHandleT r_constrs = vhpi_iterator(vhpiConstraints, r_type); + check_error(); + fail_if(r_constrs == NULL); + + vhpiHandleT r_range = vhpi_scan(r_constrs); + check_error(); + fail_if(r_range == NULL); + fail_unless(vhpi_scan(r_constrs) == NULL); + vhpi_printf("r type range handle %p", r_range); + vhpi_printf("r left bound %f", vhpi_get_real(vhpiFloatLeftBoundP, r_range)); + vhpi_printf("r right bound %f", vhpi_get_real(vhpiFloatRightBoundP, r_range)); + + fail_unless(vhpi_get_real(vhpiFloatLeftBoundP, r_range) == 0.0); + fail_unless(vhpi_get_real(vhpiFloatRightBoundP, r_range) == 1.0); + + vhpi_release_handle(r_range); + vhpi_release_handle(r_constrs); + vhpi_release_handle(r_type); + vhpiHandleT handle_v = vhpi_handle_by_name("v", root); check_error(); fail_if(handle_v == NULL); -- 2.39.2