Altera_Forum
Honored Contributor
13 years agoFirst in Last out buffer consuming too much resources
Hi all,
I'm trying to implement a first in last out buffer, that has the soul purpose of flipping image data horizontally. The image comes in as a stream of pixels in the order (1,1) , (2,1) , (3,1) ... (765,1) , (1,2) , (2,2) , (3,2) ... (765,2) etc (where the width of the image is 765) Each pixel is put through a threshold and represented by a color label, an x coordinate and a y coordinate. I've implemented a block that instances 3 arrays of length 765 one for the color label (8 bits per label) one for the x coordinate (10 bits per coordinate) one for the y coordinate (10 bits per coordinate) When the arrays are filled (a full line has come in) the direction of the arrays are reversed an the data comes out in effect flipping the row of data and delaying the output of the image by a single row. The block works and I have verified this by modifying the block to flip the RGB values rather than the color label, x and y coordinate and the output image is a horizontally flipped image. However, before this block is used the total logic elements used is around 9% and after it is around 90% (not to mention the compile time is unbearable). I have a feeling this is due to the following info I get during the compilation process Info (276014): Found 3 instances of uninferred RAM logic Info (276007): RAM logic "ImgModelling:inst32|FlipBuffer:inst5|CL_Stack~19" is uninferred due to asynchronous read logic Info (276007): RAM logic "ImgModelling:inst32|FlipBuffer:inst5|X_Stack~21" is uninferred due to asynchronous read logic Info (276007): RAM logic "ImgModelling:inst32|FlipBuffer:inst5|Y_Stack~21" is uninferred due to asynchronous read logic I'm not to sure where I have asynchronous reading occuring (bear in mind I'm very new to VHDL and FPGA's) but the amount of resources being used by this block seems to high and I would like to fix it if possible Can anyone confirm this is why the block is using that many logic elements or help me find out why. Also if anyone has a better idea of how to approach the flipping it would be greatly appreciated. I have provided my code for the block below. Thanks, Mat. CL is the color label FVAL is true when the image frame is valid DVAL is true for a valid pixel so when DVAL = '1' and FVAL = '1' the data is a valid pixel and DVAL = '0' and FVAL = '0' represents the end of a frame.library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity FlipBuffer is
generic(
LABEL_WIDTH : integer := 8;
COORD_WIDTH : integer := 10;
BUFFER_SIZE : integer := 765 -- Screen width
);
port(
-- Clock Signal
CLK : in std_logic;
-- Input Signals
CL_IN : in unsigned(LABEL_WIDTH-1 downto 0);
X_IN : in unsigned(COORD_WIDTH-1 downto 0);
Y_IN : in unsigned(COORD_WIDTH-1 downto 0);
DVAL_IN : in std_logic := '0';
FVAL_IN : in std_logic := '0';
-- Output Signals
CL_OUT : out unsigned(LABEL_WIDTH-1 downto 0) := to_unsigned(0,LABEL_WIDTH);
X_OUT : out unsigned(COORD_WIDTH-1 downto 0) := to_unsigned(0,COORD_WIDTH);
Y_OUT : out unsigned(COORD_WIDTH-1 downto 0) := to_unsigned(0,COORD_WIDTH);
DVAL_OUT : out std_logic := '0';
FVAL_OUT : out std_logic := '0'
);
end FlipBuffer;
architecture rt1 of FlipBuffer is
-- output registers
signal cl_reg : unsigned(LABEL_WIDTH-1 downto 0);
signal x_reg : unsigned(COORD_WIDTH-1 downto 0);
signal y_reg : unsigned(COORD_WIDTH-1 downto 0);
signal dval_reg : std_logic := '0';
signal fval_reg : std_logic := '0';
-- Buffer
type FILO_CL_Stack is array(0 to BUFFER_SIZE-1) of unsigned(LABEL_WIDTH-1 downto 0);
type FILO_COORD_Stack is array(0 to BUFFER_SIZE-1) of unsigned(COORD_WIDTH-1 downto 0);
signal CL_Stack : FILO_CL_Stack;
signal X_Stack : FILO_COORD_Stack;
signal Y_Stack : FILO_COORD_Stack;
begin
process (CLK)
variable read : integer;
variable write : integer;
variable reverse : std_logic;
variable read_count : integer;
variable write_count : integer;
begin
if (rising_edge(CLK)) then
if (DVAL_IN = '0' and FVAL_IN = '0') then
-- reset, this will ignore the final line of the frame to ensure
-- initial conditions are set when the frame starts. However, the
-- final line is black and therefore makes no difference.
reverse := '0';
read := BUFFER_SIZE-1;
write := 0;
read_count := 0;
write_count := 0;
cl_reg <= to_unsigned(0,LABEL_WIDTH);
x_reg <= to_unsigned(0,COORD_WIDTH);
y_reg <= to_unsigned(0,COORD_WIDTH);
dval_reg <= '0';
fval_reg <= '0';
elsif (DVAL_IN = '1' and FVAL_IN = '1' and read_count > 0) then
-- Reading and Writing state
-- Read first so data is not overwritten
cl_reg <= CL_Stack(read);
x_reg <= X_Stack(read);
y_reg <= Y_Stack(read);
dval_reg <= '1';
fval_reg <= '1';
-- Write data
CL_Stack(write) <= CL_IN;
X_Stack(write) <= X_IN;
Y_Stack(write) <= Y_IN;
-- Update counts and addresses
if (write_count + 1 = BUFFER_SIZE) then
-- Row writen, reverse buffer and start reading
reverse := not reverse;
write := write;
read := write;
write_count := 0;
read_count := BUFFER_SIZE;
else
-- Still writing row
reverse := reverse;
write_count := write_count + 1;
read_count := read_count + 1;
if (reverse = '0') then
write := write + 1;
read := read + 1;
else
write := write - 1;
read := read - 1;
end if;
end if;
elsif (DVAL_IN = '1' and FVAL_IN = '1' and read_count <= 0) then
-- Writing, NOT Reading state
-- NOT Reading
cl_reg <= to_unsigned(0,LABEL_WIDTH);
x_reg <= to_unsigned(0,COORD_WIDTH);
y_reg <= to_unsigned(0,COORD_WIDTH);
dval_reg <= '0';
fval_reg <= '1';
-- Write data
CL_Stack(write) <= CL_IN;
X_Stack(write) <= X_IN;
Y_Stack(write) <= Y_IN;
-- Update counts and addresses
if (write_count + 1 = BUFFER_SIZE) then
-- Row writen, reverse buffer and start reading
reverse := not reverse;
write := write;
read := write;
write_count := 0;
read_count := BUFFER_SIZE;
else
-- Still writing row
reverse := reverse;
write_count := write_count + 1;
if (reverse = '0') then
write := write + 1;
else
write := write - 1;
end if;
read_count := 0;
read := 0;
end if;
elsif (DVAL_IN = '0' and FVAL_IN = '0' and read_count > 0) then
-- Reading, NOT Writing state
-- NOT Writing
reverse := reverse;
write := write;
write_count := write_count;
-- Read data
cl_reg <= CL_Stack(read);
x_reg <= X_Stack(read);
y_reg <= Y_Stack(read);
dval_reg <= '1';
fval_reg <= '1';
-- Update counts and addresses
read_count := read_count + 1;
if (reverse = '0') then
read := read + 1;
else
read := read - 1;
end if;
else
-- DO NOTHING, maintain state
reverse := reverse;
read_count := read_count;
write_count := write_count;
read := read;
write := write;
cl_reg <= to_unsigned(0,LABEL_WIDTH);
x_reg <= to_unsigned(0,COORD_WIDTH);
y_reg <= to_unsigned(0,COORD_WIDTH);
dval_reg <= '0';
fval_reg <= '1';
end if;
end if;
end process;
CL_OUT <= cl_reg;
X_OUT <= x_reg;
Y_OUT <= y_reg;
DVAL_OUT <= dval_reg;
FVAL_OUT <= fval_reg;
end rt1;