GHDL模拟器:numeric_std-body.v93:NUMERIC_STD。“ =”:检测到空参数,返回FALSE

时间:2019-04-30 16:32:45

标签: vhdl

我正在尝试使用GHDL模拟器来模拟我的VHDL代码,并且该模拟器从“ numeric_std”库中产生许多警告消息,我试图记住是什么原因导致了这些错误以及如何防止它们出现在GHDL模拟器中。是否可以修改代码以防止它们或添加模拟器标志或在代码中添加杂注? :

numeric_std-body.v93:1605:7:@0ms:(assertion warning): NUMERIC_STD."=": null argument detected, returning FALSE

Windows运行脚本:

..\simtools\ghdl\bin\ghdl.exe -a bus_fifo_mem.vhdl
..\simtools\ghdl\bin\ghdl.exe -a bus_fifo.vhdl
..\simtools\ghdl\bin\ghdl.exe -e bus_fifo
..\simtools\ghdl\bin\ghdl.exe -r bus_fifo

numeric_std-body.v93:1605:7:@0ms:(assertion warning): NUMERIC_STD."=": null argument detected, returning FALSE

library ieee;
use ieee.std_logic_1164.all;
use IEEE.numeric_std.all;

entity bus_fifo is
    generic(
        DEPTH_WIDTH               : integer := 0;
        DATA_WIDTH                : integer := 0
    );
    port(
        clk         : in    std_logic;
        rst         : in    std_logic;
        wr_data_i   : in    std_logic_vector(DATA_WIDTH-1 downto 0);
        wr_en_i     : in    std_logic;
        rd_data_o   : out   std_logic_vector(DATA_WIDTH-1 downto 0);
        rd_en_i     : in    std_logic;
        full_o      : out   std_logic;
        empty_o     : out   std_logic        
    );
end entity;
architecture rtl of bus_fifo is
    constant   DW                        : integer := DATA_WIDTH;
    constant   AW                        : integer := DEPTH_WIDTH;
    signal     write_pointer             : unsigned(AW downto 0);
    signal     read_pointer              : unsigned(AW downto 0);
    signal     empty_int                 : std_logic;
    signal     full_or_empty             : std_logic;
begin

    process(write_pointer, read_pointer)
    begin
        if (write_pointer(AW) = read_pointer(AW)) then
            empty_int <= '1';
        else 
            empty_int <= '0';
        end if;
    end process;


    process(write_pointer, read_pointer)
    begin
        if (write_pointer(AW-1 downto 0) = read_pointer(AW-1 downto 0)) then
            full_or_empty <= '1';
        else 
            full_or_empty <= '0';
        end if;
    end process;

    full_o  <= full_or_empty and not empty_int;
    empty_o <= full_or_empty and empty_int;

    process(clk)
    begin   
        if (wr_en_i = '1') then
            write_pointer <= write_pointer + 1;
        end if;

        if (rd_en_i = '1') then
            read_pointer <= read_pointer + 1;
        end if;

        if (rst = '1') then
            read_pointer  <= (others => '0');
            write_pointer <= (others => '0');
        end if;
    end process;

    bus_fifo_mem: entity work.bus_fifo_mem
        generic map(
            ADDR_WIDTH    => AW,
            DATA_WIDTH    => DW,
            ENABLE_BYPASS => 1
        )
        port map(
            clk         => clk,
            dout        => rd_data_o,
            raddr       => std_logic_vector(read_pointer(AW-1 downto 0)),
            re          => rd_en_i,
            waddr       => std_logic_vector(write_pointer(AW-1 downto 0)),
            we          => wr_en_i,
            din         => wr_data_i
        );

end architecture;


library ieee;
use ieee.std_logic_1164.all;
use IEEE.numeric_std.all;

entity bus_fifo_mem is
    generic(
        ADDR_WIDTH     : integer := 32;
        DATA_WIDTH     : integer := 32;
        ENABLE_BYPASS  : integer := 1
    );
    port(
        clk    : in    std_logic;
        raddr  : in    std_logic_vector(ADDR_WIDTH-1 downto 0);
        re     : in    std_logic;
        waddr  : in    std_logic_vector(ADDR_WIDTH-1 downto 0);
        we     : in    std_logic;
        din    : in    std_logic_vector(DATA_WIDTH-1 downto 0);
        dout   : out   std_logic_vector(DATA_WIDTH-1 downto 0)        
    );
end entity;

