Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Print screen statements in VHDL, need code explanation...!!

Status
Not open for further replies.

xtcx

Advanced Member level 1
Joined
Dec 22, 2007
Messages
493
Helped
65
Reputation
130
Reaction score
58
Trophy points
1,308
Location
Bangalore, India
Activity points
5,003
hi, I have used print statement many times, but never understood how it works or what the code actually means. Can somebody explain a little in detail?


This code is provided in one of the Xilinx testbench file

Code:
package rapidio_lib is
  --=======================================
  -- Printl
  -- OPERATION: print a string to the display
  --=======================================
   procedure printf(
      S          : string; 
      PRINT_TIME : boolean := FALSE
      ) is
      
   variable screen : line;
   begin

      if (PRINT_TIME) then
         write(screen, NOW);      
      end if;

      write(screen, S);

      writeline(output, screen);
   end procedure;

I can see two functions write and writeline (for which I could not see the declaration, may be is it in textio lib?)
Anyway what is the difference and what is the data type "line" mean here an why is print time set to false

Your help is appreciated!....
Thanks...
 

You are right. write and writeline are taken from textio lib.
By default PRINT_TIME is set to false because you dont want to print current time always .
You can overwrite it to true if you want to print the time!
 
  • Like
Reactions: xtcx

    xtcx

    Points: 2
    Helpful Answer Positive Rating
write (in the context of line types) is a function that allows you to append stuff to a line type. A line is just a pointer to a string. The way write actually works is that it creates a new pointer to a string that is long enough to hold the old data and the new data. Write is defined for all types declared in std.standard (integer, real, bit). For std_logic types you need to use std_logic_textio.

But in VHDL 2008, the function to_string are defined for ALL types in the IEEE packages (and to_hstring, to_bstring and to_ostring for standard array types like std_logic_vector, unsigned etc) which is really nice, so no need to include std_logic_textio anymore.

writeline allows you to write a line type to a text file, and it appends a line feed (LF) character on the end of the line.

The write/read procedure is also defined for files.You can write or read any standard type directly to a file, but its use is simulator dependent, so I wouldnt rely on it. (with this you can actually read and write data files in modelsim via the character type - this allows full file byte access - useful for things like bitmaps).

---------- Post added at 10:38 ---------- Previous post was at 10:35 ----------

Also forgot to add : OUTPUT is a file defined in Textio, which simulators are supposed to use for their console output.

You can also write to output like this (no writeline needed):

write(std.textio_OUTPUT, "Hello World!" & LF);

It uses the write to file option I talked about above.
 
  • Like
Reactions: xtcx

    xtcx

    Points: 2
    Helpful Answer Positive Rating
Thanks,
Also this link provides even more information....

**broken link removed**
 

It doesnt quite provide all the information.

line HAS to be a variable because it is an access type (access types - ie. pointers- must be variables). The write procedure takes the line as an inout, because it deallocats the old line and creates a new one. Once you understand how pointers work, you can use line types elsewhere for other jobs.
 
  • Like
Reactions: xtcx

    xtcx

    Points: 2
    Helpful Answer Positive Rating
write (in the context of line types) is a function that allows you to append stuff to a line type. A line is just a pointer to a string. The way write actually works is that it creates a new pointer to a string that is long enough to hold the old data and the new data. Write is defined for all types declared in std.standard (integer, real, bit). For std_logic types you need to use std_logic_textio.

But in VHDL 2008, the function to_string are defined for ALL types in the IEEE packages (and to_hstring, to_bstring and to_ostring for standard array types like std_logic_vector, unsigned etc) which is really nice, so no need to include std_logic_textio anymore.

writeline allows you to write a line type to a text file, and it appends a line feed (LF) character on the end of the line.

The write/read procedure is also defined for files.You can write or read any standard type directly to a file, but its use is simulator dependent, so I wouldnt rely on it. (with this you can actually read and write data files in modelsim via the character type - this allows full file byte access - useful for things like bitmaps).

---------- Post added at 10:38 ---------- Previous post was at 10:35 ----------

Also forgot to add : OUTPUT is a file defined in Textio, which simulators are supposed to use for their console output.

You can also write to output like this (no writeline needed):

write(std.textio_OUTPUT, "Hello World!" & LF);

It uses the write to file option I talked about above.

Thanks, good explanation.
But i have some doubts.
I'm using this library call
Code:
library std;
use std.textio.all;

My xilinx tool shows supports for VHDL 200x(is it 2008)???

In such case, what exactly the library should I use?.

Also, I asked this for printing line\text in monitor while sim. But as you said, can I simply add output syntax to write a file just this way?....

