OpenCores
URL https://opencores.org/ocsvn/common_pkg/common_pkg/trunk

Subversion Repositories common_pkg

[/] [common_pkg/] [trunk/] [common_str_pkg.vhd] - Blame information for rev 9

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 danv
-------------------------------------------------------------------------------
2
--
3 9 danv
-- Copyright (C) 2019
4 6 danv
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
--
7
-- This program is free software: you can redistribute it and/or modify
8
-- it under the terms of the GNU General Public License as published by
9
-- the Free Software Foundation, either version 3 of the License, or
10
-- (at your option) any later version.
11
--
12
-- This program is distributed in the hope that it will be useful,
13
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
-- GNU General Public License for more details.
16
--
17
-- You should have received a copy of the GNU General Public License
18
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
-------------------------------------------------------------------------------
21
 
22 9 danv
-- Author:
23
-- . Daniel van der Schuur
24
-- Purpose:
25
-- . Collection of commonly used string funtions
26
-- Interface:
27
-- . [n/a]
28
-- Description:
29
-- . None
30
 
31 6 danv
LIBRARY IEEE;
32
USE IEEE.STD_LOGIC_1164.ALL;
33
USE IEEE.NUMERIC_STD.ALL;
34
USE STD.TEXTIO.ALL;
35
USE IEEE.STD_LOGIC_TEXTIO.ALL;
36 9 danv
USE common_pkg_lib.common_pkg.ALL;
37 6 danv
 
38
PACKAGE common_str_pkg IS
39
 
40
  TYPE t_str_4_arr IS ARRAY (INTEGER RANGE <>) OF STRING(1 TO 4);
41
 
42
  FUNCTION nof_digits(number: NATURAL) RETURN NATURAL;
43
  FUNCTION nof_digits_int(number: INTEGER) RETURN NATURAL;
44
 
45
  FUNCTION time_to_str(in_time : TIME) RETURN STRING;
46
  FUNCTION str_to_time(in_str : STRING) RETURN TIME;
47
  FUNCTION slv_to_str(slv : STD_LOGIC_VECTOR) RETURN STRING;
48
  FUNCTION str_to_hex(str : STRING) RETURN STRING;
49
  FUNCTION slv_to_hex(slv : STD_LOGIC_VECTOR) RETURN STRING;
50
  FUNCTION hex_to_slv(str : STRING) RETURN STD_LOGIC_VECTOR;
51
 
52
  Function hex_nibble_to_slv(c: character) return std_logic_vector;
53
 
54
  FUNCTION int_to_str(int: INTEGER) RETURN STRING;
55
  FUNCTION real_to_str(re: REAL; width : INTEGER; digits : INTEGER) RETURN STRING;
56
 
57
  PROCEDURE print_str(str : STRING);
58
 
59
  FUNCTION str_to_ascii_integer_arr(s: STRING) RETURN t_integer_arr;
60
  FUNCTION str_to_ascii_slv_8_arr(  s: STRING) RETURN t_slv_8_arr;
61
  FUNCTION str_to_ascii_slv_32_arr( s: STRING) RETURN t_slv_32_arr;
62
  FUNCTION str_to_ascii_slv_32_arr( s: STRING; arr_size : NATURAL) RETURN t_slv_32_arr;
63
 
64
END common_str_pkg;
65
 
66
PACKAGE BODY common_str_pkg IS
67
 
68
  FUNCTION nof_digits(number: NATURAL) RETURN NATURAL IS
69
  -- Returns number of digits in a natural number. Only used in string processing, so defined here.
70
  -- log10(0) is not allowed so:
71
  -- . nof_digits(0) = 1
72
  -- We're adding 1 so:
73
  -- . nof_digits(1) = 1
74
  -- . nof_digits(9) = 1
75
  -- . nof_digits(10) = 2
76
  BEGIN
77
    IF number>0 THEN
78
      RETURN floor_log10(number)+1;
79
    ELSE
80
      RETURN 1;
81
    END IF;
82
  END;
83
 
84
  FUNCTION nof_digits_int(number: INTEGER) RETURN NATURAL IS
85
  -- Returns number of digits in a natural number. Only used in string processing, so defined here.
86
  -- log10(0) is not allowed so:
87
  -- . nof_digits(0) = 1
88
  -- We're adding 1 so:
89
  -- . nof_digits(1) = 1
90
  -- . nof_digits(9) = 1
91
  -- . nof_digits(10) = 2
92
  -- . nof_digits(1) = 2
93
  BEGIN
94
    IF number=0 THEN
95
      RETURN 1;
96
    ELSE
97
      IF number > 0 THEN
98
        RETURN floor_log10(number)+1;
99
      ELSE
100
        RETURN floor_log10(-1*number)+2;
101
      END IF;
102
    END IF;
103
  END;
104
 
105
  FUNCTION time_to_str(in_time : TIME) RETURN STRING IS
106
    CONSTANT c_max_len_time : NATURAL := 20;
107
        VARIABLE v_line         : LINE;
