Vivado可以处理用户定义的物理类型吗?

时间:2015-01-06 05:11:56

标签: vhdl fpga xilinx synthesis vivado

我为Xilinx XST,iSim,Altera Quartus II,Mentor Graphics QuestaSim和GHDL编写了一些跨平台的VHDL库。现在我想移植我的ISE 14.7项目,它将这些库用于Vivado 2014.4,但是一个库似乎有致命的问题。

我的库physical定义了几种新的用户定义的物理类型,例如:FREQUENCYBAUD;转换功能和报告功能。

一个主要用例是计算给定延迟和系统频率的延迟或计数器周期。因此,例如125 ns的延迟需要在100 MHz时有12或13个延迟周期(这取决于.5处的舍入模式)。

我从Vivado Synth获得了几个信息和警告(一些是断言声明的结果,请参见下面的最小示例):

[Synth 8-638] synthesizing module 'Top_PhysicalTest' ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":410]
[Synth 8-63] RTL assertion: "to_time: f= 2147483647.1000 THz  return 2147483647.1000 sec" ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":277]
[Synth 8-63] RTL assertion: "res_real: 0.000000" ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":321]
[Synth 8-63] RTL assertion: "TimingToCycles: 
  Timing: 2147483647.1000 sec
  Clock_Period: 2147483647.1000 sec
  RoundingStyle: TO_NEAREST
  res_real = 2147483647.1000
  => 0" ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":323]
