6

Could you tell me if there is a better way to write a priority encoder in VHDL than just using if-else statements? I mean, I have got this code and it works, but could it be written shorter? Switch is an std_logic_vector.

Thanks for your help!

shifting : PROCESS(CLK_IN, new_length_ready, switch)

    VARIABLE highest_switch :      INTEGER RANGE 0 TO 15 := 15;

BEGIN

    -- priority encoder, changes the length of the snake track 
    -- ( i.e., number of leds for the snake to move )

    IF switch(15) = '1' THEN
        highest_switch := 15;
    ELSIF switch(14) = '1' THEN
        highest_switch := 14;
    ELSIF switch(13) = '1' THEN
        highest_switch := 13;
    ELSIF switch(12) = '1' THEN
        highest_switch := 12;
    ELSIF switch(11) = '1' THEN
        highest_switch := 11;
    ELSIF switch(10) = '1' THEN
        highest_switch := 10;
    ELSIF switch(9) = '1' THEN
        highest_switch := 9;
    ELSIF switch(8) = '1' THEN
        highest_switch := 8;
    ELSIF switch(7) = '1' THEN
        highest_switch := 7;
    ELSIF switch(6) = '1' THEN
        highest_switch := 6;
    ELSIF switch(5) = '1' THEN
        highest_switch := 5;
    ELSIF switch(4) = '1' THEN
        highest_switch := 4;
    ELSIF switch(3) = '1' THEN
        highest_switch := 3;
    ELSIF switch(2) = '1' THEN
        highest_switch := 2;
    ELSIF switch(1) = '1' THEN
        highest_switch := 1;
    ELSIF switch(0) = '1' THEN
        highest_switch := 0;
    ELSE
        highest_switch := 15;
    END IF
petajamaja
  • 520
  • 2
  • 9
  • 26

1 Answers1

12

Within a process, you can use a loop.

type Switches is range 0 to 15;

shifting : PROCESS(switch)
   VARIABLE highest_switch : Switches := 15;
begin
   for i in Switches loop
      if switch(i) = '1' then 
         highest_switch := i;
      end if;
   end loop
...
end process;

Notice that if several switches are set, the variable is assigned multiple times. However as the loop is executed in increasing order, the last (highest) assignment wins.

Incidentally this process, like yours is combinational, but I removed unnecessary signals from the sensitivity list. It would be better to make it synchronous;

shifting : PROCESS(clk)
begin
   if rising_edge(clk) then
      for i in ...
   end if;
end process;
  • 1
    You could also order evaluation from highest to lowest switch and use an exit statement in the if statement. It simplifies the amount of synthesis optimization and simulates faster. You'd likely also want to assign highest_switch to NONE when none are '1' (setting to 15 appears a defect in the original). –  Aug 21 '18 at 18:53
  • 1
    @user1155120 thanks for the rollback. You're right about the exit statement, but I doubt the simulation time is significant. And as you surmised, I wanted to emulate the "feature" of the original. –  Aug 21 '18 at 20:08