Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

Array make's logic or uses BRAM?

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;

6 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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 :)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

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