Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
15475 Discussions

Help with a VHDL code - using an array

Honored Contributor II



I want to use an array in order to check if my coordinates are correct, according to certain conditions. The coordinates represent a beginning point of a picture I will print on the screen using VGA and I want to duplicate this picture, I need to check if the coordinates (which I receive from a random numbers generator component) do not overlap. 


I tried to make an array and fill it according to the conditions, but after running simulations on my VHDL code I noticed that the output does not receive the values from my array, even though I assign them into the output. 


My code: 


library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.std_logic_unsigned.all; use ieee.numeric_std.all; use ieee.std_logic_arith.all; entity pigsCoordinate is port ( clk : in std_logic; resetN : in std_logic; limit : in integer; run : in std_logic; random : in std_logic_vector(7 downto 0); coordinate : out integer ); end pigsCoordinate; architecture pigsCoordinateArch of pigsCoordinate is type pigsArray is array (0 to 7) of integer range 0 to limit; signal pigsArray_signal: pigsArray := (0,0,0,0,0,0,0,0); signal counter : integer := 0; signal counterData : integer := 0; begin process (clk,resetN) variable tempLocation: integer := 0; begin if (resetN = '0') then coordinate <= 0; elsif rising_edge(clk) then if (run = '1') then tempLocation := conv_integer(random); if (counter = 0) then pigsArray_signal(counter) <= tempLocation; counter <= counter + 1; elsif (counter < 8) then pigsArray_signal(counter) <= tempLocation; for checkCounter in 0 to 7 loop exit when ((pigsArray_signal(counter) > pigsArray_signal(checkCounter)) and (pigsArray_signal(counter) < (pigsArray_signal(checkCounter) + 26) and (counter /= checkCounter))); end loop; counter <= counter + 1; elsif (counter = 8) and (counterData < 8) then coordinate <= pigsArray_signal(counterData); counterData <= counterData + 1; end if; end if; end if; end process; end pigsCoordinateArch;  


Thank you very much for your help and attention!
0 Kudos
4 Replies
Honored Contributor II

Try and simulate your code, or use signaltap in an FPGA project to see what is happening. 

type pigsArray is array (0 to 7) of integer range 0 to limit; 

limit is a variable input and can't be used to constrain a type. I don't even understand how this compiled without error. Use a generic for limit instead of an input. 


for checkCounter in 0 to 7 loop exit when ((pigsArray_signal(counter) > pigsArray_signal(checkCounter)) and (pigsArray_signal(counter) < (pigsArray_signal(checkCounter) + 26) and (counter /= checkCounter))); end loop;  

I don't understand exactly what you tried to do here, but as is this loop doesn't do anything. It just tests values and exits early if certain conditions are met, but it doesn't change any signal or output, so it is probably removed by the synthesizer.
Honored Contributor II

Thank you very much for your reply! 


I tried to simulate my code, but I didn't receive the result I wanted. 


I wanted to create an array with integers range of 0 to a given limit. Do I always have to define a constant limit? 

For example, if I want to create the same component but one with integers range 0 to 100 and the other one with range 0 to 200, do I need to create two VHDL codes, And change this single number in both of them? 


As for the for loop, I have another component that generates a random number, and it changes with every clock cycle. If this condition is true, I want to exit the loop and try to fill this element of the array in the next clock cycle (so I don't go to the next element, meaning don't increase the counter), when I have a new random value. Does it make any sense? 


I am beginner in VHDL coding. Thank you again for your help and attention!
Honored Contributor II

You can define a generic so that the range can be set when you instantiate the component. 


Currently the loop does nothing because remember that all the code will be executed on every clock cycle. This is hardware description, not software programming. Did you draw the circuit before you wrote the code?
Honored Contributor II

The main problem with your loop is that the line "counter <= counter + 1;" will always be executed, whatever the conditions you test inside the loop are. 

If I understand correctly what you mean (i.e. that the "counter <= counter + 1;" only be executed if the condition you test for is never met inside the loop) then you could do that by adding a boolean variable in your process, for example called "new_code_valid", initially set to true, and that you set to false with an if inside your loop when the condition is met. Then outside of the loop you add a second if that will only increase the counter if the variable new_code_valid is true. 

I usually don't recommend to use variables in a process, especially if you are a beginner, but this is one of the cases where using a variable is much easier and readable. 

There are three another flaws I think in your design. First the test condition that you put would still allow the exact same value in the array. You can fix this by changing the < in the first test to a <=. Then, in the elsif (counter < 8) condition, you assign an entry in the array, and then you read back the exact same entry, in the same clock cycle. This won't work, because when you read back pigsArray_signal(counter) you will still read the old value in the array. Use tempLocation instead. 

In addition, in the case where numbers are between 0 and 100, if you start filling your array with the values 0, 25, 50, 75, then no other value will be accepted and you will never fill up with 8 values.