- added models
git-svn-id: http://moon:8086/svn/vhdl/trunk@1290 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
LIBRARY ieee;
|
||||
USE std.textio.ALL;
|
||||
USE ieee.std_logic_1164.ALL;
|
||||
|
||||
PACKAGE io_utils IS
|
||||
|
||||
PROCEDURE write_string(l : INOUT line;
|
||||
value : IN string;
|
||||
justified : IN side := right;
|
||||
field : IN width := 0);
|
||||
|
||||
TYPE radix IS (binary, octal, decimal, hex);
|
||||
|
||||
-- read a number from the line
|
||||
-- use this if you have hex numbers that are not in VHDL pound-sign format
|
||||
PROCEDURE read(l : INOUT line; value : OUT integer; radix : IN positive);
|
||||
|
||||
-- read a number that might be in VHDL pound-sign format
|
||||
PROCEDURE read_based(l : INOUT line; value : OUT integer);
|
||||
|
||||
PROCEDURE write(l : INOUT line;
|
||||
value : IN std_logic_vector;
|
||||
justified : IN side := right;
|
||||
field : IN width := 0;
|
||||
base : IN radix;
|
||||
use_pound : boolean := false);
|
||||
|
||||
PROCEDURE write(l : INOUT line;
|
||||
value : IN integer;
|
||||
justified : IN side := right;
|
||||
field : IN width := 0;
|
||||
base : IN radix;
|
||||
use_pound : boolean := false);
|
||||
END io_utils;
|
||||
|
||||
PACKAGE BODY io_utils IS
|
||||
|
||||
PROCEDURE write_string(l : INOUT line;
|
||||
value : IN string;
|
||||
justified : IN side := right;
|
||||
field : IN width := 0)
|
||||
IS
|
||||
BEGIN
|
||||
write(l, value, justified, field);
|
||||
END;
|
||||
|
||||
PROCEDURE shrink_line(l : INOUT line; pos : integer) IS
|
||||
VARIABLE tmpl : line;
|
||||
BEGIN
|
||||
tmpl := l;
|
||||
l := NEW string'(tmpl(pos TO tmpl'high));
|
||||
deallocate(tmpl);
|
||||
END;
|
||||
|
||||
PROCEDURE read(l : INOUT line;
|
||||
value : OUT integer;
|
||||
radix : IN positive)
|
||||
IS
|
||||
CONSTANT not_digit : integer := -999;
|
||||
|
||||
-- convert a character to a value from 0 to 15
|
||||
FUNCTION digit_value(c : character) RETURN integer IS
|
||||
BEGIN
|
||||
IF (c >= '0') AND (c <= '9') THEN
|
||||
RETURN (character'pos(c) - character'pos('0'));
|
||||
ELSIF (c >= 'a') AND (c <= 'f') THEN
|
||||
RETURN (character'pos(c) - character'pos('a') + 10);
|
||||
ELSIF (c >= 'A') AND (c <= 'F') THEN
|
||||
RETURN (character'pos(c) - character'pos('A') + 10);
|
||||
ELSE
|
||||
RETURN not_digit;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
-- skip leading white space in the line
|
||||
PROCEDURE skip_white(VARIABLE l : IN line; pos : OUT integer) IS
|
||||
BEGIN
|
||||
pos := l'low;
|
||||
FOR i IN l'low TO l'high LOOP
|
||||
CASE l(i) IS
|
||||
WHEN ' ' | ht =>
|
||||
pos := i + 1;
|
||||
WHEN OTHERS =>
|
||||
EXIT;
|
||||
END CASE;
|
||||
END LOOP;
|
||||
END;
|
||||
|
||||
VARIABLE digit : integer;
|
||||
VARIABLE result : integer := 0;
|
||||
VARIABLE pos : integer;
|
||||
BEGIN
|
||||
-- skip white space
|
||||
skip_white(l, pos);
|
||||
|
||||
-- calculate the value
|
||||
FOR i IN pos TO l'right LOOP
|
||||
digit := digit_value(l(i));
|
||||
EXIT WHEN (digit = not_digit) OR (digit >= radix);
|
||||
result := result * radix + digit;
|
||||
pos := i + 1;
|
||||
END LOOP;
|
||||
value := result;
|
||||
|
||||
-- remove the "used" characters from the line
|
||||
shrink_line(l, pos);
|
||||
END;
|
||||
|
||||
PROCEDURE read_based(l : INOUT line; value : OUT integer) IS
|
||||
VARIABLE digit : integer;
|
||||
VARIABLE num : integer;
|
||||
VARIABLE base : integer;
|
||||
BEGIN
|
||||
read(l, num, 10);
|
||||
IF (l'length > 1) AND (l(l'left) = '#') THEN
|
||||
shrink_line(l, l'left+1);
|
||||
base := num;
|
||||
read(l, num, base);
|
||||
IF (l'length >= 1) AND (l(l'left) = '#') THEN
|
||||
shrink_line(l, l'left+1);
|
||||
END IF;
|
||||
END IF;
|
||||
value := num;
|
||||
END;
|
||||
|
||||
PROCEDURE write(l : INOUT line;
|
||||
value : IN std_logic_vector;
|
||||
justified : IN side := right;
|
||||
field : IN width := 0;
|
||||
base : IN radix;
|
||||
use_pound : boolean := false)
|
||||
IS
|
||||
FUNCTION to_int(bv : std_logic_vector) RETURN integer
|
||||
IS
|
||||
VARIABLE result : integer := 0;
|
||||
BEGIN
|
||||
FOR i IN bv'RANGE LOOP
|
||||
result := result * 2;
|
||||
IF (bv(i) = '1') THEN
|
||||
result := result + 1;
|
||||
END IF;
|
||||
END LOOP;
|
||||
RETURN result;
|
||||
END;
|
||||
|
||||
TYPE array_of_widths IS ARRAY(radix) OF natural;
|
||||
CONSTANT nibble_widths : array_of_widths := (
|
||||
binary => 1,
|
||||
octal => 3,
|
||||
hex => 4,
|
||||
decimal=> 32);
|
||||
CONSTANT hex_digit : string(1 TO 16) := "0123456789ABCDEF";
|
||||
|
||||
ALIAS input_val : std_logic_vector(value'length DOWNTO 1) IS value;
|
||||
CONSTANT nibble_width : natural := nibble_widths(base);
|
||||
CONSTANT result_width : natural := (value'length + nibble_width - 1)/nibble_width;
|
||||
|
||||
VARIABLE result : string(1 TO result_width); -- longest possible value
|
||||
VARIABLE result_pos : positive := 1;
|
||||
VARIABLE nibble_val : integer;
|
||||
VARIABLE bitcnt : integer;
|
||||
BEGIN
|
||||
IF base = decimal THEN
|
||||
write(l, to_int(value), justified, field, base, use_pound);
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
bitcnt := value'length MOD nibble_width;
|
||||
IF (bitcnt = 0) THEN
|
||||
bitcnt := nibble_width;
|
||||
END IF;
|
||||
FOR i IN input_val'RANGE LOOP
|
||||
nibble_val := nibble_val * 2;
|
||||
IF (input_val(i) = '1') THEN
|
||||
nibble_val := nibble_val + 1;
|
||||
END IF;
|
||||
bitcnt := bitcnt - 1;
|
||||
IF (bitcnt = 0) THEN
|
||||
result(result_pos) := hex_digit(nibble_val + 1);
|
||||
result_pos := result_pos + 1;
|
||||
nibble_val := 0;
|
||||
bitcnt := nibble_width;
|
||||
END IF;
|
||||
END LOOP;
|
||||
write(l, result, justified, field);
|
||||
END;
|
||||
|
||||
PROCEDURE write(l : INOUT line;
|
||||
value : IN integer;
|
||||
justified : IN side := right;
|
||||
field : IN width := 0;
|
||||
base : IN radix;
|
||||
use_pound : boolean := false)
|
||||
IS
|
||||
FUNCTION to_bv(int : integer) RETURN std_logic_vector
|
||||
IS
|
||||
VARIABLE bv : std_logic_vector(32 DOWNTO 1) := (OTHERS => '0');
|
||||
VARIABLE pos : integer := 0;
|
||||
VARIABLE tmpval : integer := int;
|
||||
BEGIN
|
||||
FOR i IN 1 TO 32 LOOP
|
||||
pos := pos + 1;
|
||||
IF (tmpval MOD 2) = 1 THEN
|
||||
bv(i) := '1';
|
||||
END IF;
|
||||
tmpval := tmpval / 2;
|
||||
EXIT WHEN tmpval = 0;
|
||||
END LOOP;
|
||||
RETURN bv(pos DOWNTO 1);
|
||||
END;
|
||||
|
||||
VARIABLE tmp : line;
|
||||
BEGIN
|
||||
IF (base = decimal) THEN
|
||||
IF (use_pound) THEN
|
||||
write_string(tmp, "10#");
|
||||
END IF;
|
||||
write(tmp, value);
|
||||
IF (use_pound) THEN
|
||||
write_string(tmp, "#");
|
||||
END IF;
|
||||
write(l, tmp.ALL, justified, field);
|
||||
deallocate(tmp);
|
||||
ELSE
|
||||
write(l, to_bv(value), justified, field, base, use_pound);
|
||||
END IF;
|
||||
END;
|
||||
|
||||
END io_utils;
|
||||
|
||||
|
||||
|
||||
-- test the hex number reader
|
||||
--ENTITY test IS END;
|
||||
|
||||
--USE std.textio.ALL;
|
||||
--USE work.io_utils.ALL;
|
||||
--ARCHITECTURE hex_test OF test IS
|
||||
--BEGIN
|
||||
-- PROCESS
|
||||
-- VARIABLE val : integer;
|
||||
-- FILE myfile : text IS IN "values";
|
||||
-- VARIABLE inline : line;
|
||||
-- VARIABLE outline : line;
|
||||
-- BEGIN
|
||||
-- WHILE NOT endfile(myfile) LOOP
|
||||
-- readline(myfile, inline);
|
||||
|
||||
-- write(outline, inline.ALL);
|
||||
--
|
||||
-- read_based(inline, val);
|
||||
-- write_string(outline, " binary: ");
|
||||
-- write(outline, val, base => binary);
|
||||
-- write_string(outline, " octal: ");
|
||||
-- write(outline, val, base => octal);
|
||||
-- write_string(outline, " decimal: ");
|
||||
-- write(outline, val, base => decimal);
|
||||
-- write_string(outline, " hex: ");
|
||||
-- write(outline, val, base => hex);
|
||||
-- writeline(output, outline);
|
||||
-- END LOOP;
|
||||
-- WAIT;
|
||||
-- END PROCESS;
|
||||
--END;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user