Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16596 Discussions

VHDL getting Array elements with std_logic_vector

Altera_Forum
Honored Contributor II
7,957 Views

Hello,  

 

I'm having some trouble synthesizing my code, I'm running out of logic cells on my DE2 Altera board. 

 

I want to use the values from 4 std_logic_vectors(7 downto 0) to retrieve the elements of an array, CollisionReg which consists of 119 std_logic_vectors(159 downto 0). I'm doing this by converting the std_logic_vectors to integer using to_integer( unsigned( some std_logic_vector ). If I remove the integer conversions, I can compile fine. I've also tried storing the conversion into some integer variable of a fixed range 0 to 160, but it doesn't help. Is there a reason why integer conversion is taking so many logic cells? Is there a better way for me to do this? 

 

My code creates a matrix equal to the screen resolution and detects if a coordinate on the screen has been travelled before. Any help would be appreciated, thanks! 

 

entity CoordinateMatrix is port( XHead: in std_logic_vector(7 downto 0); YHead: in std_logic_vector(7 downto 0); XTail: in std_logic_vector(7 downto 0); YTail: in std_logic_vector(7 downto 0); LoadCM: in std_logic; initCM: in std_logic; CLK: in std_logic; didCollide: out std_logic); end; architecture behavioural of CoordinateMatrix is type CMArray is array(119 downto 0) of std_logic_vector(159 downto 0); signal CollisionReg: CMArray; begin collisionMatrix: process(CLK) begin if(rising_edge(clk)) then if(LoadCM = '1') then if(initCM = '1') then -------********* PROBLEM HERE didCollide <= CollisionReg(to_integer( unsigned( XHead)))(to_integer( unsigned( YHead))); --return old value CollisionReg(to_integer( unsigned( XHead)))(to_integer( unsigned( YHead))) <= '1'; --update to already been here CollisionReg(to_integer( unsigned( XTail)))(to_integer( unsigned( YTail))) <= '0'; --remove last pixel of snake -------------------------------- else for i in 119 downto 0 loop for y in 159 downto 0 loop if(i = 0 OR i = 119 OR y = 0 or y = 159) then --border always occupied CollisionReg(i)(y) <= '1'; else CollisionReg(i)(y) <= '0'; end if; end loop; end loop; end if; end if; end if; end process;
0 Kudos
20 Replies
Altera_Forum
Honored Contributor II
5,052 Views

 

--- Quote Start ---  

Hello,  

 

I'm having some trouble synthesizing my code, I'm running out of logic cells on my DE2 Altera board. 

 

I want to use the values from 4 std_logic_vectors(7 downto 0) to retrieve the elements of an array, CollisionReg which consists of 119 std_logic_vectors(159 downto 0). I'm doing this by converting the std_logic_vectors to integer using to_integer( unsigned( some std_logic_vector ). If I remove the integer conversions, I can compile fine. I've also tried storing the conversion into some integer variable of a fixed range 0 to 160, but it doesn't help. Is there a reason why integer conversion is taking so many logic cells? Is there a better way for me to do this? 

 

My code creates a matrix equal to the screen resolution and detects if a coordinate on the screen has been travelled before. Any help would be appreciated, thanks! 

 

entity CoordinateMatrix is port( XHead: in std_logic_vector(7 downto 0); YHead: in std_logic_vector(7 downto 0); XTail: in std_logic_vector(7 downto 0); YTail: in std_logic_vector(7 downto 0); LoadCM: in std_logic; initCM: in std_logic; CLK: in std_logic; didCollide: out std_logic); end; architecture behavioural of CoordinateMatrix is type CMArray is array(119 downto 0) of std_logic_vector(159 downto 0); signal CollisionReg: CMArray; begin collisionMatrix: process(CLK) begin if(rising_edge(clk)) then if(LoadCM = '1') then if(initCM = '1') then -------********* PROBLEM HERE didCollide <= CollisionReg(to_integer( unsigned( XHead)))(to_integer( unsigned( YHead))); --return old value CollisionReg(to_integer( unsigned( XHead)))(to_integer( unsigned( YHead))) <= '1'; --update to already been here CollisionReg(to_integer( unsigned( XTail)))(to_integer( unsigned( YTail))) <= '0'; --remove last pixel of snake -------------------------------- else for i in 119 downto 0 loop for y in 159 downto 0 loop if(i = 0 OR i = 119 OR y = 0 or y = 159) then --border always occupied CollisionReg(i)(y) <= '1'; else CollisionReg(i)(y) <= '0'; end if; end loop; end loop; end if; end if; end if; end process; 