[Synth 8-26] 'image of non-integer, non-enum type not implemented ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":422]
[Synth 8-63] RTL assertion: "CLOCK_FREQ: <complex-type>" ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":422]
[Synth 8-63] RTL assertion: "CLOCK_FREQ: 2147483647.1000 THz" ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":423]
[Synth 8-26] 'image of non-integer, non-enum type not implemented ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":424]
[Synth 8-63] RTL assertion: "DELAY: <complex-type>" ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":424]
[Synth 8-63] RTL assertion: "DELAY: 2147483647.1000 sec" ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":425]
[Synth 8-63] RTL assertion: "CYCLES: 0" ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":426]
[Synth 8-256] done synthesizing module 'Top_PhysicalTest' (1#1) ["D:/Temp/PhysicalTest_Vivado2014.4/vhdl/Top_PhysicalTest.vhd":410]
[Synth 8-3330] design Top_PhysicalTest has an empty top module
[Synth 8-3331] design Top_PhysicalTest has unconnected port Clock
[Synth 8-3330] design Top_PhysicalTest has an empty top module
[Synth 8-3331] design Top_PhysicalTest has unconnected port Clock
[Project 1-571] Translating synthesized netlist

我的场景有点复杂,因此最小的示例看起来并不像应该看起来那么小。我没有内联每个函数来防止复制/替换错误,我没有删除调试和断言/报告例程。

概述:

  1. Package utils:常用类型,枚举和函数
  2. 包字符串:字符串操作和转换函数
  3. 包物理:新类型及其功能
  4. 实体:实现简单延迟元素/ shift-register的单个顶级实体
  5. 最小例子:

    -- EMACS settings: -*-  tab-width: 2; indent-tabs-mode: t -*-
    -- vim: tabstop=2:shiftwidth=2:noexpandtab
    -- kate: tab-width 2; replace-tabs off; indent-width 2;
    -- 
    -- ============================================================================
    -- Package:                 Common functions and types
    --
    -- Authors:                 Thomas B. Preusser
    --                          Martin Zabel
    --                          Patrick Lehmann
    --
    -- License:
    -- ============================================================================
    -- Copyright 2007-2015 Technische Universitaet Dresden - Germany
    --                                       Chair for VLSI-Design, Diagnostics and Architecture
    -- 
    -- Licensed under the Apache License, Version 2.0 (the "License");
    -- you may not use this file except in compliance with the License.
    -- You may obtain a copy of the License at
    -- 
    --      http://www.apache.org/licenses/LICENSE-2.0
    -- 
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -- See the License for the specific language governing permissions and
    -- limitations under the License.
    -- ============================================================================
    
    library IEEE;
    use     IEEE.STD_LOGIC_1164.all;
    use     IEEE.NUMERIC_STD.all;
    
    package utils is
        -- rounding style
        type T_ROUNDING_STYLE   is (ROUND_TO_NEAREST, ROUND_TO_ZERO, ROUND_TO_INF, ROUND_UP, ROUND_DOWN);
    
        function ite(cond : BOOLEAN; value1 : STRING; value2 : STRING) return STRING;
        function imin(arg1 : integer; arg2 : integer) return integer;
        function imax(arg1 : integer; arg2 : integer) return integer;
        function log2ceil(arg : positive) return natural;
        function log2ceilnz(arg : positive) return positive;
    end package utils;
    
    package body utils is
        function ite(cond : BOOLEAN; value1 : STRING; value2 : STRING) return STRING is
        begin
            if cond then
                return value1;
            else
                return value2;
            end if;
        end function;
    
        function imin(arg1 : integer; arg2 : integer) return integer is
        begin
            if arg1 < arg2 then return arg1; end if;
            return arg2;
        end function;
    
        function imax(arg1 : integer; arg2 : integer) return integer is
        begin
            if arg1 > arg2 then return arg1; end if;
            return arg2;
        end function;
    
        function log2ceil(arg : positive) return natural is
            variable tmp : positive     := 1;
            variable log : natural      := 0;
        begin
            if arg = 1 then return 0; end if;
            while arg > tmp loop
                tmp := tmp * 2;
                log := log + 1;
            end loop;
            return log;
        end function;
    
        function log2ceilnz(arg : positive) return positive is
        begin
            return imax(1, log2ceil(arg));
        end function;
    end utils;
    
    -- ============================================================================
    -- Package:                 String related functions and types
    --
    -- Authors:                 Thomas B. Preusser
    --                          Martin Zabel
    --                          Patrick Lehmann
    --
    -- =============================================================================
    library IEEE;
    use     IEEE.STD_LOGIC_1164.all;
    use     IEEE.NUMERIC_STD.all;
    use     IEEE.MATH_REAL.all;
    
    use     work.utils.all;
    
    package strings is
        function raw_format_nat_dec(value : NATURAL)                return STRING;
        function str_format(value : REAL; precision : NATURAL := 3) return STRING;
        FUNCTION resize(str : STRING; size : POSITIVE; FillChar : CHARACTER := NUL) RETURN STRING;
        function str_length(str : STRING)                           return NATURAL;
        function str_trim(str : STRING)                             return STRING;
        function str_substr(str : STRING; start : INTEGER := 0; length : INTEGER := 0) return STRING;
    end package strings;
    
    package body strings is
        -- raw_format_* functions
        function raw_format_nat_dec(value : NATURAL) return STRING is
        begin
            return INTEGER'image(value);
        end function;
    
        -- str_format_* functions
        function str_format(value : REAL; precision : NATURAL := 3) return STRING is
            constant s      : REAL          := sign(value);
            constant int    : INTEGER       := integer((value * s) - 0.5);                                                                      -- force ROUND_DOWN
            constant frac   : INTEGER       := integer((((value * s) - real(int)) * 10.0**precision) - 0.5);    -- force ROUND_DOWN
            constant res    : STRING        := raw_format_nat_dec(int) & "." & raw_format_nat_dec(frac);
        begin
    --      assert (not MY_VERBOSE)
    --          report "str_format:" & CR &
    --                       "  value:" & REAL'image(value) & CR &
    --                       "  int = " & INTEGER'image(int) & CR &
    --                       "  frac = " & INTEGER'image(frac)
    --          severity note;
            return ite((s   < 0.0), "-" & res, res);
        end function;
    
        -- resize
        FUNCTION resize(str : STRING; size : POSITIVE; FillChar : CHARACTER := NUL) RETURN STRING IS
            CONSTANT MaxLength  : NATURAL               := imin(size, str'length);
            VARIABLE Result     : STRING(1 TO size)     := (OTHERS => FillChar);
        BEGIN
            if (MaxLength > 0) then
                Result(1 TO MaxLength) := str(str'low TO str'low + MaxLength - 1);
            end if;
            RETURN Result;
        END FUNCTION;
    
        -- String functions
        FUNCTION str_length(str : STRING) RETURN NATURAL IS
            VARIABLE l  : NATURAL       := 0;
        BEGIN
            FOR I IN str'range LOOP
                IF (str(I) = NUL) THEN
                    RETURN l;
                ELSE
                    l := l + 1;
                END IF;
            END LOOP;
            RETURN str'length;
        END FUNCTION;
    
        function str_trim(str : STRING) return STRING is
            constant len    : NATURAL   := str_length(str);
        begin
            if (len = 0) then
                return "";
            else
                return resize(str, len);
            end if;
        end function;
    
        function str_substr(str : STRING; start : INTEGER := 0; length : INTEGER := 0) return STRING is
            variable StartOfString      : positive;
            variable EndOfString        : positive;
        begin
            if (start < 0) then         -- start is negative -> start substring at right string boundary
                StartOfString       := str'high + start + 1;
            elsif (start = 0) then  -- start is zero -> start substring at left string boundary
                StartOfString       := str'low;
            else                                        -- start is positive -> start substring at left string boundary + offset
                StartOfString       := start;
            end if;
    
            if (length < 0) then        -- length is negative -> end substring at length'th character before right string boundary
                EndOfString         := str'high + length;
            elsif (length = 0) then -- length is zero -> end substring at right string boundary
                EndOfString         := str'high;
            else                                        -- length is positive -> end substring at StartOfString + length
                EndOfString         := StartOfString + length - 1;
            end if;
    
            if (StartOfString < str'low) then   report "StartOfString is out of str's range. (str=" & str & ")" severity error;     end if;
            if (EndOfString < str'high) then    report "EndOfString is out of str's range. (str=" & str & ")" severity error;           end if;
    
            return str(StartOfString to EndOfString);
        end function;
    end strings;
    
    
    -- ============================================================================
    -- Package:                 This VHDL package declares new physical types and their
    --                                  conversion functions.
    --
    -- Authors:                 Patrick Lehmann
    -- 
    -- ============================================================================
    library IEEE;
    use     IEEE.MATH_REAL.all;
    
    use     work.utils.all;
    use     work.strings.all;
    
    package physical is
        type FREQ is range 0 to INTEGER'high units
            Hz;
            kHz = 1000 Hz;
            MHz = 1000 kHz;
            GHz = 1000 MHz;
            THz = 1000 GHz;
        end units;
    
        constant C_PHYSICAL_REPORT_TIMING_DEVIATION     : BOOLEAN       := TRUE;
        function to_time(f : FREQ)  return TIME;
        function to_real(t : TIME;          scale : TIME)       return REAL;
        function to_real(f : FREQ;          scale : FREQ)       return REAL;
        function TimingToCycles(Timing : TIME; Clock_Period : TIME; RoundingStyle : T_ROUNDING_STYLE := ROUND_TO_NEAREST) return NATURAL;
        function TimingToCycles(Timing : TIME; Clock_Frequency  : FREQ; RoundingStyle : T_ROUNDING_STYLE := ROUND_TO_NEAREST) return NATURAL;
        function to_string(t : TIME; precision : NATURAL := 3)  return STRING;
        function to_string(f : FREQ; precision : NATURAL := 3)  return STRING;
    end physical;
    
    
    package body physical is
        -- iSim 14.7 does not support fs in simulation by default (fs values are converted to 0 ps)
        --  activate fs support by overriding the time precision
        --  fuse[.exe] [...] -timeprecision_vhdl 1fs [...]
        function MinimalTimeResolutionInSimulation return TIME is
        begin
            if      (1 fs > 0 sec) then return 1 fs;
            elsif   (1 ps > 0 sec) then return 1 ps;
            elsif   (1 ns > 0 sec) then return 1 ns;
            elsif   (1 us > 0 sec) then return 1 us;
            elsif   (1 ms > 0 sec) then return 1 ms;
            else                                            return 1 sec;
            end if;
        end function;
    
        -- real division for physical types
        function div(a : TIME; b : TIME) return REAL is
            constant MTRIS  : TIME      := MinimalTimeResolutionInSimulation;
        begin
            if  (a < 1 us) then
                return real(a / MTRIS) / real(b / MTRIS);
            elsif (a < 1 ms) then
                return real(a / (1000 * MTRIS)) / real(b / MTRIS) * 1000.0;
            elsif (a < 1 sec) then
                return real(a / (1000000 * MTRIS)) / real(b / MTRIS) * 1000000.0;
            else
                return real(a / (1000000000 * MTRIS)) / real(b / MTRIS) * 1000000000.0;
            end if;
        end function;
    
        function div(a : FREQ; b : FREQ) return REAL is
        begin
            return real(a / 1 Hz) / real(b / 1 Hz);
        end function;
    
    
        -- conversion functions
        function to_time(f : FREQ) return TIME is
            variable res : TIME;
        begin
            if    (f < 1.0 kHz) then res := div(1.0  Hz, f) * 1.0 sec;
            elsif (f < 1.0 MHz) then res := div(1.0 kHz, f) * 1.0 ms;
            elsif (f < 1.0 GHz) then res := div(1.0 MHz, f) * 1.0 us;
            elsif (f < 1.0 THz) then res := div(1.0 GHz, f) * 1.0 ns;
            else                     res := div(1.0 THz, f) * 1.0 ps;
            end if;
    
            assert FALSE report "to_time: f= " & to_string(f) & "  return " & to_string(res) severity note;
            return res;
        end function;
    
        -- convert physical types (TIME, FREQ) to standard type (REAL)
        function to_real(t : TIME; scale : TIME) return REAL is
        begin
            if      (scale = 1.0    fs) then    return div(t, 1.0    fs);
            elsif   (scale = 1.0    ps) then    return div(t, 1.0    ps);
            elsif   (scale = 1.0    ns) then    return div(t, 1.0    ns);
            elsif   (scale = 1.0    us) then    return div(t, 1.0    us);
            elsif   (scale = 1.0    ms) then    return div(t, 1.0    ms);
            elsif   (scale = 1.0 sec) then  return div(t, 1.0 sec);
            else    report "to_real: scale must have a value of '1.0 <unit>'" severity failure;
            end if;
        end;
    
        function to_real(f : FREQ; scale : FREQ) return REAL is
        begin
            if      (scale = 1.0    Hz) then    return div(f, 1.0    Hz);
            elsif   (scale = 1.0 kHz) then  return div(f, 1.0 kHz);
            elsif   (scale = 1.0 MHz) then  return div(f, 1.0 MHz);
            elsif   (scale = 1.0 GHz) then  return div(f, 1.0 GHz);
            elsif   (scale = 1.0 THz) then  return div(f, 1.0 THz);
            else    report "to_real: scale must have a value of '1.0 <unit>'" severity failure;
            end if;
        end;
    
        -- calculate needed counter cycles to achieve a given 1. timing/delay and 2. frequency/period
        -- ===========================================================================
        --  @param Timing           A given timing or delay, which should be achived
        --  @param Clock_Period     The period of the circuits clock
        --  @RoundingStyle          Default = round to nearest; other choises: ROUND_UP, ROUND_DOWN
        function TimingToCycles(Timing : TIME; Clock_Period : TIME; RoundingStyle : T_ROUNDING_STYLE := ROUND_TO_NEAREST) return NATURAL is
            variable res_real   : REAL;
            variable res_nat    : NATURAL;
        begin
            res_real := div(Timing, Clock_Period);  
            case RoundingStyle is
                when ROUND_TO_NEAREST =>    res_nat := natural(round(res_real));
                when ROUND_UP =>            res_nat := natural(res_real + 0.5);
                when ROUND_DOWN =>          res_nat := natural(res_real);
                when others =>  report "RoundingStyle '" & T_ROUNDING_STYLE'image(RoundingStyle) & "' not supported." severity failure;
            end case;
            report "res_real: " & REAL'image(res_real) severity note;
    
            assert FALSE
                report "TimingToCycles: " &     CR &
                             "  Timing: " &             to_string(Timing) & CR &
                             "  Clock_Period: " &       to_string(Clock_Period) & CR &
                             "  RoundingStyle: " &  str_substr(T_ROUNDING_STYLE'image(RoundingStyle), 7) & CR &
                             "  res_real = " &          str_format(res_real, 3) & CR &
                             "  => " &                  INTEGER'image(res_nat)
                severity note;
    
            return res_nat;
        end;
    
        function TimingToCycles(Timing : TIME; Clock_Frequency  : FREQ; RoundingStyle : T_ROUNDING_STYLE := ROUND_TO_NEAREST) return NATURAL is
        begin
            return TimingToCycles(Timing, to_time(Clock_Frequency), RoundingStyle);
        end function;
    
        -- convert and format physical types to STRING
        function to_string(t : TIME; precision : NATURAL := 3) return STRING is
            variable unit       : STRING(1 to 3)    := (others => NUL);
            variable value  : REAL;
        begin
            if (t < 1.0 ps) then
                unit(1 to 2)    := "fs";
                value           := to_real(t, 1.0 fs);
            elsif (t < 1.0 ns) then
                unit(1 to 2)    := "ps";
                value           := to_real(t, 1.0 ps);
            elsif (t < 1.0 us) then
                unit(1 to 2)    := "ns";
                value           := to_real(t, 1.0 ns);
            elsif (t < 1.0 ms) then
                unit(1 to 2)    := "us";
                value           := to_real(t, 1.0 us);
            elsif (t < 1.0 sec) then
                unit(1 to 2)    := "ms";
                value           := to_real(t, 1.0 ms);
            else
                unit            := "sec";
                value           := to_real(t, 1.0 sec);
            end if;
    
            return str_format(value, precision) & " " & str_trim(unit);
        end function;
    
        function to_string(f : FREQ; precision : NATURAL := 3) return STRING is
            variable unit       : STRING(1 to 3)    := (others => NUL);
            variable value  : REAL;
        begin
            if (f < 1.0 kHz) then
                unit(1 to 2)    := "Hz";
                value           := to_real(f, 1.0 Hz);
            elsif (f < 1.0 MHz) then
                unit            := "kHz";
                value           := to_real(f, 1.0 kHz);
            elsif (f < 1.0 GHz) then
                unit            := "MHz";
                value           := to_real(f, 1.0 MHz);
            elsif (f < 1.0 THz) then
                unit            := "GHz";
                value           := to_real(f, 1.0 GHz);
            else
                unit            := "THz";
                value           := to_real(f, 1.0 THz);
            end if;
    
            return str_format(value, precision) & " " & str_trim(unit);
        end function;
    end package body;
    
    
    library IEEE;
    use     IEEE.STD_LOGIC_1164.ALL;
    use     IEEE.NUMERIC_STD.ALL;
    
    use     work.utils.all;
    use     work.strings.all;
    use     work.physical.all;
    
    entity Top_PhysicalTest is
        Port (
            Clock   : in    STD_LOGIC;
            Input   : in    STD_LOGIC;
            Output  : out   STD_LOGIC
        );
    end;
    
    architecture rtl of Top_PhysicalTest is
        -- configuration
        constant CLOCK_FREQ                 : FREQ          := 100 MHz;
        constant SHIFTER_DELAY              : TIME          := 125 ns;
        -- calculations
        constant SHIFTER_DELAY_CYCLES       : NATURAL       := TimingToCycles(SHIFTER_DELAY, CLOCK_FREQ);
        constant SHIFTER_BITS               : NATURAL       := SHIFTER_DELAY_CYCLES + 2; -- to prevent an underrun, while Vivado has a bug
    
        signal Shifter_nxt                  : STD_LOGIC_VECTOR(SHIFTER_BITS - 1 downto 0);
        signal Shifter_d                    : STD_LOGIC_VECTOR(SHIFTER_BITS - 2 downto 0)   := (others => '0');
    
    begin
        assert false report "CLOCK_FREQ: " & FREQ'image(CLOCK_FREQ)                             severity note;
        assert false report "CLOCK_FREQ: " & to_string(CLOCK_FREQ)                            severity note;
        assert false report "DELAY: "      & TIME'image(SHIFTER_DELAY)                      severity note;
        assert false report "DELAY: "      & to_string(SHIFTER_DELAY)                       severity note;
        assert false report "CYCLES: "     & INTEGER'image(SHIFTER_DELAY_CYCLES)  severity note;
    
        Shifter_nxt <= Shifter_d & Input;
        Shifter_d   <= Shifter_nxt(Shifter_d'range) when rising_edge(Clock);
        Output      <= Shifter_nxt(SHIFTER_DELAY_CYCLES);
    end;
    

    UDPT :: =用户定义的物理类型

    我的观察:

    • 合成运行没有任何错误但导致错误计算
    • '图片未实现 - &gt;如何调试这个?
    • 似乎持有INTEGER'high
    • 的值

    问题:

    • 如何为Vivado解决这个问题?
    • 任何人都可以确认这种行为吗?
    • 哪种VHDL标准(87,93,...)引入了物理类型?

    注意:手动将我的问题从CR移到SO.

    编辑1:

    我将错误删除到:

    • 物理类型中的十进制文字是错误处理的 - &gt;每种情况下结果为0
    • 物理类型的
    • 属性'image(..)不再实施
    • 物理类型的操作,包括比较导致错误值
    • 物理类型的值范围不是单调的

    问题在Xilinx forum

    中报告

2 个答案:

答案 0 :(得分:1)

THz超出了Time类型的最小范围(参见IEEE Std 1076-2008,16.3 Package standard,&#34; type INTEGER是range implementation_defined;&#34;,5.2.3 Integer types&#34 ; ...实现可以限制类型为universal_integer的整数类型的范围约束的范围。但是,实现应允许声明任何整数类型,其范围完全包含在-2147483647和+2147483647的范围内。 #34;,输入FREQ)。

从头顶算起,行:pos 272:65,298:55,384:51。

我对你的结果并不感到惊讶。

  • 如何为Vivado解决这个问题?

预分频器。使用两个整数,一个用于某个整数单位的一小部分。或者使用位数组类型,它将问题转换为字符串转换之一。

在类型声明中,您似乎不太可能让Xilinx支持范围的64位整数:

type FREQ is range 0 to INTEGER'high units
    Hz;
    kHz = 1000 Hz;
    MHz = 1000 kHz;
    GHz = 1000 MHz;
    THz = 1000 GHz;
end units;
  • 任何人都可以确认这种行为吗?

算术运算完毕,没有Vivaldo。它表示支持32位整数。

  • 哪种VHDL标准(87,93,...)引入了物理类型?

正如Bill Lynch所说,物理类型可以在IEEE Std 1076-1987,3.1.3物理类型,第3-5页中找到。

这证明了在合成之前使用VHDL分析器/模拟器验证设计规范的优势:

  

ghdl -a top_physicaltest.vhdl
  top_physicaltest.vhdl:272:65:静态常量违反边界
  top_physicaltest.vhdl:298:55:静态常量违反边界
  top_physicaltest.vhdl:384:51:静态常量违反边界


使用ghdl-0.31我增加了FREQ的HIGH界限:

    type FREQ is range 0 to 2**61 units

这是有效的,因为ghdl的通用整数是64位,物理类型可以有一个通用的整数范围。

(ghdl中有一个bug,应该使用相当于2 ** 63 -1的整数,Tristan修正了我认为ghdl-0.33。我想知道2 ** 61是一个安全的界限。)

分析。您可以注意到Real Range限制了您执行任何缩放的准确性。没有检查,我无法告诉你ghdl是否有64位通用Real来匹配它的64位通用整数。

然后分析,精心制作并运行Top_PhysicalTest(测试平台)。

  

ghdl -r top_physicaltest
  ./top_physicaltest:error:物理检查失败在物理上.vhdl:117
  ghdl:编译错误

    -- raw_format_* functions
    function raw_format_nat_dec(value : NATURAL) return STRING is
    begin
        return INTEGER'image(value);
    end function;

    -- str_format_* functions
    function str_format(value : REAL; precision : NATURAL := 3) return STRING is
        constant s      : REAL          := sign(value);
        constant int    : INTEGER       := integer((value * s) - 0.5);                                                                      -- force ROUND_DOWN
        constant frac   : INTEGER       := integer((((value * s) - real(int)) * 10.0**precision) - 0.5);    -- force ROUND_DOWN
        constant res    : STRING        := raw_format_nat_dec(int) & "." & raw_format_nat_dec(frac); -- LINE 117
    begin
--      assert (not MY_VERBOSE)
--          report "str_format:" & CR &
--                       "  value:" & REAL'image(value) & CR &
--                       "  int = " & INTEGER'image(int) & CR &
--                       "  frac = " & INTEGER'image(frac)
--          severity note;
        return ite((s   < 0.0), "-" & res, res);
    end function;

其中,第117行是包体中包含常量res的声明。

来自std.standard:

subtype NATURAL is INTEGER range 0 to INTEGER'HIGH;

ghdl中的类型整数是32位精度(在综合工具中普遍存在)。

这看起来像'IMAGE错误我可能会或可能没有通知Tristan(Yup!,见#31 Type conversion subtype constraint check not performed,它也固定为0.33(gee I&#39;我想跳过0.32我认为))。

所以我尝试了nvc,它也有64位通用整数,我之前提交了一些与表达式有关的错误:

  

nvc -a physical.vhdl
  nvc -e Top_PhysicalTest
  **致命:表达式不能折叠成整数常数
      文件physical.vhdl,第412行

Line 412在Top_PhysicalTest中:

    constant CLOCK_FREQ                 : FREQ          := 100 MHz;
    constant SHIFTER_DELAY              : TIME          := 125 ns;
    -- calculations
    constant SHIFTER_DELAY_CYCLES       : NATURAL       := TimingToCycles(SHIFTER_DELAY, CLOCK_FREQ);
    constant SHIFTER_BITS               : NATURAL       := SHIFTER_DELAY_CYCLES + 2; -- to prevent an underrun, while Vivado has a bug

    constant SHIFTER_BITS               : NATURAL       := SHIFTER_DELAY_CYCLES + 2; -- to prevent an underrun, while Vivado has a bug

    signal Shifter_nxt                  : STD_LOGIC_VECTOR(SHIFTER_BITS - 1 downto 0);

信号Shifter_nxt的声明。

(看起来像是一种不同类型的错误)。

答案 1 :(得分:0)

我看来Xilinx Vivado 2019.2将修复物理类型,尤其是时间。

摘自Vivado 2019.2发行说明:
enter image description here