xornonop
xornonop

Reputation: 51

VDHL loop with variable outside of the process (how to be)

How can I avoid variable in this loop (outside the process)?

variable var1 : std_logic_vector (ADRESS_WIDTH-1 downto 0) := (others => '0');

        for i in 0 to ADRESS_WIDTH-2 loop
            var1 := var1 + '1';
            with r_addr select
             fifo_data_out <= array_reg(i) when var1,
        end loop;
        array_reg(ADRESS_WIDTH-1) when others;

This version (in process) isn't correct too - syntax errors

process (r_addr, r_addr1, fifo_data_out, array_reg, r_data1)
variable var1 : std_logic_vector (ADRESS_WIDTH-1 downto 0) := (others => '0');

begin

case r_addr is
    when "0000000000" => fifo_data_out <= array_reg(0);
        for i in 1 to ADRESS_WIDTH-2 loop
            when var1 => fifo_data_out <= array_reg(i);
            var1 := var1 + '1';
        end loop;
     when others => fifo_data_out <= array_reg(ADRESS_WIDTH-1);
end case;

Upvotes: 1

Views: 5555

Answers (1)

Jeff Langemeier
Jeff Langemeier

Reputation: 1018

There's a bunch of things that aren't quite right on your implementation. Completely agnostic of what you're trying to accomplish there are some things with VHDL that should be remembered:

  • Every opening statement must have a closing one.
  • Every nesting level must have a closing statement to "un-nest" it
  • You can't put portions of one statement set (the case internals) inside another statement (the for loop), this seems odd, but think about it, what case is it going to attach itself to.
  • VHDL and hardware programming in general is ridiculously parallel, from one iteration to the next the process is completely independent of all other processes.

Now, looking at your code I see what looks like what you want to accomplish, and this is a perfect example of why you should know a little bit of scripting in another language to help out hardware level programming. You should be as specific as possible when creating a process, know what you want to accomplish and in what bounds, I know this is like every other languages but hardware programming gives you all the tools to hang yourself very very thoroughly. Here's the best that I can make out from your code to clean things up.

async_process : process (r_addr, fifo_data_out, array_reg)

begin
    case r_addr is
        when "0000000000" => fifo_data_out <= array_reg(0);
        when "0000000001" => fifo_data_out <= array_reg(1);
        when "0000000002" => fifo_data_out <= array_reg(2);
        when others => fifo_data_out <= array_reg(ADRESS_WIDTH-1);
    end case;
end process;

r_addr_inc_process : process (clock <or other trigger>, reset)
    <This is where you would deal with the bounds of the register address.  
     If you still want to deal with that variable, do it here.>
end process;

So, as you can see from this, you want to update as few things as possible when you're dealing with a process, this way your sensitivity list is extremely specific, and you can force most updating to occur synchronously instead of asynchronously. The reason your async process can be as such is that it will update every time r_addr is updated, and that happens every clock read, or on some flag, and it gives you a consistent reset state.

With how iterative the process is, you can see how using a scripting language to fill in the 100's of register values would help it from being very time consuming.

Upvotes: 1

Related Questions