aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/gna/issue795/file_reader_pkg.vhdl
blob: 99e167ac91d39b01f39265fb29f39a503258a30e (plain)
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
library ieee;
--! Standard packages
use ieee.Std_logic_1164.all;
use ieee.Numeric_std.all;
--! Implicit use of std libary
--library std;
use std.textio.all;
--
-- unit name: csv_file_reader package
--
--! @brief Package contains functions to read CSV file
--!
--! @author Ricardo Jasinski
--!
--! @version 2.0
--!
--! @details
--! CSV Reader package taken from Web
--! Latest commit 4e2d20f  on 10 Sep 2013 
--! Public license - no guarrentee
--! https://github.com/ricardo-jasinski/vhdl-csv-file-reader
--!
--! Modifications by CL add to include function to read HEX numberes
-- Define operations to read formatted data from a comma-separated-values file
-- (CSV file). To use this package:
--    1. Create a csv_file_reader:      variable csv: csv_file_reader_type;
--    2. Open a csv file:               csv.initialize("c:\file.csv");
--    3. Read one line at a time:       csv.readline;
--    4. Start reading values:          my_integer := csv.read_integer;
--    5. To read more values in the same line, call any of the read_* functions
--    6. To move to the next line, call csv.readline() again
package csv_file_reader_pkg is
	-- Maximum string length for read operations
	constant LINE_LENGTH_MAX : integer := 256;
	-- file reader type
	type csv_file_reader_type is protected
		-- Open the CSV text file to be used for subsequent read operations
		procedure initialize(file_pathname : string);
		-- Release (close) the associated CSV file
		procedure dispose;
		-- Read one line from the csv file, and keep it in the cache
		procedure readline;
		-- Read a string from the csv file and convert it to an integer
		impure function read_integer return integer;
		-- Read a string from the csv file as an  hex number and convert it to an integer
		-- convert to a unsigned integer depending if MSB is set
		impure function read_hex return integer;
		-- Read a string from the csv file and convert it to real
		impure function read_real return real;
		-- Read a string from the csv file and convert it to boolean
		impure function read_boolean return boolean;
		-- Read a string with a numeric value from the csv file and convert it to a boolean
		impure function read_integer_as_boolean return boolean;
		-- Read a string from the csv file, until a separator character ',' is found
		impure function read_string return string;
		-- True when the end of the CSV file was reached
		impure function end_of_file return boolean;
	end protected;
end;

package body csv_file_reader_pkg is

	type csv_file_reader_type is protected body
		file my_csv_file             : text;
		-- cache one line at a time for read operations
		variable current_line        : line;
		-- true when end of file was reached and there are no more lines to read
		variable end_of_file_reached : boolean;

		-- True when the end of the CSV file was reached
		impure function end_of_file return boolean is
		begin
			return end_of_file_reached;
		end;

		-- Open the CSV text file to be used for subsequent read operations
		procedure initialize(file_pathname : string) is
		begin
			file_open(my_csv_file, file_pathname, READ_MODE);
			end_of_file_reached := false;
		end;

		-- Release (close) the associated CSV file
		procedure dispose is
		begin
			file_close(my_csv_file);
		end;

		-- Read one line from the csv file, and keep it in the cache
		procedure readline is
		begin
			readline(my_csv_file, current_line);
			end_of_file_reached := endfile(my_csv_file);
		end;

		-- Skip a separator (comma character) in the current line
		procedure skip_separator is
			variable dummy_string : string(1 to LINE_LENGTH_MAX);
		begin
			dummy_string := read_string;
		end;

		-- Read a string from the csv file and convert it to integer
		impure function read_integer return integer is
			variable read_value : integer;
		begin
			-- read(current_line, read_value);
			skip_separator;
			return read_value;
		end;

		-- Read a string from the csv file and assume it is Hex value
		impure function read_hex return integer is
			variable return_integer : integer := 0;
			variable char_val       : integer := 0;
			variable read_char      : character;
			variable read_ok        : boolean := true;
		begin
			-- read(current_line, read_char, read_ok);
			while read_ok loop
				if read_char = ',' then
					return return_integer;
				else
					return_integer := return_integer * 16;
					if read_char >= 'a' and read_char <= 'f' then
						char_val := (character'pos(read_char) - character'pos('a')) + 10;
					elsif read_char >= 'A' and read_char <= 'F' then
						char_val := (character'pos(read_char) - character'pos('A')) + 10;
					else
						char_val := (character'pos(read_char) - character'pos('0'));
					end if;
					return_integer := return_integer + char_val;
				end if;
				-- read(current_line, read_char, read_ok);
			end loop;
			return read_integer;
		end;

		-- Read a string from the csv file and convert it to real
		impure function read_real return real is
			variable read_value : real;
		begin
			read(current_line, read_value);
			skip_separator;
			return read_value;
		end;

		-- Read a string from the csv file and convert it to boolean
		impure function read_boolean return boolean is
		begin
			return boolean'value(read_string);
		end;

		impure function read_integer_as_boolean return boolean is
		begin
			return (read_integer /= 0);
		end;

		-- Read a string from the csv file, until a separator character ',' is found
		-- Delimeter "" used if first and last char
		impure function read_string return string is
			variable return_string : string(1 to LINE_LENGTH_MAX);
			variable read_char     : character;
			variable read_ok       : boolean := true;
			variable read_delim    : boolean := false;
			variable index         : integer := 0;
		begin
			read(current_line, read_char, read_ok);
			while read_ok loop
				case index is
					when 0 =>
						if read_char = ',' then
							return return_string;
						elsif read_char = '"' then
							index      := 1;
							read_delim := true;
						else
							return_string(1) := read_char;
							index            := 2;
						end if;
					when -1 =>
						if read_char = ',' then
							return return_string;
						else
							read_delim := false;
						end if;
					when others =>
						if read_delim and read_char = '"' then
							index      := -1;
							read_delim := false;
						elsif not read_delim and read_char = ',' then
							return return_string;
						else
							return_string(index) := read_char;
							index                := index + 1;
						end if;
				end case;
				read(current_line, read_char, read_ok);
			end loop;
			return "Exit";
		end;
	end protected body;

end;