opening an image, using it for simulation stimulus

W

wallge

I am working on a video processing system with FPGAs. I would like to
tell my simulator
through my VHDL testbench to open a raw image file (say pgm) and use
each pixel in the image as stimulous for the simulation.

Is it possible to read all the pixels in the image into an array
variable, and then send them into the simulation line by line?

Anyone have some pointers on how to get this done?

It would also be nice to write the processed results back to a pgm file
when the simulation was done in order to see how the FPGA
implementation of the algorithm performed. Maybe save the output from
the entity to another array variable, and then write the results to
another pgm file at the end...
 
K

KJ

wallge said:
I am working on a video processing system with FPGAs. I would like to
tell my simulator
through my VHDL testbench to open a raw image file (say pgm) and use
each pixel in the image as stimulous for the simulation.

Is it possible to read all the pixels in the image into an array
variable, and then send them into the simulation line by line? Yes.

Anyone have some pointers on how to get this done?
Start by writing two procedures: one to read an arbitrary file and
then write one back out. The ones that I wrote have the following
interface

procedure Read_File(File_Name: in STRING; Data: out ptr_arr_t_BYTE;
Length: out integer);

procedure Write_File(File_Name: in STRING; variable Data: in
ptr_arr_t_BYTE; Length: in natural; Write_Status: out BOOLEAN)

with the following types....

subtype t_BYTE is integer range 0 to 2**8 - 1;
type ptr_arr_t_BYTE is access arr_t_BYTE;

Then mosey on over to the following link...
http://www.vhdl.org/comp.lang.vhdl/FAQ1.html#binary_files

The last paragraph starts "To read raw binary files..." and is
basically what you will want to do. The one problem I found with the
approach listed there is that whereas Mr. Moore suggests using type
'character' I found that in the Windows world this won't work because
no matter what I did I would get bitten by the dang CR/LF translation.
Since a binary file may very well have a byte of 0xD or 0xA in it and
they have nothing to do with carriage returns or line feeds this is a
bit of a problem.....the solution I found is to use type 'bit_vector'
instead.

Once you get these two procedures working you can read an write any
file at all. Personally I've used this in my simulation testbench to
read and write TIFF image files which are binary.
It would also be nice to write the processed results back to a pgm file
when the simulation was done in order to see how the FPGA
implementation of the algorithm performed. Maybe save the output from
the entity to another array variable, and then write the results to
another pgm file at the end...
See above, you'll want to get both procedures working so that they can
each be used to test that the other is working correctly.

KJ
 
D

Dal

Here's a example of a function that reads data from a file. Makes use
of stdio_h and a few of my own procedures (get_word). I expect it
could be done more elagantly but I hope it gets you started.


impure function read_pnm (
fname : IN string
) return img_info_t is
variable img_open : boolean := false;
variable img_info : img_info_t;
variable line_str : string(1 to MAX_LINE_SIZE);
variable word : string(1 to MAX_WORD_SIZE);
variable IMG_FH : CFILE;
variable pnm_state : pnm_state_t := PNM_TYPE;
variable pix_count : integer := 0;
begin

if (not img_open) then
IMG_FH := fopen(fname, "r");
if (IMG_FH=0) then
report "Couldn't open image file: " & fname
severity error;
else
img_open := true;
end if;
end if;

line_loop : while (not feof(IMG_FH)) and (img_open) and (pnm_state /=
DONE) loop
-- Get line.
fgets(line_str,line_str'length,IMG_FH);
-- trim lf.
if (strchr(line_str, LF) > 0) then
line_str(strchr(line_str, LF)) := NUL;
end if;
-- trim comment.
trim_comment(line_str);
-- Skip blank lines
if (line_str(1) = NUL) then
next line_loop;
end if;

-- Extract data from the image file line
get_word(line_str,word);
while (word(1) /= NUL) loop
case pnm_state is
when PNM_TYPE =>
sscanf(word,"%s",img_info.pnm_type);
if (strcmp(img_info.pnm_type,"P2")=0) then
pnm_state := WIDTH;
else
pnm_state := DONE;
report "Image file type not supported"
severity failure;
end if;
when WIDTH =>
sscanf(word,"%d",img_info.width);
pnm_state := HEIGHT;
when HEIGHT =>
sscanf(word,"%d",img_info.height);
img_info.num_pix := img_info.width * img_info.height;
pnm_state := PIX_RANGE;
when PIX_RANGE =>
sscanf(word,"%d",img_info.pix_range);
pnm_state := PIX;
when PIX =>
sscanf(word,"%d",img_info.pix(pix_count));
pix_count := pix_count + 1;
if (pix_count = img_info.num_pix) then
pnm_state := DONE;
exit;
end if;
when others => null;
end case;
get_word(line_str,word);
end loop;

end loop;

if (img_open) then
fclose(IMG_FH);
img_open := false;
end if;

return img_info;

end function read_pnm;
 
M

Martin Thompson

wallge said:
I am working on a video processing system with FPGAs. I would like to
tell my simulator
through my VHDL testbench to open a raw image file (say pgm) and use
each pixel in the image as stimulous for the simulation.

Is it possible to read all the pixels in the image into an array
variable, and then send them into the simulation line by line?

I have a package which does this pixel by pixel from text-mode PGM
files (as these are easiest for VHDL to deal with).
Anyone have some pointers on how to get this done?
You just write a function to read the heaeder information from the
file and then read an integer at a time from the file and send it out.
It would also be nice to write the processed results back to a pgm file
when the simulation was done in order to see how the FPGA
implementation of the algorithm performed. Maybe save the output from
the entity to another array variable, and then write the results to
another pgm file at the end...

Again, you can write out a PGM header and then write out each pixel in
turn.

PGM fileformat is documented here:
http://netpbm.sourceforge.net/doc/pgm.html

I use format P2 as it is all ASCII.
Cheers,
Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top