Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20687 Discussions

Array make's logic or uses BRAM?

Altera_Forum
Honored Contributor II
1,267 Views

Hi I'm working on a project with a cyclone III ( EP3C10F256C8). 

In the project en monitoring with a camera. I need to write a code who finds the position of the brightest pixel in the image.  

 

I made an array for the full lengt (1280 columns) of 8 bit.  

 

When I recieve the first line of the camera, i compare the value of the corresponding column with a value of a register who memory's the maximum value (brightest pixel). If it is a higher (brighter) value , then i place the number line (position) in a position_register. If the camera has sended the image is read out the position_register.  

 

The problem si that the compiler doesn't use BRAM and the logic generated for the process is to big for the device.  

 

How can i force it to use BRAM ? (Working in Quartus II v8.0) 

 

The code i wrote:  

 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity VERTICAL_COUNTER is generic ( Write_adress : std_logic_vector (22 downto 0) := "000" & x"00000" ); port ( RESETn : in std_logic; CLK100MHz : in std_logic; CAM_DATA_VALID : in std_logic := '0'; CAM_DATA : in std_logic_vector (7 downto 0) ; CAM_FRAME_VALID : in std_logic := '0'; CAM_LINE_VALID : in std_logic := '0'; COUNTER_ABLE : in std_logic := '0'; DATA_VALID : out std_logic := '0'; DATA_OUT : out std_logic_vector (7 downto 0) ; FRAME_WRITE_ADR : out std_logic_vector (22 downto 0); WRITE_ABLE : out std_logic := '0' ); end entity; architecture rtl of VERTICAL_COUNTER is signal buff_CAM_LINE_VALID : std_logic_vector (1 downto 0) := (others => '0'); signal send_data : std_logic := '0'; signal line_counter : integer range 0 to 255 := 0; signal column_counter : integer range 0 to 1279 := 0; signal max_column : integer range 0 to 1279 := 0; type array_type is array (0 to 1279) of unsigned (7 downto 0); signal array_position , array_amplitude : array_type; begin FRAME_WRITE_ADR <= Write_adress; prog_adr : process (CLK100MHz) begin if rising_edge (CLK100MHz) then buff_CAM_LINE_VALID <= buff_CAM_LINE_VALID(0) & CAM_LINE_VALID; if CAM_FRAME_VALID = '1' and COUNTER_ABLE = '1' then send_data <= '1'; if CAM_LINE_VALID = '1' then if CAM_DATA_VALID = '1' then column_counter <= column_counter +1 ; if unsigned (CAM_DATA) >= array_amplitude(column_counter) then array_position(column_counter) <= to_unsigned (line_counter, 8); array_amplitude(column_counter) <= unsigned (CAM_DATA) ; end if; end if; end if; if buff_CAM_LINE_VALID = "10" then line_counter <= line_counter + 1; if column_counter > max_column then max_column <= column_counter; else max_column <= max_column; end if; column_counter <= 0; end if; else -- cam frame valid = 0 if send_data = '1' then DATA_VALID <= '0'; WRITE_ABLE <= '1'; if column_counter >= max_column then send_data <= '0'; column_counter <= 0; max_column <= 0; else DATA_VALID <= '1'; column_counter <= column_counter +1 ; DATA_OUT <= std_logic_vector (array_position(column_counter)); end if; else WRITE_ABLE <= '0'; column_counter <= 0; line_counter <= 0; array_amplitude <= (OTHERS => (OTHERS => '0')); array_position <= (OTHERS => (OTHERS => '0')); end if; end if; end if; end process; end rtl;
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
414 Views

If more explanation is needed ,plz say! 

Thx anyhow.
0 Kudos
Altera_Forum
Honored Contributor II
414 Views

No Reply's are coming so let me explain it in an other way. 

 

A Camera sends its pixel from left to right and top to bottom. (Like you read a text).  

 

I need to find the brightest pixel in a column (Vertically). Therefor i need to memorize the maximum value for each column.  

 

I use 2 array's : Position array and Amplitude_array  

 

- Amplitude array witch holds the maximum value of the pixel for each column 

- Position array witch holds the position of the pixel for each column 

 

At start both array's are filled with '0'  

 

First line is read ->  

 

I compare the value of the first image_pixel with the value  

that is stored in the amplitude_array.  

If the read value is more than the stored one:  

Than overwrite the stored value with the new one in the amplitude_array. Also store the linenumber in the position_array.  

If not -> Do nothing to the array's 

I need to do this for 1280 columns (image size is 200x1280) 

The result: An array with the position of 1280 pixels (brightest) 

 

I wrote some code but the problem is that it generates logic to find the brightest pixel 1280 times. I need code that that generates logic, to find the brightest pixel and use it 1280 times in stead of making it.  

 

 

EXPLANATION OF MY CODE:  

signal send_data : std_logic := '0'; signal line_counter : integer range 0 to 255 := 0; signal column_counter : integer range 0 to 1279 := 0; signal max_column : integer range 0 to 1279 := 0; type array_type is array (0 to 1279) of std_logic_vector (7 downto 0); signal array_position , array_amplitude : array_type; 

Declaration Array 

 

if CAM_DATA_VALID = '1' then column_counter <= column_counter +1 ; if (CAM_DATA >= array_amplitude(column_counter)) then array_position(column_counter) <= std_logic_vector (to_unsigned (line_counter, 8)); array_amplitude(column_counter) <= CAM_DATA; end if; end if;  

Need to wait untill DATA_VALID for camera. 

If valid add index (column) with one. 

T'check if New pixel is brighter than stored one  

If so -> Store position (line number) to array_position 

-> Store new pixel in array_amplitude 

 

 

For each new line there is a counter that increases line_number. 

 

 

 

 

Why doe's this code generates so dam'n much logic ? 

 

Plz Help
0 Kudos
Altera_Forum
Honored Contributor II
414 Views

The problem is that you reset the memory. No internal ram can be reset, so it cannot infer a RAM from the behaviour you have specified. So it uses logic instead (and probably takes a long time to compile) 

 

Remove the reset code (the bit that sets all locations to 0) and try again.
0 Kudos
Altera_Forum
Honored Contributor II
414 Views

Indeed, just found it by trying and came here to tell about my results and saw your post.  

 

Do you have a ID how to clear it ? Or do i need to do it sequentially (one by one)?  

 

Compilation time reduced with 28 min :)
0 Kudos
Altera_Forum
Honored Contributor II
414 Views

If you really have to clear the memory, you have to do it one by one.

0 Kudos
Altera_Forum
Honored Contributor II
414 Views

K, Thx for the help!

0 Kudos
Reply