working on a VHDL testbench for image processing
I want to instantiate the following component several times:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
entity gen_ppm is
port( Clk : in std_logic;
Data : in std_logic_vector(23 downto 0);
DataEnable : in std_logic
);
end gen_ppm;
architecture behavior of gen_ppm is
signal frames_cnt : integer range 0 to 8191;
begin
process(Clk)
file F: TEXT;
variable L: LINE;
variable FNAME : LINE;
variable P3 : string(1 TO 2) := "P3";
variable homepage : string(1 TO 32):= "# http://www.richardrosenman.com";
variable resu_x : string(1 TO 5) := "1920 ";
variable resu_y : string(1 TO 5) := "1200 ";
variable space : string(1 TO 1) := " ";
begin
if falling_edge(Clk) then
...
write(FNAME, string'("./images/images_read/"));
write(FNAME, string'("images_read_"));
write(FNAME, frames_cnt);
write(FNAME, string'(".ppm"));
file_open(F, FNAME.all, write_mode);
write(L, P3);
writeline(F, L);
write(L, homepage);
writeline(F, L);
write(L, resu_x);
write(L, resu_y);
writeline(F, L);
write(L, 255);
...
end if;
end process;
end behavior;
Now for every instance of that component I need to have a different
path,
and a different resolution (resu_x, resu_y)
for example:
"./images/images_read/" with resolution 1920x1200
"./images/images_read_direct/" with resolution 1280x1024
...
How can I pass different strings of different lengths as generics ?
Thank you for your help.
Rgds
Andre
How can I write these generic strings to the variable
FNAME ?
(instead of using
write(FNAME, string'("./images/images_read/"));
write(FNAME, string'("images_read_"));
)
Rgds
Andre
> How can I pass different strings of different lengths
Consider using an access string type.
Related example below.
-- Mike Treseler
____________________________________________________
procedure verify is
type string_p is access string;
variable string_v : string_p;
begin
string_v := new string'(integer'image(to_integer(expect_v)));
report "___Step " & integer'image(step_v);
match_v := expect_v = unsigned(readData_s);
pass_v := pass_v and match_v; -- all ok so far?
step_v := step_v + 1;
ck : if match_v then
boring : if verbose_g then
report "____________ saw "
& string_v.all & " as expected";
end if boring;
else
report "_____________Expected byte is " & string_v.all;
report "_____________Actual bus data is "
& integer'image(to_integer(unsigned(readData_s)))
severity error;
report "___________________________WIRE STATE IS "
& wire_t'image(wire_g);
die;
end if ck;
end procedure verify;
thank you for your suggestion.
As I see signals or generics cannot be declared of access type, is
that right ?
I would like to define something similar like
entity gen_ppm is
generic ( path_to_open : string ....;
resu_x, resu_y : string ...);
port( Clk : in std_logic;
Data : in std_logic_vector(23 downto 0);
DataEnable : in std_logic
);
end gen_ppm;
I do not see how to achieve that by using string access type.
Andre
> thank you for your suggestion.
> As I see signals or generics cannot be declared of access type, is
> that right ?
The generic is a string:
generic( x : string := "abc");
The function or procedure that uses the string
needs the access type to handle the variable
length. Or, keep it simple and use a fixed length string.
-- Mike Treseler
> How can I pass different strings of different lengths as generics ?
It's much easier than you think.
The type STRING in VHDL is just another kind of unconstrained array
(like STD_LOGIC_VECTOR) and so you can create a generic of type
STRING and associate a string of any length with that generic.
Having done so, you can use the normal array attributes such as
'LENGTH to find out about your generic's properties. So...
use std.textio.all;
entity file_handler is
generic (width, height: NATURAL;
filename: STRING);
port (....);
end;
architecture A of file_handler is
begin
process
variable L: LINE;
begin
write(L, string'("Filename generic is "));
write(L, filename); -- answer to your 2nd question
writeline(output, L);
write(L, string'("That string has "));
write(L, filename'LENGTH);
write(L, string'(" characters numbered from "));
write(L, filename'LEFT);
write(L, string'(" to ");
write(L, filename'RIGHT);
writeline(output, L);
wait;
end process;
end;
And when you instantiate this entity, you can provide any
string you care as the generic:
my_instance: entity work.file_handler
generic map(width=>100, height=>50,
filename=>"Any filename you care")
port map (....);
You'll find that the string's array range is (1 to N). Strings
are "array (positive range <>) of character", so the lowest
possible subscript is 1 - NOT zero!!!!
Hope this helps. Apologies for posting from the ghastly Google
groups account - I can't reach my news-server from here.
--
Jonathan Bromley
great explanations !
Thank you.
Rgds
Andre