[SOLVED] string confusions in VHDL

Status
Not open for further replies.

syedshan

Advanced Member level 1
Joined
Feb 27, 2012
Messages
463
Helped
27
Reputation
54
Reaction score
26
Trophy points
1,308
Location
Jeonju, South Korea
Visit site
Activity points
5,134
Hi all

Few days back I posted my message over file reading for VHDL testbenches.

At that time I was beginner in typing testbenches in VHDL. Hence tried to learn with implmentation.
Now I have some confusions(and big ones) with string data types...

At that time, TrickyDicky helped me understanding things related to string...and as we know that in order to declare string we should fill all the locations of the signal or variable, unlike C or C++. But I don't want this, I want the function like C/C++

i.e.
Code:
variable str : string (1 to 10) := "Hello!"; --This should be valid, although it is not,

Hence I looked and found something about "line" type which is like a pointer to STRING.
I have gathered info about it but cannot implement it to any purpose of mine although I tried...

How can we use LINE type as the pointer, as we use to deal in C, i.e. take part of pointer etc.

Code:
--C code: i am talking about concept only, not exactly remember the syntax in C, now
char *name := "edaboard";
char k = name[3]; --hence k= b;
char m[3] = *(name + 4);

VHDL code
Code:
signal str : string(1 to 8) := "edaboard";

process
variable my_line : line;
begin
wait for 10 ns;

	write(my_line, str & " forum"); -- my_line has "edaboard forum"
	writeline(output, my_line); --displays on screen

	report(my_line.all); --error
--I read about my_line.all will return string. then why not it prints

bests
shan
 

pointers in VHDL are different from C. You can only create a pointer with the "new" keyword, so you cannot create a pointer to a variable that already exists, like you can in C with &

so, inside the write function, you'll find something like the following

Code:
procedure write(variable li : inout line; constant s : string) is
begin
  DEALLOCATE(li);

  li = new string(s'range);
  li.all = s;
end write;

then in writeline you get

Code:
write(f, li.all & LF);  --add a line feed at the end of the text
DEALLOCATE(li);

I think the error you have is that you wrapped the my_line.all in (), making the compiler think report is a function - it is not. report is a standard part of the language. So try:

report myline.all severity note;

This should work fine.

Personally, I get annoyed with the extra stuff report puts in the modelsim console window, so I have an echo procedure:

Code:
procedure echo(s : string) is
begin
  write(std.textio.output, s);
end procedure echo;


echo("This is on one line" & LF);

- - - Updated - - -

As a note, write() exists for all file types implicitly, as does the DEALLOCATE() procedure for pointers (so you wont find them in any package).

To create a pointer, you create the type like this:

Code:
type integer_ptr_t is access integer;
variable int_ptr : integer_ptr_t;
variable num : integer;

.....

num := 7;

int_ptr := new integer(7);  --I think this is valid - initialise data at int_ptr.all to 7
int_ptr.all := 7;   --definiately valid

--I also think this is valid, but it copies the value, not the address
int_ptr := new integer(num);

Pointers in VHDL must be variables.
 

Thank you for your reply.

I tried to implement using the understanding that I have made but could not successfully implement. If you remember that when once I said in a thread that when I need to call the file using string and file_open etc. then I said I will use if-then-else, but this thing is actually getting very tedious in the code and hence I was trying someway of make only 1 string-type but could not succeed.
Please see the code below as a reference.


Code:
read_write : process(clk, rst) 
...
....
	variable str1 : string(1 to 9) :=  "data0.txt";	--for file number 0-9
	variable str2 : string(1 to 10) := "data10.txt";  --for file number 10-99
	variable str3 : string(1 to 11) := "data100.txt"; ----for file number 100-999
	variable str4 : string(1 to 12) := "data1000.txt";
	variable str5 : string(1 to 13) := "data10000.txt";
	variable str6 : string(1 to 14) := "data100000.txt";
        variable i : integer := 0;

...

begin

...
..

if(rd_file_process = '1') then
if(inline = NULL) then
	if(i<10) then
	file_open(infile, str1, read_mode);

	elsif(i>= 10 and i<100) then
	file_open(infile, str2, read_mode);

	elsif(i>= 100 and i<1000) then
	file_open(infile, str3, read_mode);

	elsif(i>=1000 and i<10000) then
	file_open(infile, str4, read_mode);

	elsif(i>=1000 and i<10000) then
	file_open(infile, str5, read_mode);

	end if;


...
...i := i +1;

end process read_write;

Is it possible to do this.
 

Hi

I just wrote it when I was half asleep and today morning when I check your message I just posted it

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_textio.all;
use IEEE.NUMERIC_STD.ALL;
library std;
use std.textio.all;

entity read_string is
end read_string;

architecture Behavioral of read_string is
signal dataread_s : integer:=0;
signal clk :std_logic := '0';
begin

process(clk)

variable str : line;
variable fileline : line;
variable i: integer := 0;
file filea	: text;
variable dataread : integer := 0;

begin

dataread_s	<= dataread;

if(rising_edge(clk)) then
		
if(fileline = NULL) then	
	write(str, "data"&integer'image(i)&".txt" );
	file_open(filea, str, read_mode);	
end if;	
	
if(not endfile(filea))	 then
	readline(filea, fileline);
	read(fileline, dataread);
else
	i:= i+1;
	fileline := NULL;
end if;

end if;
	
end process;

process		begin
wait for 5 ns;	clk <= '1';
wait for 5 ns;	clk <= '0';
end process;

end Behavioral;


 

A few issues:

file_open(filea, str, read_mode);

needs to be

file_open(filea, str.all, read_mode);

Also you shouldnt assign fileline to NULL, you will get a dangling pointer (basically allocated memory that no longer has a pointer). You should always use DEALLOCATE(fileline). But the readline procedure does this for you, so there is no need to do this. Instead of checking if fileline = null for opening the file, you should probably check endfile(filea).
 
Great....:grin:

works fine.
here's the code

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_textio.all;
use IEEE.NUMERIC_STD.ALL;
library std;
use std.textio.all;

entity read_string is
end read_string;

architecture Behavioral of read_string is
signal dataread_s : integer:=0;
signal clk :std_logic := '0';
signal	fileline_bit : bit := '0';
begin

process(clk)

variable str : line;
variable fileline : line := NULL;
variable i: integer := 0;
file filea	: text;
variable dataread : integer := 0;

begin

dataread_s	<= dataread;

if(rising_edge(clk)) then
		
if(fileline_bit = '0') then	
	deallocate(str);
	write(str, "data"&integer'image(i)&".txt" );
	file_open(filea, str.all, read_mode);	
	fileline_bit <= '1';
end if;	
	
if(not endfile(filea))	 then
	readline(filea, fileline);
	read(fileline, dataread);
else
	i:= i+1;	
	fileline_bit <= '0';
	file_close(filea);
end if;

end if;	
	assert i/=13	report "Stopping !"	severity failure;
end process;

process		begin
wait for 5 ns;	clk <= '1';
wait for 5 ns;	clk <= '0';
end process;

end Behavioral;
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…