1
\$\begingroup\$

I am trying to read data from a text file in VHDL which includes two vectors and single character. While reading, white spaces are not detected for the numbers but are detected for the character. Why is that?

VHDL CODE:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_TEXTIO.ALL;
library STD;
use STD.TEXTIO.ALL;
entity sample_tb is
end sample_tb;
architecture Behavioral of sample_tb is
 
begin
 stim : process 
 file F_in : TEXT open READ_MODE is "input_sample.txt";
 variable current_read_line : line;
 
 variable input_number1 : std_logic_vector(1 downto 0);
 variable input_number2 : std_logic_vector(1 downto 0);
 variable input_field : string(1 to 1);
 
 variable current_write_line : line;
 begin 
 while( not endfile(F_in)) loop
 readline(F_in, current_read_line);
 read(current_read_line, input_number1);
 read(current_read_line, input_number2);
 read(current_read_line, input_field);
 
 wait for 100 ns;
 
 write(current_write_line, input_number1);
 write(current_write_line, input_number2);
 write(current_write_line, input_field);
 writeline(OUTPUT, current_write_line);
 end loop;
 
 wait;
 end process;
 
end Behavioral;

input_sample.txt:

00 00 A
00 00 B
00 00 C
00 00 D
00 00 E

Output when I declare variable input_field : string(1 to 1); (keep in mind that there is an extra space after 0000)

0000 
0000 
0000 
0000 
0000 

Output when I declare variable input_field : string(1 to 2);

0000 A
0000 B
0000 C
0000 D
0000 E

I have understood that the code detects the white space before the letters and considers it to be a string. But, why doesn't that happen when reading the two std_logic_vectors? Why is the white space between 00 and 00 ignored?

Also, is the way to ensure that the code disregards the white space before the letters as well?

Jim Lewis
1,2506 silver badges12 bronze badges
asked May 20, 2024 at 11:08
\$\endgroup\$
1
  • \$\begingroup\$ Why and how do you expect a std_logic_vector to store the white space? Coming from a software background, it is clear to me that read() ignores leading white space and stops at the first non-std_logic character. \$\endgroup\$ Commented May 21, 2024 at 5:35

2 Answers 2

3
\$\begingroup\$

Space characters are not a legal std_logic character, hence, reads for std_logic_vector throw away leading white space and fail if there is a non-white space character that is not a std_logic value. In fact, all reads except for type string behave this way. The string read OTOH, returns the next characters in the line and expects to read exactly the number of characters in the argument - if there are not at least argument length characters in the line, then it is an error.

Sread is designed to read tokens - white space separated words - hence, it only keeps the non-space characters in a similar fashion to what read does for std_logic_vector. Sread reads up to the number of characters in the argument string and also returns the length. Sread returns 0 as the length if no characters were available to read. I should also note that Sread is VHDL-2008 so make sure to turn on the appropriate switch in your simulator.

Hence, the following code segment will strip out all leading white space.

 variable str_len : integer ; 
 . . . 
 readline(F_in, current_read_line);
 read(current_read_line, input_number1);
 read(current_read_line, input_number2);
 sread(current_read_line, input_field, str_len);

If you want the white space when writing, simply add it back:

 write(current_write_line, to_string(input_number1) & ' ' &
 to_string(input_number2) & ' ' & input_field);
 writeline(OUTPUT, current_write_line);
answered May 20, 2024 at 20:20
\$\endgroup\$
2
  • \$\begingroup\$ It's meant for the OP \$\endgroup\$ Commented May 21, 2024 at 2:03
  • \$\begingroup\$ @user16145658 Anyone can make careless editing mistakes. I certainly appreciate anything that is on-point and corrects something I may have missed. \$\endgroup\$ Commented May 21, 2024 at 22:15
1
\$\begingroup\$

This will reproduce input_sample.txt on OUTPUT by writing input_number1, input_number2 and input_field. Note the two writes of a space (" ") interposed between the values written.