---------- Post added at 14:26 ---------- Previous post was at 14:18 ----------

It doesnt quite provide all the information.

line HAS to be a variable because it is an access type (access types - ie. pointers- must be variables). The write procedure takes the line as an inout, because it deallocats the old line and creates a new one. Once you understand how pointers work, you can use line types elsewhere for other jobs.

Got it, Do you mean to say that this line argument which works like a pointers in C?...
So this write statement compiles similar to C compiler, is it so?...
What I understood from your words is
Line points to display location where the char will be displayed in monitor of simulation window. So any char\string pointed to line will be displayed as a result ?, right?...

Thanks
Also, what are the other jobs\places line types can be used elsewhere?...
 

For xilinx, when it says 200x, it probably means 2002. Full 2008 support is a little lacking atm.
You can download the 2008 extensions here:
**broken link removed** (its not just the fixed point stuff - it also has all the to_string stuff)

They are similar to pointers in any langauge - BUT in VHDL you can only create pointers via the "new" keyword:

variable myline : line;

myline := new string(1 to 100);

or you can initialise the data in the pointer:

myline := new string'("Hello World!"); --you need the ' when doing this

This works similar to malloc. BUT There is no create pointer function like & in C, which can be a limitation.
But with pointers, you can do stuff like linked lists (great for modelling big fifos) or sparse memory models (when your DDR chip is 2GB, but you only want to use 128 Mbs).

As for line types elsewhere, just any time you want to do string processing (like a string tokensier):


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
type string_tokeniser_t is protected body
  variable tok_str          : line;
  variable next_tok_idx     : natural;
  
  procedure set_string( s : string) is
  begin
    --clean up existing instance
    DEALLOCATE(tok_str);
    
    --Open a new memory area and put the data into it
    tok_str                 := new string(s'range);
    tok_str.all             := s;
    next_tok_idx            := tok_str.all'low; --starting point of the string
  end procedure;
  
  procedure restart is
  begin
    next_tok_idx            := tok_str.all'low;
  end procedure restart;
  
  procedure cleanup is
  begin
    DEALLOCATE(tok_str);
  end procedure cleanup;
  
  
  impure function get_next_token(delim : character) return string is
    variable temp           : natural;
  begin
    if tok_str = null then
      report "string_tokeniser-get_next_token: Null pointer found - returning null string"
        severity WARNING;
      
      return "";
    
    elsif next_tok_idx > tok_str.all'high then --Previously ended a string
      --no need to report. String exists, but all tokens returned
      return "";
    
    else
      --User wants to search the previous specified string
      search_loop_old : for i in next_tok_idx to tok_str.all'high loop
        
        if tok_str(i) = delim then --found delimiter match
          
          temp                := next_tok_idx;
          next_tok_idx        := i + 1; --this is where the next search should start
          
          return tok_str.all(temp to i-1);
          
        end if;
      end loop search_loop_old;
      
      --run off the end of the string, so return from the last know start index to the end 
      temp                := next_tok_idx;         
      next_tok_idx        := tok_str.all'high + 1; --This is off the end so subsequent
                                                   --calls return null
                                                   
      return tok_str.all(temp to tok_str.all'high);
    end if; 
  end function get_next_token;
 
  
  impure function count_tokens(delim : character) return natural is
    variable temp           : natural := 0;
  begin
    if tok_str = null then
      report "string_tokeniser-count_tokens: Null pointer detected, no string available to count."
        severity WARNING;
      temp                  := 0;
    
    else
      --count the number of tokens left in the current stored string
      for i in next_tok_idx to tok_str.all'high loop
        if    tok_str.all(i) = delim
           or i              = tok_str.all'high    --the end of the string gives 
                                                   --us the end of another token 
        then
          temp                := temp + 1;
        end if;
      end loop;
    end if;
    
    return temp;
  end function count_tokens;
 
end protected body string_tokeniser_t;

 

    V

    Points: 2
    Helpful Answer Positive Rating
Thanks, I could understand the line data type, but however I could only partially understand your code. I could not find "Deallocate" function defined anywhere. I believe it is no key function word in VHDL.

Also I don't understand this term "tok_str.all'high".
How can you access the string with ".all" and "'high"extension?.
 

Deallocate is an implicitly defined procedure for all access types. its like the "free" function in C
.all deferences a pointer - equivolent to * in C

so in the case of a line,
myline.all is a string type.

hence
myline.all'high gives the high attribute for the string stored in myline.

like in C, if myline is a pointer, you dont have to dereference it to get individual array elements:

variable char : character;

char := myline(n);

identical to:

char := myline.all(n);
 
  • Like
Reactions: xtcx

    xtcx

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top