From f06420aaf0db94a97bf62038d7a7289b9553bc0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Br=C3=BCndler?= Date: Mon, 21 Apr 2025 17:31:04 +0200 Subject: [PATCH 1/9] BUGFIX: ChunkInt_v can get negative Negative ChunkInt_v values failed the conversion to_unsigned(). --- hdl/en_cl_fix_pkg.vhd | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hdl/en_cl_fix_pkg.vhd b/hdl/en_cl_fix_pkg.vhd index 5f6c056..b8c793d 100644 --- a/hdl/en_cl_fix_pkg.vhd +++ b/hdl/en_cl_fix_pkg.vhd @@ -775,6 +775,7 @@ package body en_cl_fix_pkg is constant ChunkCount_c : positive := (cl_fix_width(result_fmt) + ChunkSize_c - 1)/ChunkSize_c; variable ASat_v : real; variable Chunk_v : std_logic_vector(ChunkSize_c-1 downto 0); + variable ChunkInt_v : integer; variable Result_v : std_logic_vector(ChunkSize_c*ChunkCount_c-1 downto 0); begin -- Saturation is mandatory in this function (because wrapping has not been implemented) @@ -797,7 +798,12 @@ package body en_cl_fix_pkg is -- Convert to fixed-point in chunks (required for formats that don't fit into integer) for i in 0 to ChunkCount_c-1 loop -- Note: Due to a Xilinx Vivado bug, we must explicitly call the math_real mod operator - Chunk_v := std_logic_vector(to_unsigned(integer(ieee.math_real."mod"(ASat_v, 2.0**ChunkSize_c)), ChunkSize_c)); + ChunkInt_v := integer(ieee.math_real."mod"(ASat_v, 2.0**ChunkSize_c)); + if ChunkInt_v > 0 then + Chunk_v := std_logic_vector(to_unsigned(ChunkInt_v, ChunkSize_c)); + else + Chunk_v := std_logic_vector(to_signed(ChunkInt_v, ChunkSize_c)); + end if; Result_v((i+1)*ChunkSize_c-1 downto i*ChunkSize_c) := Chunk_v; ASat_v := floor(ASat_v/2.0**ChunkSize_c); end loop; From a4ae3053194fc064fd8ecf6009bb5f7b704ff077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Br=C3=BCndler?= Date: Mon, 21 Apr 2025 17:38:21 +0200 Subject: [PATCH 2/9] BUGFIX: Make cl_fix_to_integer working for Widefix types --- bittrue/models/python/en_cl_fix_pkg/en_cl_fix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittrue/models/python/en_cl_fix_pkg/en_cl_fix.py b/bittrue/models/python/en_cl_fix_pkg/en_cl_fix.py index 74e6b0d..7be97a8 100644 --- a/bittrue/models/python/en_cl_fix_pkg/en_cl_fix.py +++ b/bittrue/models/python/en_cl_fix_pkg/en_cl_fix.py @@ -165,7 +165,7 @@ def cl_fix_to_integer(a, a_fmt : FixFormat): a = _clean_input(a) if cl_fix_is_wide(a_fmt): - return a + return a.data else: return NarrowFix(a, a_fmt, copy=False).to_integer() From b4f43881a3d2dec0dbcc13b166763f12dc3bdf57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Br=C3=BCndler?= Date: Mon, 21 Apr 2025 17:41:44 +0200 Subject: [PATCH 3/9] BUGFIX: Made cl_fix_from_integer() working for WideFix --- bittrue/models/python/en_cl_fix_pkg/en_cl_fix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittrue/models/python/en_cl_fix_pkg/en_cl_fix.py b/bittrue/models/python/en_cl_fix_pkg/en_cl_fix.py index 7be97a8..6bb6a83 100644 --- a/bittrue/models/python/en_cl_fix_pkg/en_cl_fix.py +++ b/bittrue/models/python/en_cl_fix_pkg/en_cl_fix.py @@ -151,7 +151,7 @@ def cl_fix_from_integer(a, r_fmt : FixFormat): a = _clean_input(a) if cl_fix_is_wide(r_fmt): - return a + return WideFix(a, r_fmt) else: return NarrowFix.from_integer(a, r_fmt)._data From 8ace64e4b1920c36c6e6f8892033aa0ec2102e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Br=C3=BCndler?= Date: Mon, 5 May 2025 13:54:10 +0200 Subject: [PATCH 4/9] Add fusesoc core file --- en_cl_fix_dev.core | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 en_cl_fix_dev.core diff --git a/en_cl_fix_dev.core b/en_cl_fix_dev.core new file mode 100644 index 0000000..488e5a4 --- /dev/null +++ b/en_cl_fix_dev.core @@ -0,0 +1,18 @@ +CAPI=2: + +name : open-logic:open-logic-dev:en_cl_fix:2.1.1 +description : local files (release plus WIP); see https://github.com/enclustra/en_cl_fix/blob/main/README.md + +filesets: + rtl: + files: + - hdl/en_cl_fix_private_pkg.vhd + - hdl/en_cl_fix_pkg.vhd + file_type : vhdlSource + logical_name : olo + +targets: + default: + filesets : + - rtl + \ No newline at end of file From 7efb21ea2dbc7895a08f387b7ad61ded51bed75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Br=C3=BCndler?= Date: Sat, 24 May 2025 23:24:33 +0200 Subject: [PATCH 5/9] RELEASE: Open Logic version 2.2.0 --- en_cl_fix_dev.core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en_cl_fix_dev.core b/en_cl_fix_dev.core index 488e5a4..071e538 100644 --- a/en_cl_fix_dev.core +++ b/en_cl_fix_dev.core @@ -1,6 +1,6 @@ CAPI=2: -name : open-logic:open-logic-dev:en_cl_fix:2.1.1 +name : open-logic:open-logic-dev:en_cl_fix:2.2.0 description : local files (release plus WIP); see https://github.com/enclustra/en_cl_fix/blob/main/README.md filesets: From 4e34f81cdd8e422ff722bc14da60bf8ad533d70e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Br=C3=BCndler?= Date: Wed, 18 Jun 2025 21:12:18 +0200 Subject: [PATCH 6/9] Update core-file to VHDL-2008 --- en_cl_fix_dev.core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en_cl_fix_dev.core b/en_cl_fix_dev.core index 071e538..1963475 100644 --- a/en_cl_fix_dev.core +++ b/en_cl_fix_dev.core @@ -8,7 +8,7 @@ filesets: files: - hdl/en_cl_fix_private_pkg.vhd - hdl/en_cl_fix_pkg.vhd - file_type : vhdlSource + file_type : vhdlSource-2008 logical_name : olo targets: From bbc3df6b7d5c203c3cccde3f7461c9fac2465999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Br=C3=BCndler?= Date: Wed, 25 Jun 2025 17:12:50 +0200 Subject: [PATCH 7/9] RELEASE: open-logic-2.1.1 --- en_cl_fix_dev.core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en_cl_fix_dev.core b/en_cl_fix_dev.core index 1963475..6b0c7db 100644 --- a/en_cl_fix_dev.core +++ b/en_cl_fix_dev.core @@ -1,6 +1,6 @@ CAPI=2: -name : open-logic:open-logic-dev:en_cl_fix:2.2.0 +name : open-logic:open-logic-dev:en_cl_fix:2.2.1 description : local files (release plus WIP); see https://github.com/enclustra/en_cl_fix/blob/main/README.md filesets: From 909d886b397a191eb29f6866b4980ccc0dd07097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Br=C3=BCndler?= Date: Fri, 12 Sep 2025 20:59:10 +0200 Subject: [PATCH 8/9] RELEASE: open-logic-2.3.1 --- en_cl_fix_dev.core | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/en_cl_fix_dev.core b/en_cl_fix_dev.core index 6b0c7db..c71f398 100644 --- a/en_cl_fix_dev.core +++ b/en_cl_fix_dev.core @@ -1,12 +1,15 @@ CAPI=2: -name : open-logic:open-logic-dev:en_cl_fix:2.2.1 +name : open-logic:open-logic-dev:en_cl_fix:2.3.1 description : local files (release plus WIP); see https://github.com/enclustra/en_cl_fix/blob/main/README.md filesets: rtl: files: - hdl/en_cl_fix_private_pkg.vhd + - hdl/en_cl_fix_saturate.vhd + - hdl/en_cl_fix_round.vhd + - hdl/en_cl_fix_resize.vhd - hdl/en_cl_fix_pkg.vhd file_type : vhdlSource-2008 logical_name : olo From 434a89280ddc40e72b3fc0a2d4732cb14fff7820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Br=C3=BCndler?= Date: Sat, 27 Sep 2025 16:10:41 +0200 Subject: [PATCH 9/9] FEATURE: Disable asserts for synthesis oss-cad-suite does not allow asserts in synthesis --- hdl/en_cl_fix_pkg.vhd | 28 +++++++++++++++++++++++++++- hdl/en_cl_fix_private_pkg.vhd | 4 ++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/hdl/en_cl_fix_pkg.vhd b/hdl/en_cl_fix_pkg.vhd index 272de13..8ae777a 100644 --- a/hdl/en_cl_fix_pkg.vhd +++ b/hdl/en_cl_fix_pkg.vhd @@ -595,7 +595,9 @@ package body en_cl_fix_pkg is function cl_fix_shift_fmt(a_fmt : FixFormat_t; min_shift : integer; max_shift : integer) return FixFormat_t is begin + -- synthesis translate_off assert min_shift <= max_shift report "min_shift must be <= max_shift" severity Failure; + -- synthesis translate_on return (a_fmt.S, a_fmt.I + max_shift, a_fmt.F - min_shift); end; @@ -733,8 +735,10 @@ package body en_cl_fix_pkg is -- Parse Format Index_v := Str'low; Index_v := string_find_next_match(Str, '(', Index_v); + -- synthesis translate_off assert Index_v > 0 report "cl_fix_format_from_string: Format string is missing '('" severity Failure; + -- synthesis translate_on -- Number of sign bits must be 0 or 1 if Str(Index_v+1) = '0' then Format_v.S := 0; @@ -744,16 +748,22 @@ package body en_cl_fix_pkg is report "cl_fix_format_from_string: Unsupported number of sign bits: " & Str(Index_v+1) severity Failure; end if; Index_v := string_find_next_match(Str, ',', Index_v+1); + -- synthesis translate_off assert Index_v > 0 report "cl_fix_format_from_string: Format string is missing ',' between S and I" severity Failure; + -- synthesis translate_on Format_v.I := string_parse_int(Str, Index_v+1); Index_v := string_find_next_match(Str, ',', Index_v+1); + -- synthesis translate_off assert Index_v > 0 report "cl_fix_format_from_string: Format string is missing ',' between I and F" severity Failure; + -- synthesis translate_on Format_v.F := string_parse_int(Str, Index_v+1); Index_v := string_find_next_match(Str, ')', Index_v+1); + -- synthesis translate_off assert Index_v > 0 report "cl_fix_format_from_string: Format string is missing ')'" severity Failure; + -- synthesis translate_on return Format_v; end; @@ -813,10 +823,12 @@ package body en_cl_fix_pkg is variable Result_v : std_logic_vector(ChunkSize_c*ChunkCount_c-1 downto 0); begin -- Saturation is mandatory in this function (because wrapping has not been implemented) + -- synthesis translate_off assert saturate = SatWarn_s or saturate = Sat_s report "cl_fix_for_real: Saturation mode must be SatWarn_s or Sat_s" severity Failure; - + -- synthesis translate_on + -- Saturate if a > max_real(result_fmt) then ASat_v := max_real(result_fmt); @@ -938,8 +950,10 @@ package body en_cl_fix_pkg is begin -- Allow the designer to ignore the worst-case result format (with caution). if fmt_check then + -- synthesis translate_off assert result_fmt = cl_fix_round_fmt(a_fmt, result_fmt.F, round) report "cl_fix_round: Invalid result format. Use cl_fix_round_fmt()." severity Failure; + -- synthesis translate_on end if; -- Write the input value into mid_v with correct binary point alignment. @@ -984,12 +998,16 @@ package body en_cl_fix_pkg is ) return std_logic_vector is variable result_v : std_logic_vector(cl_fix_width(result_fmt)-1 downto 0); begin + -- synthesis translate_off assert result_fmt.F = a_fmt.F report "cl_fix_saturate: Number of frac bits cannot change." severity Failure; + -- synthesis translate_on -- Saturation warning if saturate = Warn_s or saturate = SatWarn_s then + -- synthesis translate_off assert cl_fix_in_range(a, a_fmt, result_fmt) report "cl_fix_saturate : Saturation warning!" severity Warning; + -- synthesis translate_on end if; -- Write the input value into result_v with correct binary point alignment. @@ -1048,8 +1066,10 @@ package body en_cl_fix_pkg is begin -- Allow the designer to ignore the worst-case result format (with caution). if fmt_check then + -- synthesis translate_off assert result_fmt = cl_fix_round_fmt(a_fmt, result_fmt.F, round) report "cl_fix_recommended_pipelining: Invalid result format. Use cl_fix_round_fmt()." severity Failure; + -- synthesis translate_on end if; -- Registering is not needed if zero logic is used. This happens in two cases: @@ -1058,9 +1078,11 @@ package body en_cl_fix_pkg is return 0; else -- If a new rounding mode is defined, then appropriate behavior must be implemented. + -- synthesis translate_off assert round = NonSymPos_s or round = NonSymNeg_s or round = SymInf_s or round = SymZero_s or round = ConvEven_s or round = ConvOdd_s report "cl_fix_recommended_pipelining: Unhandled rounding mode." severity Failure; + -- synthesis translate_on end if; -- (2) If the number of fractional bits isn't being decreased. if result_fmt.F >= a_fmt.F then @@ -1075,9 +1097,11 @@ package body en_cl_fix_pkg is saturate : FixSaturate_t ) return natural is begin + -- synthesis translate_off assert result_fmt.F = a_fmt.F report "cl_fix_recommended_pipelining: Number of frac bits cannot change during saturation." severity Failure; + -- synthesis translate_on -- Registering is not needed if zero logic is used. This happens in two cases: -- (1) During wrapping. @@ -1085,9 +1109,11 @@ package body en_cl_fix_pkg is return 0; else -- If a new saturation mode is defined, then appropriate behavior must be implemented. + -- synthesis translate_off assert saturate = Sat_s or saturate = SatWarn_s report "cl_fix_recommended_pipelining: Unhandled saturation mode." severity Failure; + -- synthesis translate_on end if; -- (2) If the number of integer bits is not being decreased, and the number of sign bits is -- not being changed. diff --git a/hdl/en_cl_fix_private_pkg.vhd b/hdl/en_cl_fix_private_pkg.vhd index ff5bdcf..6c466d9 100644 --- a/hdl/en_cl_fix_private_pkg.vhd +++ b/hdl/en_cl_fix_private_pkg.vhd @@ -161,7 +161,9 @@ package body en_cl_fix_private_pkg is variable MatchIdx_v : integer := -1; begin -- Checks + -- synthesis translate_off assert StartIdx <= Str'high and StartIdx >= Str'low report "string_find_next_match: StartIdx out of range" severity Failure; + -- synthesis translate_on -- Implementation while (not Match_v) and (CurrentIdx_v <= Str'high) loop @@ -203,7 +205,9 @@ package body en_cl_fix_private_pkg is variable AbsoluteVal_v : integer := 0; begin -- Checks + -- synthesis translate_off assert StartIdx <= Str'high and StartIdx >= Str'low report "string_parse_int: StartIdx out of range" severity Failure; + -- synthesis translate_on -- Remove leading spaces while Str(CurrentIdx_v) = ' ' loop