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;
|