0
votes

My requirement is to compare the two array values using case statement. So I am using a for loop for all iterations.

Both are Input arrays : Memory_in array(expression) values are compared with sorted_array(choice) array values and Shaped_data is the output array (case statements).

I am getting static case error for my code below:

process (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;

The logic can be implemented using if else statement also but case statement would require less hardware. So I thought case statement would be better.

Is this error because of i value ? how do i do this ?

3
Each choice (IEEE Std 1076-2008, 9.3.3.1 {simple_expression, discrete_range, *element_*simple_name, others} if a simple expression (9.1, term--factor-primary-name-indexed_name, 8.1) must be locally static (10.9). "if the expression is the name of an object whose subtype is locally static, whether a scalar type or an array type, then each value of the subtype shall be represented once and only once in the set of choices of the case statement, and no other value is allowed;" (9.1). That's not possible with non-locally static values {variables, signals}.user1155120

3 Answers

2
votes

Whenever you find a big but regular structure, you can usually exploit that regularity. In this case, it simply means another loop.

What you have written reduces to something very like this:

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;
0
votes

The syntax of a VHDL case statement is:

[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}

It's an error because the choice must be one of

  • constant expression
  • range
  • others

In your code the choice (sorted_array) is none of these; you say it is an "input".

0
votes

Tip: Assign your case selection vector to a local process variable. (I don't know why, but, VHDL just requires you to do this.) Also, while you are assigning it to a local variable of the process, convert std_logic_vector to "unsigned" then "resize" it to the width of your case literals. Example:

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;

A more detailed example:

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;