architecture rtl of bus_fifo_mem is
    signal     rdata  : std_logic_vector(DATA_WIDTH-1 downto 0);
    signal     din_r  : std_logic_vector(DATA_WIDTH-1 downto 0);
    signal     bypass : std_logic;

    -- VERILOG
    --reg [DATA_WIDTH-1:0] mem[(1<<ADDR_WIDTH)-1:0];

    type mem_type is array (integer'(2) ** ADDR_WIDTH - 1 downto 0) 
          of std_logic_vector(DATA_WIDTH-1 downto 0);

    signal mem : mem_type := (others => (others => '0'));

begin

process(clk)
begin
    if (clk = '1' and clk'event) then

        if (we = '1') then
            mem(to_integer(unsigned(waddr))) <= din;
        end if;

        if (re = '1') then
           rdata <= mem(to_integer(unsigned(raddr)));
        end if;

    end if;
end process;


end architecture;

3 个答案:

答案 0 :(得分:0)

对于GHDL模拟器,请参见--run-help:

..选项:: --ieee-asserts <= POLICY>

选择来自ieee单位的断言如何 处理。 POLICY可以是enable(默认值), disable会禁用ieee包中的所有断言 和disable-at-0仅在模拟开始时禁用。

此选项对于避免从 ieee.numeric_std(和其他ieee软件包)。

# PowerShell Build Script
class build {
    [Void] static info1([string]$msg) {
        write-host -background DarkBlue -foreground yellow $msg
    }
    [Void] static info2([string]$msg) {
        write-host -background DarkBlue -foreground cyan $msg
    }

    [void] static read ([string]$file) {
        $GHDL="..\simtools\ghdl\bin\ghdl.exe"

        [build]::info2("")
        [build]::info2("GHDL ANALYSIS: " + $file)
        & $GHDL "-a" $file
    }

    [void] static elab ([string]$unit) {
        $GHDL="..\simtools\ghdl\bin\ghdl.exe"

        [build]::info2("")
        [build]::info2("GHDL ELAB: " + $unit)
        & $GHDL "-e" $unit
    }

    [void] static run ([string]$unit) {
        $GHDL="..\simtools\ghdl\bin\ghdl.exe"

        [build]::info2("")
        [build]::info2("GHDL RUN: " + $unit)
        & $GHDL "-r" $unit "--ieee-asserts=disable-at-0"
    }

}

# RTL Design
[build]::read("bus_fifo_mem.vhdl")
[build]::read("bus_fifo.vhdl")

[build]::elab("bus_fifo")
[build]::run("bus_fifo")

答案 1 :(得分:0)

对于GHDL,以下是一个powershell脚本,该脚本可能会关闭这些VHDL消息:

class build {
    [Void] static info1([string]$msg) {
        write-host -background DarkBlue -foreground yellow $msg
    }
    [Void] static info2([string]$msg) {
        write-host -background DarkBlue -foreground cyan $msg
    }

    [void] static read ([string]$file) {
        $GHDL="..\simtools\ghdl\bin\ghdl.exe"

        [build]::info2("")
        [build]::info2("GHDL ANALYSIS: " + $file)
        & $GHDL "-a" $file
        [build]::info1(" $GHDL -a " + $file)
    }

    [void] static elab ([string]$unit) {
        $GHDL="..\simtools\ghdl\bin\ghdl.exe"

        [build]::info2("")
        [build]::info2("GHDL ELAB: " + $unit)
        & $GHDL "-e" $unit
        [build]::info1(" $GHDL -e " + $unit)
    }

    [void] static run ([string]$unit) {
        $GHDL="..\simtools\ghdl\bin\ghdl.exe"

        [build]::info2("")
        $cmd = "$GHDL ""-r"" $unit ""--ieee-asserts=disable-at-0"" ""--vcd=ghdl_waves.vcd"" " 
        [build]::info2("GHDL RUN: " + $unit)
        [build]::info1("$cmd")
        & $GHDL "-r" $unit "--ieee-asserts=disable-at-0" "--vcd=ghdl_waves.vcd" "--stop-time=1us" "--disp-time"
    }

}

# RTL Design
[build]::read("hello.vhdl")
[build]::elab("hello")
[build]::run("hello")

答案 2 :(得分:-1)

不确定如何在GHDL仿真器中禁用此警告...

这是因为在0 ns时,我对无效值(可能是“ UUUU”)执行to_integer。在重设设计之前,不要预料到任何这些警告,并且不要表示任何错误。但是,如果您在重置后得到它们,就会有问题。

“可以禁止显示警告。IEEE Std 1076-2008 16.8.5.2第2部分允许的修改(部分)NUMERIC_BIT和NUMERIC_STD程序包的程序包主体声明了一个名为NO_WARNING的常量,其值为FALSE。用户可以设置NO_WARNING设置为TRUE,然后重新分析程序包主体以禁止调用由这些程序包或modelsim.ini中的函数生成的警告消息,取消注释或设置NumericStdNoWarnings =1。它们是由存在于有符号或无符号中且其二进制值为通常在初始化时进行评估。查看您的组件。”

Package numeric_std is
...
end numeric_std;

Package body numeric_std is
   ...
   constant NO_WARNING : boolean := FALSE;  -- default to emit warnings
   ...
end numeric_std;

实际上,我可以通过将默认值从零更改为以下代码来修复此警告消息:(DEPTH_WIDTH:integer:= 2; DATA_WIDTH:integer:= 2),然后使用函数检查未签名的信号是否不是未定义的“ x” “ is_X(…)”…我只是不知道以下代码是否可合成:

    process(write_pointer, read_pointer)
    begin
        if (is_X(write_pointer) or is_X(read_pointer)) then         
            empty_int <= 'U';

        elsif (write_pointer(AW) = read_pointer(AW)) then
            empty_int <= '1';
        else 
            empty_int <= '0';
        end if;
    end process;


    process(write_pointer, read_pointer)
    begin
        if (is_X(write_pointer) or is_X(read_pointer) then          
            full_or_empty <= 'U';

        elsif (write_pointer(AW-1 downto 0) = read_pointer(AW-1 downto 0)) then
            full_or_empty <= '1';

        else 
            full_or_empty <= '0';
        end if;
    end process;