--- Quote End ---  

 

 

you say if you remove integer conversion it is fine. I assume by that you mean you declare your inputs as integers, then you can just do that. 

But that does not make sense because this conversion is a compile time issue that is settled at compilation and the final logic should be same. 

 

I tried to compile your code and gave same resource whether I do conversions or not. As a side note it tells me that two of your inputs bit 7 are not driving anything.
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

It is nothing to do with integer conversion. It will be the collisionReg. That is a huge array, requiring over 100k registers.

0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

A reasonable way is to implement CollisonReg in internal RAM, changing the code to fulfill the requirements for RAM inference. The most important restriction is that you can't access more than two memory locations at a time if you utilize the dual-port feature. This means that the basic program algorithm has to be redesigned.

0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

Your array CollisionReg requires 120x160 registers i.e. 19,200. It also requires logic cells for its assignments 

Your DidCollide is one bit register but requires 2^16 tests and this is a candidate for moving to ram. I mean you can keep CollisionReg logic as it is then save to ram then use inputs as address to this ram.
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

 

--- Quote Start ---  

I mean you can keep CollisionReg logic as it is then save to ram then use inputs as address to this ram. 

--- Quote End ---  

 

The present logic won't infer RAM as is. The border initialization can be easily achieved as power-up content. Repeating it at runtime can be only done in a sequential process, one address per clock cycle. 

 

As another issue, the design expects to read old data on the same port (addressed by XHead/YHead). That's no possible in a single address cycle with Cyclone II.
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

Thanks for the responses. You guys are right. It is the registers. I lowered it to 70 by 90 and now I hit 28k / 32k of my logic cells. After 8 minutes of compiling my entire program together it is working fine 

 

 

--- Quote Start ---  

you say if you remove integer conversion it is fine. I assume by that you mean you declare your inputs as integers, then you can just do that. 

But that does not make sense because this conversion is a compile time issue that is settled at compilation and the final logic should be same. 

 

I tried to compile your code and gave same resource whether I do conversions or not. As a side note it tells me that two of your inputs bit 7 are not driving anything. 

--- Quote End ---  

 

 

I meant removing those conversion lines entirely. I thought it was the integer conversion for the heavy logic cell usage because in the else statement I'm already filling up the matrix with the for loops. So the registers would still be synthesized, that was a bad assumption. In software it would be true, but I'm guessing without the input signals accessing the array the compiler optimizes it and sees the registers aren't accessed and replaces it with some '0' or '1' signals? 

 

In class, we learn about FPGA logic blocks which are look-up tables consisting of a MUX and a flip-flop. Does each logic cell in the DE2 refer to the same thing, or is it a cluster of logic blocks? 8 Bit register = 8 logic cells? 

 

I'll see if I use the 160 x 120 matrix using RAM.
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

 

--- Quote Start ---  

Thanks for the responses. You guys are right. It is the registers. I lowered it to 70 by 90 and now I hit 28k / 32k of my logic cells. After 8 minutes of compiling my entire program together it is working fine 

--- Quote End ---  

 

 

I believe you may run into timing problems in hardware (but that depends on your speed). Your inputs XHead,YHead and others enter a massive logic cloud to decide didCollide. You must make sure you choose your set_input_delay correctly and then pass io timing on the path from these inputs to didCollide register. 

 

 