108
        VARIABLE v_str          : STRING(1 TO c_max_len_time):= (OTHERS => ' ');
109
  BEGIN
110
    write(v_line, in_time);
111
        v_str(v_line.ALL'RANGE) := v_line.ALL;
112
        deallocate(v_line);
113
        RETURN v_str;
114
  END;
115
 
116
  FUNCTION str_to_time(in_str : STRING) RETURN TIME IS
117
  BEGIN
118
    RETURN TIME'VALUE(in_str);
119
  END;
120
 
121
  FUNCTION slv_to_str(slv : STD_LOGIC_VECTOR) RETURN STRING IS
122
    VARIABLE v_line : LINE;
123
    VARIABLE v_str  : STRING(1 TO slv'LENGTH) := (OTHERS => ' ');
124
  BEGIN
125
     write(v_line, slv);
126
     v_str(v_line.ALL'RANGE) := v_line.ALL;
127
     deallocate(v_line);
128
     RETURN v_str;
129
  END;
130
 
131
  FUNCTION str_to_hex(str : STRING) RETURN STRING IS
132
    CONSTANT c_nof_nibbles : NATURAL := ceil_div(str'LENGTH, c_nibble_w);
133
    VARIABLE v_nibble_arr  : t_str_4_arr(0 TO c_nof_nibbles-1) := (OTHERS=>(OTHERS=>'0'));
134
    VARIABLE v_hex         : STRING(1 TO c_nof_nibbles) := (OTHERS => '0');
135
  BEGIN
136
    FOR i IN 0 TO v_hex'RIGHT-1 LOOP
137
      v_nibble_arr(i) := slice_up(str, c_nibble_w, i, '0');
138
 
139
      CASE v_nibble_arr(i) IS
140
        WHEN "0000" => v_hex(i+1) := '0';
141
        WHEN "0001" => v_hex(i+1) := '1';
142
        WHEN "0010" => v_hex(i+1) := '2';
143
        WHEN "0011" => v_hex(i+1) := '3';
144
        WHEN "0100" => v_hex(i+1) := '4';
145
        WHEN "0101" => v_hex(i+1) := '5';
146
        WHEN "0110" => v_hex(i+1) := '6';
147
        WHEN "0111" => v_hex(i+1) := '7';
148
        WHEN "1000" => v_hex(i+1) := '8';
149
        WHEN "1001" => v_hex(i+1) := '9';
150
        WHEN "1010" => v_hex(i+1) := 'A';
151
        WHEN "1011" => v_hex(i+1) := 'B';
152
        WHEN "1100" => v_hex(i+1) := 'C';
153
        WHEN "1101" => v_hex(i+1) := 'D';
154
        WHEN "1110" => v_hex(i+1) := 'E';
155
        WHEN "1111" => v_hex(i+1) := 'F';
156
        WHEN OTHERS => v_hex(i+1) := 'X';
157
      END CASE;
158
    END LOOP;
159
    RETURN v_hex;
160
  END;
161
 
162
  FUNCTION slv_to_hex(slv :STD_LOGIC_VECTOR) RETURN STRING IS
163
  BEGIN
164
    RETURN str_to_hex(slv_to_str(slv));
165
  END;
166
 
167
  FUNCTION hex_to_slv(str: STRING) RETURN STD_LOGIC_VECTOR IS
168
  CONSTANT c_length : NATURAL := str'LENGTH;
169
  VARIABLE v_str    : STRING(1 TO str'LENGTH) := str; -- Keep local copy of str to prevent range mismatch
170
  VARIABLE v_result : STD_LOGIC_VECTOR(c_length * 4 - 1 DOWNTO 0);
171
  BEGIN
172
   FOR i IN c_length DOWNTO 1 LOOP
173
       v_result(3 +(c_length - i)*4  DOWNTO (c_length-i)*4) := hex_nibble_to_slv(v_str(i));
174
   END LOOP;
175
   RETURN v_result;
176
  END;
177
 
178
  FUNCTION hex_nibble_to_slv(c: CHARACTER) RETURN STD_LOGIC_VECTOR IS
179
    VARIABLE v_result : STD_LOGIC_VECTOR(3 DOWNTO 0);
180
  BEGIN
181
    CASE c IS
182
      WHEN '0' => v_result :=  "0000";
183
      WHEN '1' => v_result :=  "0001";
184
      WHEN '2' => v_result :=  "0010";
185
      WHEN '3' => v_result :=  "0011";
186
      WHEN '4' => v_result :=  "0100";
187
      WHEN '5' => v_result :=  "0101";
188
      WHEN '6' => v_result :=  "0110";
189
      WHEN '7' => v_result :=  "0111";
190
      WHEN '8' => v_result :=  "1000";
191
      WHEN '9' => v_result :=  "1001";
192
      WHEN 'A' => v_result :=  "1010";
193
      WHEN 'B' => v_result :=  "1011";
194
      WHEN 'C' => v_result :=  "1100";
195
      WHEN 'D' => v_result :=  "1101";
196
      WHEN 'E' => v_result :=  "1110";
197
      WHEN 'F' => v_result :=  "1111";
198
      WHEN 'a' => v_result :=  "1010";
199
      WHEN 'b' => v_result :=  "1011";
200
      WHEN 'c' => v_result :=  "1100";
201
      WHEN 'd' => v_result :=  "1101";
202
      WHEN 'e' => v_result :=  "1110";
203
      WHEN 'f' => v_result :=  "1111";
204
      WHEN 'x' => v_result :=  "XXXX";
205
      WHEN 'X' => v_result :=  "XXXX";
206
      WHEN 'z' => v_result :=  "ZZZZ";
207
      WHEN 'Z' => v_result :=  "ZZZZ";
208
 
209
            WHEN OTHERS => v_result := "0000";
210
     END CASE;
211
   RETURN v_result;
212
  END hex_nibble_to_slv;
213
 
214
  FUNCTION int_to_str(int: INTEGER) RETURN STRING IS
215
    VARIABLE v_line: LINE;
216
    VARIABLE v_str: STRING(1 TO nof_digits_int(int)):= (OTHERS => ' ');
217
  BEGIN
218
    STD.TEXTIO.WRITE(v_line, int);
219
    v_str(v_line.ALL'RANGE) := v_line.ALL;
220
    deallocate(v_line);
221
    RETURN v_str;
222
  END;
223
 
224
  FUNCTION real_to_str(re: REAL; width : INTEGER; digits : INTEGER) RETURN STRING IS
225
    VARIABLE v_line: LINE;
226
    VARIABLE v_str: STRING(1 TO width):= (OTHERS => ' ');
227
  BEGIN
228
    STD.TEXTIO.WRITE(v_line, re, right, width, digits);
229
    v_str(v_line.ALL'RANGE) := v_line.ALL;
230
    deallocate(v_line);
231
    RETURN v_str;
232
  END;
233
 
234
  PROCEDURE print_str(str: STRING) IS
235
  VARIABLE v_line: LINE;
236
  BEGIN
237
    write(v_line, str);
238
    writeline(output, v_line);
239
    deallocate(v_line);
240
  END;
241
 
242
  FUNCTION str_to_ascii_integer_arr(s: STRING) RETURN t_integer_arr IS
243
    VARIABLE r: t_integer_arr(0 TO s'RIGHT-1);
244
  BEGIN
245
    FOR i IN s'RANGE LOOP
246
      r(i-1) := CHARACTER'POS(s(i));
247
    END LOOP;
248
    RETURN r;
249
  END;
250
 
251
  FUNCTION str_to_ascii_slv_8_arr(s: STRING) RETURN t_slv_8_arr IS
252
    VARIABLE r: t_slv_8_arr(0 TO s'RIGHT-1);
253
  BEGIN
254
    FOR i IN s'RANGE LOOP
255
      r(i-1) := TO_UVEC(str_to_ascii_integer_arr(s)(i-1), 8);
256
    END LOOP;
257
    RETURN r;
258
  END;
259
 
260
  -- Returns minimum array size required to fit the string
261
  FUNCTION str_to_ascii_slv_32_arr(s: STRING) RETURN t_slv_32_arr IS
262
    CONSTANT c_slv_8: t_slv_8_arr(0 TO s'RIGHT-1) := str_to_ascii_slv_8_arr(s);
263
    CONSTANT c_bytes_per_word : NATURAL := 4;
264
    -- Initialize all elements to (OTHERS=>'0') so any unused bytes become a NULL character
265
    VARIABLE r: t_slv_32_arr(0 TO ceil_div(s'RIGHT * c_byte_w, c_word_w)-1) := (OTHERS=>(OTHERS=>'0'));
266
  BEGIN
267
    FOR word IN r'RANGE  LOOP --0, 1
268
      FOR byte IN 0 TO c_bytes_per_word-1 LOOP -- 0,1,2,3
269
        IF byte+c_bytes_per_word*word<=c_slv_8'RIGHT THEN
270
          r(word)(byte*c_byte_w+c_byte_w-1 DOWNTO byte*c_byte_w) := c_slv_8(byte+c_bytes_per_word*word);
271
        END IF;
272
      END LOOP;
273
    END LOOP;
274
 
275
    RETURN r;
276
  END;
277
 
278
  -- Overloaded version to match array size to arr_size
279
  FUNCTION str_to_ascii_slv_32_arr(s: STRING; arr_size: NATURAL) RETURN t_slv_32_arr IS
280
    CONSTANT slv_32: t_slv_32_arr(0 TO ceil_div(s'RIGHT * c_byte_w, c_word_w)-1) := str_to_ascii_slv_32_arr(s);
281
    VARIABLE r: t_slv_32_arr(0 TO arr_size-1) := (OTHERS=>(OTHERS=>'0'));
282
  BEGIN
283
    FOR word IN slv_32'RANGE  LOOP
284
      r(word) := slv_32(word);
285
    END LOOP;
286
    RETURN r;
287
  END;
288
 
289
END common_str_pkg;
290
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.