vhdl:object子类型不是本地静态的

问题描述 投票:0回答:1

使用GHDL编译一些VHDL得到一个奇怪的错误。 VHDL的模拟编译器在线失败:“case i_cli_adr is”,错误消息:“vhdl:object subtype not local static”。怎么解决?

library ieee;
use ieee.std_logic_1164.all;

entity sim_regs is
    generic(
        LW                        : integer := 16
    );
    port(
        i_sys_clk                 : in    std_logic;
        i_sys_rst_n               : in    std_logic;

        i_cli_vld                 : in    std_logic;
        i_cli_wnr                 : in    std_logic;
        i_cli_adr                 : in    std_logic_vector(LW-1 downto 0);
        i_cli_dat                 : in    std_logic_vector(LW-1 downto 0);
    );
end entity;

architecture sim of sim_regs is
    signal     testreg0                  : std_logic_vector(LW-1 downto 0);
    signal     testreg1                  : std_logic_vector(LW-1 downto 0);
    signal     awrite                    : std_logic;
begin

awrite <= i_cli_vld and i_cli_wnr;

process(i_sys_clk)
begin
    if (i_sys_clk = '1' and i_sys_clk'event) then
        if (i_sys_rst_n = '0') then
            testreg0   <= (others => '0');
            testreg1   <= (others => '0');
        end if;

    else 
       o_cli_rvld <= '0';      

        if (awrite = '1') then
            case i_cli_adr is
            when 0 => testreg0 <= i_cli_dat;
            when 1 => testreg1 <= i_cli_dat;
            end case;   
        end if;
    end if;

end process;

end architecture;

vhdl
1个回答
0
投票

解决方法是在内部硬编码地址大小

architecture sim of sim_regs is

    signal     aaddr                     : std_logic_vector(15 downto 0);

begin

    aaddr  <= i_cli_adr and X"FFFF";

    --- now can use aaddr in place of i_cli_adr in "case"

完整示例:

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

entity sim_regs is
    generic(
        LW                        : integer := 16
    );
    port(
        i_sys_clk                 : in    std_logic;
        i_sys_rst_n               : in    std_logic;

        i_cli_vld                 : in    std_logic;
        i_cli_wnr                 : in    std_logic;
        i_cli_adr                 : in    std_logic_vector(LW-1 downto 0);
        i_cli_dat                 : in    std_logic_vector(LW-1 downto 0);
        o_cli_rdat                : out   std_logic_vector(LW-1 downto 0);
        o_cli_rvld                : out   std_logic;
        i_cli_rbsy                : in    std_logic        
    );
end entity;

architecture sim of sim_regs is
    signal     testreg0                  : std_logic_vector(LW-1 downto 0);
    signal     testreg1                  : std_logic_vector(LW-1 downto 0);
    signal     testreg2                  : std_logic_vector(LW-1 downto 0);
    signal     testreg3                  : std_logic_vector(LW-1 downto 0);
    signal     aaddr                     : std_logic_vector(15 downto 0);
    signal     awrite                    : std_logic;
    signal     aread                     : std_logic;
begin

awrite <= i_cli_vld and i_cli_wnr;
aread  <= i_cli_vld and  not i_cli_wnr and not i_cli_rbsy;
aaddr  <= i_cli_adr and X"FFFF";

process(i_sys_clk)
begin
    if (i_sys_clk = '1' and i_sys_clk'event) then
        if (i_sys_rst_n = '0') then
            o_cli_rvld <= '0';
            o_cli_rdat <= (others => '0');
            testreg0   <= (others => '0');
            testreg1   <= (others => '0');
            testreg2   <= (others => '0');
            testreg3   <= (others => '0');
        end if;

    else 
       o_cli_rvld <= '0';      

        if (awrite = '1') then
            case aaddr is
            when X"0000" => testreg0 <= i_cli_dat;
            when X"0001" => testreg1 <= i_cli_dat;
            when X"0002" => testreg2 <= i_cli_dat;
            when X"0003" => testreg3 <= i_cli_dat;
            when others  => null;
            end case;

        elsif (aread = '1') then
            o_cli_rvld <= '1';  

            case aaddr is
            when X"0000" => o_cli_rdat <= testreg0;
            when X"0001" => o_cli_rdat <= testreg1;
            when X"0002" => o_cli_rdat <= testreg2;
            when X"0003" => o_cli_rdat <= testreg3;
            when others  => o_cli_rdat <= (others => '0');
            end case;      
        end if;
    end if;

end process;

end architecture;