This is a specific solution for the code presented in the question:

 stim : process 
 file F_in : TEXT open READ_MODE is "input_sample.txt";
 variable current_read_line : line;
 
 variable input_number1 : std_logic_vector(1 downto 0);
 variable input_number2 : std_logic_vector(1 downto 0);
 variable input_field : string(1 to 1);
 
 variable current_write_line : line;
 variable substr : line; -- ADDED
 begin 
 while( not endfile(F_in)) loop
 readline(F_in, current_read_line);
 read(current_read_line, input_number1);
 read(current_read_line, input_number2);
 for i in current_read_line'range loop -- ADDED FOR LOOP
 if current_read_line(i) /= ' ' then -- First non space
 write(substr, current_read_line(i to current_read_line'high));
 deallocate (current_read_line);
 write(current_read_line, substr.all); 
 deallocate (substr);
 exit; -- after first non space element
 end if;
 end loop;
 
 read(current_read_line, input_field);
 
 wait for 100 ns;
 
 write(current_write_line, input_number1);
 write(current_write_line, string'(" ")); -- SPACE
 write(current_write_line, input_number2);
 write(current_write_line, string'(" ")); -- SPACE
 write(current_write_line, input_field);
 writeline(OUTPUT, current_write_line);
 end loop;
 
 wait;
 end process;

A read for a std_logic_vector will eat white space up until the first character belonging to the element base type std_ulogic value and read until the first non element value.

After the second std_logic_vector read there's a for loop that eats leading spaces. This is analogous to what a read for a non-string type will do, and it's also what occurs in sread mentioned in Jim's answer.

(The while loop iteration scheme condition does not require parentheses. Conditions are boolean expressions delimited by reserved words.)

%: ghdl -a -fsynopsys sample_tb.vhdl
%: ghdl -e -fsynopsys sample_tb
%: ghdl -r sample_tb
00 00 A
00 00 B
00 00 C
00 00 D
00 00 E
%: 

where the writeline operations duplicate the contents of input_sample.txt to OUTPUT.

The description of the read behavior can be found in IEEE std 1076-2008 16.4 Package TEXTIO pages 273 and 274 or IEEE Std 1076-1993/2002 14.3 Package TEXTIO.

The basic distinction is string read procedure calls use an end of line indication comprised of one or more characters where CHARACTER is the element type of STRING to delimit a readline operation, leaving other CHARACTER values in the read[1] string. Trying to read[2] a string from from a line will result in those characters being extracted into the string.

[1] read verb 4 his remark could be read as a dig at Forsyth. INTERPRET, take, take to mean, construe, see, explain, understand.
[2] noun I settled down for a read of "The Irish Press". perusal, study, scan, scrutiny; look (at), browse (through), glance (through), leaf (through), flick (through), skim (through).

answered May 21, 2024 at 1:57
\$\endgroup\$
6
  • \$\begingroup\$ That is obscenely complex given that VHDL-2008 supports sread and all simulators except Xilinx xsim support it. \$\endgroup\$ Commented May 21, 2024 at 3:30
  • \$\begingroup\$ A declaration and a 9 line for loop is obscenely complex because hyperbole? How's the weather in the Pacific Northwest or is the political news getting you down? \$\endgroup\$ Commented May 21, 2024 at 4:58
  • \$\begingroup\$ Considering that sread gets the job done in one simple statement and that you are suggesting pointer manipulations to a person just getting started. \$\endgroup\$ Commented May 21, 2024 at 14:01
  • \$\begingroup\$ Also note a read operation should never see an end of line character. From 16.4, "Procedure READLINE causes the next line to be read from the file and returns as the value of parameter L an access value that designates an object representing that line. If parameter L contains a non-null access value at the start of the call, the procedure may deallocate the object designated by that value. The representation of the line does not contain the representation of the end of the line." Most simulators are compliant in this regard, however, there are a few that are not - Xilinx xsim. \$\endgroup\$ Commented May 21, 2024 at 14:25
  • \$\begingroup\$ @Jim You've already down voted. Consider putting some of that effort into your own posts. \$\endgroup\$ Commented May 21, 2024 at 18:30

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.