VHDL Error : Choice in CASE statement alternative must be locally static

VHDL Error : Choice in CASE statement alternative must be locally static

我的要求是使用 case 语句比较两个数组值。所以我对所有迭代都使用 for 循环。

两者都是输入数组:Memory_in 数组(表达式)值与 sorted_array(选择)数组值进行比较,Shaped_data 是输出数组(case 语句)。

我的以下代码出现静态大小写错误:

进程(时钟)

variable in_array:     sorted;  
   variable out_array:     sorted;      
begin
  -- in_array := sorted_array;
    if rising_edge(clk) then
        for i in 0 to 15 loop 
            case (Memory_in(i)) is
          when sorted_array(0) => out_array(i) := x"F";
          when sorted_array(1) => out_array(i) := x"E";
          when sorted_array(2) => out_array(i) := x"D";
          when sorted_array(3) => out_array(i) := x"C";
          when sorted_array(4) => out_array(i) := x"B";
          when sorted_array(5) => out_array(i) := x"A";
          when sorted_array(6) => out_array(i) := x"9";
          when sorted_array(7) => out_array(i) := x"8";
          when sorted_array(8) => out_array(i) := x"7";
          when sorted_array(9) => out_array(i) := x"6";
          when sorted_array(10) => out_array(i) := x"5";
          when sorted_array(11) => out_array(i) := x"4";
          when sorted_array(12) => out_array(i) := x"3";
          when sorted_array(13) => out_array(i) := x"2";
          when sorted_array(14) => out_array(i) := x"1";
          when sorted_array(15) => out_array(i) := x"0";
          when others  => null;--out_array(i) := "ZZZZ";
     end case;
          end loop;
   Shaped_Data <= out_array;
       end if;
end process;

逻辑也可以使用 if else 语句来实现,但是 case 语句需要更少的硬件。所以我认为 case 语句会更好。

这个错误是因为我的值吗?我该怎么做?

VHDL case 语句的语法是:

[Label:] case Expression is

when Choices => SequentialStatements... {any number of when parts}

end case [Label];

Choices = Choice | Choice | ...

Choice = {one of}

ConstantExpression

Range

others {the last branch}

这是一个错误,因为选择必须是

之一
  • 常量表达式
  • 范围
  • others

在您的代码中,选项 (sorted_array) 是其中的 none;你说是 "input".

每当你发现一个大而规则的结构时,你通常可以利用这种规律性。在这种情况下,它只是意味着另一个循环。

您所写的内容简化为如下内容:

process (clk)
   variable out_array:     sorted;      
begin
  -- in_array := sorted_array;
    if rising_edge(clk) then
        for i in 0 to 15 loop 
            for j in 0 to 15 loop
                if Memory_in(i) = sorted_array(j) then
                    out_array(i) := 15 - j; -- maybe via type conversion
                end if;
            end loop;
        end loop;
        Shaped_Data <= out_array;
    end if;
end process;

提示:将您的案例选择向量分配给本地过程变量。 (我不知道为什么,但是,VHDL 只要求你这样做。)此外,当你将它分配给进程的局部变量时,将 std_logic_vector 转换为 "unsigned" 然后 "resize" 它到你的案例文字的宽度。示例:

process(amm_addr)
   variable addr :unsigned(31 downto 0); 
begin
    addr := resize(unsigned(amm_addr),32);

    ...
    case addr is
    when X"00000008" => null;
    when others => null;
    end case;
end process;

更详细的例子:

library ieee;
use     ieee.std_logic_1164.all;
use     ieee.numeric_std.all;  --for "unsigned" type and "resize" funciton

entity testit is
    generic(
        aw :natural := 12;
        dw :natural := 32
    );
    port(
        clk        :std_logic;
        rstn       :std_logic;

        amm_addr   :std_logic_vector(aw-1 downto 0);
        amm_wen    :std_logic;
        amm_wdata  :std_logic_vector(dw-1 downto 0);
        amm_ren    :std_logic;
        amm_rdata  :std_logic_vector(dw-1 downto 0);
        amm_rvalid :std_logic
    );
end entity;

architecture sim of testit is
    signal reg1 :std_logic_vector(dw-1 downto 0);
    signal reg2 :std_logic_vector(dw-1 downto 0);
    signal reg3 :std_logic_vector(dw-1 downto 0);
    signal reg4 :std_logic_vector(dw-1 downto 0);
begin

process(clk, rstn)
   variable addr :unsigned(31 downto 0); 
begin
    addr := resize(unsigned(amm_addr),32);

    if (rstn = '0') then
        reg1 <= (others => '0');
        reg2 <= (others => '0');
        reg3 <= (others => '0');
        reg4 <= (others => '0');    

    elsif (rising_edge(clk)) then
        if (amm_wen = '1') then
            case addr is 
            when X"00000000" => reg1 <= amm_wdata;
            when X"00000001" => reg2 <= amm_wdata;
            when X"00000002" => reg3 <= amm_wdata;
            when X"00000003" => reg4 <= amm_wdata;
            when others      => null;
            end case;
        end if;
    end if;
end process;

end architecture;