VHDL错误:CASE语句替代选择必须是本地静态的

时间:2017-03-01 15:11:57

标签: arrays switch-statement vhdl

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

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

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

进程(clk)

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语句需要更少的硬件。所以我认为案例陈述会更好。

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

3 个答案:

答案 0 :(得分:1)

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

你所写的东西简化为非常类似的东西:

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;

答案 1 :(得分:0)

VHDL case语句的语法是:

  

[标签 :] case 表达式 is

     

when 选择 => SequentialStatements ... {任意数量   当部分}

     

end case [标签] ;

     

选择 = 选择 | 选择 | ...

     

选择 = {one of}

     

ConstantExpression

     

范围

     

others {最后一个分支}

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

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

在您的代码中,选择sorted_array)不是这些;你说这是一个“输入”。

答案 2 :(得分:0)

提示:将案例选择向量分配给本地过程变量。 (我不知道为什么,但是,VHDL只要求您执行此操作。)此外,在将其分配给进程的局部变量时,请将std_logic_vector转换为“ unsigned”,然后将其“调整大小”为您的宽度大小写文字。示例:

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;