--- Quote Start ---  

 

In class, we learn about FPGA logic blocks which are look-up tables consisting of a MUX and a flip-flop. Does each logic cell in the DE2 refer to the same thing, or is it a cluster of logic blocks? 8 Bit register = 8 logic cells?  

--- Quote End ---  

 

 

A basic fpga fabric contains identical units each is a pair of one lut followed by one flipflip (called register usually). The muxes are intrinsic for its configuration and are not for user logic. The user logic is implemented in these luts(not gates). The user may use these pairs as such or only one member of pair with remaining orphan either usable or useless waste. 

 

 

--- Quote Start ---  

 

I'll see if I use the 160 x 120 matrix using RAM. 

--- Quote End ---  

 

If you run into timing problems then this will save you.
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

Thank for the great discussion. I am new to FPGA world 

 

My question is let say I have 160 X 120 array of 8 bit registers. This is large. How do figure out the limitations of the FPGA.
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

Second question x1222 has two for loops in the code. I am assuming that this will synthesize into to large circuit block that executes in one clock cycle. 

 

Am I correct. 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

 

--- Quote Start ---  

Thank for the great discussion. I am new to FPGA world 

My question is let say I have 160 X 120 array of 8 bit registers. This is large. How do figure out the limitations of the FPGA. 

--- Quote End ---  

 

 

You look at the FPGA specs and make educated guesses. Compile the design and see if you were correct. Usually you are more concerned with RAM or DSP usage as they are easier to estimate than LUT resources. 

 

 

--- Quote Start ---  

 

Second question x1222 has two for loops in the code. I am assuming that this will synthesize into to large circuit block that executes in one clock cycle. 

 

--- Quote End ---  

 

 

Yes, but these are all just parrallel registers as there is no memory between loop iterations.
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

Thank you for the prompt respond. Can you please help as to what and where I should be looking for this infomation in the specs? 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

The specs for your project are your own. As you get more experienced, it gets easier to understand how different elements work and how many resources they will use.

0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

You'll find the logic element, RAM and DSP count in the overview tables at the begin of each FPGA device handbook.

0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

FVM and Tricky 

 

Thank you for responding.  

 

I am currently using a Cyclone II EP2C70 device. The Handbook indicates that there are 68416 LE's.  

 

So based on the above discussion of 160 X 120 8 bit registers would require 160*120*8 = 153600 LE's. But since device has only 68416 LE's this is practically impossible.  

 

Am I correct.  

 

My understanding is that each LE has 1 bit flip flop (1 programmable register) 

 

Appreciate your feedback
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

yes, that would be a problem. But why do you need registers. Could you use a RAM instead?

0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

Tricky, 

Currently I am using the on chip RAM for other purpose. But ultimately I do intend to go to off chip RAM. I am still learning of accessing and managing off board RAM. 

Thank you for your help
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

Are you using all of them? Your "registers" would only use 40 of the M4ks available.  

What are you storing here? basically, you're not going to be able to store it in registers. And if you cant store it in M4K blocks, then your only choice is the external ram.
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

Tricky, 

 

Currently I have part of an image stored in M4K ram that I read and process. I understand this not a good design. I do intend to ultimately store the data on external RAM. I was hoping to read the complete image into a array and process the image. As I learn more about the characteristics of the FPGA I am better understanding my limitations.  

 

Can you please elaborate on the follow statement "your "registers" would only use 40 of the m4ks available" 

 

Thank you for the feedback.
0 Kudos
Altera_Forum
Honored Contributor II
5,052 Views

You could fit your image array, 160x120 x8bits into 40 M4Ks

0 Kudos
Altera_Forum
Honored Contributor II
4,004 Views

Yes I could, but currently I have the M4K filled by a 1000 x 16 x (8bit) data array.Knowing what I know I intend to complete the work that I have done, then work on learning more about external memory processing. This way I can store multiple images and then process them efficiently.

0 Kudos
Reply