Vivado可以处理用户定义的物理类型吗? [英] Can Vivado handle user defined physical types?

查看:239
本文介绍了Vivado可以处理用户定义的物理类型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wrote some cross platform VHDL libraries for Xilinx XST, iSim, Altera Quartus II, Mentor Graphics QuestaSim and GHDL. Now I wanted to port my ISE 14.7 project, which uses these libraries to Vivado 2014.4, but one library seems to have fatal problems.

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

My library physical defines several new user defined physical types like: FREQUENCY and BAUD; conversion functions and report functions.

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

One main use case is the calculation of delay or counter cycles for a given delay and system frequency. So for example a delay of 125 ns requires 12 or 13 delay cycles at 100 MHz (it depends on the rounding mode at .5).

我从Vivado Synth得到了一些信息和警告(一些是assert语句的结果,请参见下面的最小示例):

I get several infos and warnings from Vivado Synth (some are results of an assert statement, see minimal example below):

[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

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

My scenario is a bit complex, so the minimal example look not as minimal as it should look. I did not inline every function to prevent copy/replace errors and I did not remove the debug and assert/report routines.

概述:

  1. 软件包实用程序:常见的类型,枚举和函数
  2. 打包字符串:字符串操作和转换功能
  3. 物理包装:新类型及其功能
  4. 实体:实现简单延迟元素/移位寄存器的单个顶级实体

最小示例:

-- 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 :: =用户定义的物理类型

我的观察:

  • 合成过程没有任何错误,但会导致错误的计算
  • '图像未实现->应该如何调试此图像?
  • 似乎保持着INTEGER'high的价值

问题:

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

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

我将错误归结为:

  • 对物理类型的十进制文字进行了错误处理->在每种情况下结果均为0
  • 不再实现有关物理类型的
  • 属性'image(..)
  • 具有物理类型的
  • 操作,包括比较会导致错误的值
  • 物理类型的值范围不是单调的
  • decimal literals in physical types are false handled -> result is 0 in every case
  • attribute 'image(..) on physical types is not implemented any more
  • operations with physical types, incl. comparisons results in false values
  • value ranges of physical types are not monotone

Xilinx论坛.

推荐答案

THz在类型为Time的最小范围内超出范围(请参阅IEEE Std 1076-2008,16.3封装标准,类型INTEGER是range Implementation_defined;", 5.2.3整数类型"...实现可能会限制除universal_integer类型之外的整数类型的范围约束的界限.但是,实现应允许声明其范围完全包含在界限内的任何整数类型–2147483647和+2147483647(含).",键入FREQ).

THz is out of range for the minimum range of type Time (see IEEE Std 1076-2008, 16.3 Package standard, "type INTEGER is range implementation_defined;", 5.2.3 Integer types "...An implementation may restrict the bounds of the range constraint of integer types other than type universal_integer. However, an implementation shall allow the declaration of any integer type whose range is wholly contained within the bounds –2147483647 and +2147483647 inclusive.", type FREQ).

从顶部开始计数,行:pos 272:65、298:55、384:51.

Counting from the top, line:pos 272:65, 298:55, 384:51.

我对您的结果并不感到惊讶.

I'm not surprised at your results.

  • 如何为Vivado修复此问题?

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

Prescalers. Use two integers, one for a fraction part of some integer unit. Alternatively use a bit array type, which shifts the problem to one of string conversion.

Xilinx不太可能像类型声明中那样支持范围的64位整数:

It seems unlikely you'll get Xilinx to support 64 bit integers for ranges as in the type declaration:

type FREQ is range 0 to INTEGER'high units
    Hz;
    kHz = 1000 Hz;
    MHz = 1000 kHz;
    GHz = 1000 MHz;
    THz = 1000 GHz;
end units;

  • 任何人都可以确认这种行为吗?
  • 算术有效,没有维瓦尔多.它说支持32位整数.

    The arithmetic works out, no Vivaldo. It says 32 bit integers are supported.

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

    比尔·林奇(Bill Lynch)指出,物理类型位于IEEE Std 1076-1987,3.1.3物理类型,第3-5页.

    As Bill Lynch notes physical types are found in IEEE Std 1076-1987, 3.1.3 Physical types, Page 3-5.

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

    This demonstrates the advantages of using a VHDL analyzer/simulator to validate a design specification before synthesis:

    ghdl -a top_physicaltest.vhdl
    top_physicaltest.vhdl:272:65:静态常数超出范围
    top_physicaltest.vhdl:298:55:静态常数超出范围
    top_physicaltest.vhdl:384:51:静态常数超出范围

    ghdl -a top_physicaltest.vhdl
    top_physicaltest.vhdl:272:65: static constant violates bounds
    top_physicaltest.vhdl:298:55: static constant violates bounds
    top_physicaltest.vhdl:384:51: static constant violates bounds


    使用ghdl-0.31,我提高了FREQ的上限:


    Using ghdl-0.31 I increased the HIGH bound of FREQ:

        type FREQ is range 0 to 2**61 units
    

    之所以可行,是因为ghdl的通用整数是64位,并且物理类型可以具有通用整数范围.

    This works because ghdl's universal integer is 64 bit and physical types can have a universal integer range.

    (ghdl中有一个错误,应该与2 ** 63 -1的整数等效,我认为是Tristan修复了ghdl-0.33.我碰巧知道2 ** 61是一个安全界限).

    (There's a bug in ghdl, should work with the integer equivalent of 2**63 -1, Tristan's fixed it I think for ghdl-0.33. I happended to know 2**61 is a safe bound).

    那就分析了.您可能会注意到,真实范围"限制了您演奏的任何缩放的准确性.如果不检查,我无法告诉您ghdl是否具有64位通用实数来匹配它的64位通用整数.

    That analyzes. You could note that the Real Range limits the accuracy of any scaling your perform. Without checking I couldn't tell you if ghdl has a 64 bit universal Real to match it's 64 bit universal integer.

    然后分析,详细说明并运行Top_PhysicalTest(测试平台).

    So then analyze, elaborate and run Top_PhysicalTest (the test bench).

    ghdl -r top_physicaltest
    ./top_physicaltest:错误:Physical.vhdl:117的绑定检查失败
    ghdl:编译错误

    ghdl -r top_physicaltest
    ./top_physicaltest:error: bound check failure at physical.vhdl:117
    ghdl: compilation error

        -- 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的声明.

    Where Line 117 is the declaration for constant res in the package body for package strings.

    并且来自标准标准:

    subtype NATURAL is INTEGER range 0 to INTEGER'HIGH;
    

    类型整数在ghdl中是32位精度(在综合工具中通常如此).

    Type integer is 32 bit precision in ghdl (and universally in synthesis tools).

    那似乎是一个'IMAGE错误,我可能已经通知Tristan,也可能没有通知(是!,请参阅#31未执行类型转换子类型约束检查,它也固定为0.33(我想我想跳过0.32).

    And that looks like a 'IMAGE error I may or may not have notified Tristan of (Yup!, see #31 Type conversion subtype constraint check not performed, it's fixed for 0.33, too (gee I'm going to skip 0.32 I think)).

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

    So I tried with nvc, which also has 64 bit universal integers, and I had previously submitted some errors to do with expressions for:

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

    nvc -a physical.vhdl
    nvc -e Top_PhysicalTest
    ** Fatal: expression cannot be folded to an integer constant
    File physical.vhdl, Line 412

    第412行在Top_PhysicalTest中:

    And Line 412 is in 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的声明.

    The declaration for signal Shifter_nxt.

    (看起来像是另一种错误).

    (And which looks like a different type of error).

    这篇关于Vivado可以处理用户定义的物理类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