summaryrefslogtreecommitdiff
path: root/vhdl/fmf/conversions.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'vhdl/fmf/conversions.vhd')
-rw-r--r--vhdl/fmf/conversions.vhd1178
1 files changed, 1178 insertions, 0 deletions
diff --git a/vhdl/fmf/conversions.vhd b/vhdl/fmf/conversions.vhd
new file mode 100644
index 0000000..bc42e47
--- /dev/null
+++ b/vhdl/fmf/conversions.vhd
@@ -0,0 +1,1178 @@
+--------------------------------------------------------------------------------
+-- File Name: conversions.vhd
+--------------------------------------------------------------------------------
+-- Copyright (C) 1997-2008 Free Model Foundry; http://www.FreeModelFoundry.com
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License version 2 as
+-- published by the Free Software Foundation.
+--
+-- This package was originally written by SEVA Technologies, Inc. and donated
+-- to the FMF.
+-- www.seva.com
+--
+-- MODIFICATION HISTORY:
+--
+-- version: | author: | mod date: | changes made:
+-- V1.0 R. Steele 97 DEC 05 Added header and formatting to SEVA file
+-- V1.1 R. Munden 98 NOV 28 Corrected some comments
+-- Corrected function b
+-- V1.2 R. Munden 01 MAY 27 Corrected function to_nat for weak values
+-- and combined into a single file
+-- V1.3 M.Radmanovic 03 Aug 18 Added signed conversion function to_int
+-- V1.4 M.Radmanovic 03 Nov 10 Added signed conversion function
+-- int_to_slv
+-- V1.5 R. Munden 04 NOV 11 Added type conversion to t_hex_str
+-- V1.6 D. Rheault 07 MAY 21 Corrected int_to_slv for value of 0
+-- V1.7 V.Markovic 08 Apr 24 Changed condition for variable int (in
+-- function int_to_slv) from > to >=
+-- V1.8 R. Munden 08 MAY 21 Fixed default base for x=0 in to_int_str
+--
+--------------------------------------------------------------------------------
+
+LIBRARY IEEE; USE IEEE.std_logic_1164.ALL;
+
+--------------------------------------------------------------------------------
+-- CONVERSION FUNCTION SELECTION TABLES
+--------------------------------------------------------------------------------
+--
+-- FROM TO: std_logic_vector std_logic natural time string
+-- -----------------|---------------|---------|---------|---------|-----------
+-- std_logic_vector | N/A | N/A | to_nat | combine | see below
+-- std_logic | N/A | N/A | to_nat | combine | see below
+-- natural | to_slv | to_sl | N/A | to_time | see below
+-- integer | to_slv | N/A | N/A | N/A | N/A
+-- time | N/A | N/A | to_nat | N/A | to_time_str
+-- hex string | h | N/A | h | combine | N/A
+-- decimal string | d | N/A | d | combine | N/A
+-- octal string | o | N/A | o | combine | N/A
+-- binary string | b | N/A | b | combine | N/A
+-- -----------------|---------------|---------|---------|---------|-----------
+--
+-- FROM TO: hex string decimal string octal string binary string
+-- -----------------|------------|-------------|------------|----------------
+-- std_logic_vector | to_hex_str | to_int_str | to_oct_str | to_bin_str
+-- std_logic | N/A | N/A | N/A | to_bin_str
+-- natural | to_hex_str | to_int_str | to_oct_str | to_bin_str
+-- -----------------|------------|-------------|------------|----------------
+--
+-- FROM TO: integer
+-- -----------------|---------------|
+-- std_logic_vector | to_int |
+--------------------------------------------------------------------------------
+
+PACKAGE conversions IS
+
+ ----------------------------------------------------------------------------
+ -- the conversions in this package are not intended to be synthesizable.
+ --
+ -- others functions available
+ -- fill creates a variable length string of the fill character
+ --
+ --
+ --
+ -- input parameters of type natural or integer can be in the form:
+ -- normal -> 8, 99, 4_237
+ -- base#value# -> 2#0101#, 16#fa4C#, 8#6_734#
+ -- with exponents(x10) -> 8e4, 16#2e#E4
+ --
+ -- input parameters of type string can be in the form:
+ -- "99", "4_237", "0101", "1010_1010"
+ --
+ -- for bit/bit_vector <-> std_logic/std_logic_vector conversions use
+ -- package std_logic_1164
+ -- to_bit(std_logic)
+ -- to_bitvector(std_logic_vector)
+ -- to_stdlogic(bit)
+ -- to_stdlogicvector(bit_vector)
+ --
+ -- for "synthesizable" signed/unsigned/std_logic_vector/integer
+ -- conversions use
+ -- package std_logic_arith
+ -- conv_integer(signed/unsigned)
+ -- conv_unsigned(integer/signed,size)
+ -- conv_signed(integer/unsigned,size)
+ -- conv_std_logic_vector(integer/signed/unsigned,size)
+ --
+ -- for "synthesizable" std_logic_vector -> integer conversions use
+ -- package std_logic_unsigned/std_logic_signed
+ -- <these packages are mutually exclusive>
+ -- conv_integer(std_logic_vector)
+ -- <except for this conversion, these packages are unnecessary)
+ -- to minimize compile problems write:
+ -- use std_logic_unsigned.conv_integer;
+ -- use std_logic_signed.conv_integer;
+ --
+ -- std_logic_vector, signed and unsigned types are "closely related"
+ -- no type conversion functions are needed, use type casting or qualified
+ -- expressions
+ --
+ -- type1(object of type2) <type casting>
+ -- type1'(expression of type2) <qualified expression>
+ --
+ -- most conversions have 4 parmeters:
+ -- x : value to be converted
+ -- rtn_len : size of the return value
+ -- justify : justify value 'left' or 'right', default is right
+ -- basespec : print the base of the value - 'yes'/'no', default is yes
+ --
+ -- Typical ways to call these functions:
+ -- simple, all defaults used
+ -- to_bin_str(x)
+ -- x will be converted to a string of minimum size with a
+ -- base specification appended for clarity
+ -- if x is 10101 then return is b"10101"
+ --
+ -- to control size of return string
+ -- to_hex_str(x,
+ -- 6)
+ -- length of string returned will be 6 characters
+ -- value will be right justified in the field
+ -- if x is 10101 then return is ....h"15"
+ -- where '.' represents a blank
+ -- if 'rtn_len' parm defaults or is set to 0 then
+ -- return string will always be minimum size
+ --
+ -- to left justify and suppress base specification
+ -- to_int_str(x,
+ -- 6,
+ -- justify => left,
+ -- basespec => yes)
+ -- length of return string will be 6 characters
+ -- the base specification will be suppressed
+ -- if x is 10101 then return is 21....
+ -- where '.' represents a blank
+ --
+ -- other usage notes
+ --
+ -- if rtn_len less than or equal to x'length then ignore
+ -- rtn_len and return string of x'length
+ -- the 'justify' parm is effectively ignored in this case
+ --
+ -- if rtn_len greater than x'length then return string
+ -- of rtn_len with blanks based on 'justify' parm
+ --
+ -- these routines do not handle negative numbers
+ ----------------------------------------------------------------------------
+
+ type justify_side is (left, right);
+ type b_spec is (no , yes);
+
+ -- std_logic_vector to binary string
+ function to_bin_str(x : std_logic_vector;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes)
+ return string;
+
+ -- std_logic to binary string
+ function to_bin_str(x : std_logic;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes)
+ return string;
+
+ -- natural to binary string
+ function to_bin_str(x : natural;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes)
+ return string;
+ -- see note above regarding possible formats for x
+
+ -- std_logic_vector to hex string
+ function to_hex_str(x : std_logic_vector;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes)
+ return string;
+
+ -- natural to hex string
+ function to_hex_str(x : natural;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes)
+ return string;
+ -- see note above regarding possible formats for x
+
+ -- std_logic_vector to octal string
+ function to_oct_str(x : std_logic_vector;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes)
+ return string;
+
+ -- natural to octal string
+ function to_oct_str(x : natural;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes)
+ return string;
+ -- see note above regarding possible formats for x
+
+ -- natural to integer string
+ function to_int_str(x : natural;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes)
+ return string;
+ -- see note above regarding possible formats for x
+
+ -- std_logic_vector to integer string
+ function to_int_str(x : std_logic_vector;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes)
+ return string;
+
+ -- time to string
+ function to_time_str (x : time)
+ return string;
+
+ -- add characters to a string
+ function fill (fill_char : character := '*';
+ rtn_len : integer := 1)
+ return string;
+ -- usage:
+ -- fill
+ -- returns *
+ -- fill(' ',10)
+ -- returns .......... when '.' represents a blank
+ -- fill(lf) or fill(ht)
+ -- returns line feed character or tab character respectively
+
+ -- std_logic_vector to natural
+ function to_nat (x : std_logic_vector)
+ return natural;
+
+ -- std_logic to natural
+ function to_nat (x : std_logic)
+ return natural;
+
+ -- time to natural
+ function to_nat (x : time)
+ return natural;
+
+ -- hex string to std_logic_vector
+ function h (x : string;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector;
+ -- if rtn_len is < than x'length*4, result will be truncated on the left
+ -- if x is other than characters 0 to 9 or a,A to f,F
+ -- or x,X,z,Z,u,U,-,w,W, result will be 0
+
+ -- decimal string to std_logic_vector
+ function d (x : string;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector;
+ -- if rtn_len is < than x'length*4, result will be truncated on the left
+ -- if x is other than characters 0 to 9 or x,X,z,Z,u,U,-,w,W,
+ -- result will be 0
+
+ -- octal string to std_logic_vector
+ function o (x : string;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector;
+ -- if rtn_len is < than x'length*4, result will be truncated on the left
+ -- if x is other than characters 0 to 7 or x,X,z,Z,u,U,-,w,W,
+ -- result will be 0
+
+ -- binary string to std_logic_vector
+ function b (x : string;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector;
+ -- if rtn_len is < than x'length*4, result will be truncated on the left
+ -- if x is other than characters 0 to 1 or x,X,z,Z,u,U,-,w,W,
+ -- result will be 0
+
+ -- hex string to natural
+ function h (x : string)
+ return natural;
+ -- if x is other than characters 0 to 9 or a,A to f,F, result will be 0
+
+ -- decimal string to natural
+ function d (x : string)
+ return natural;
+ -- if x is other than characters 0 to 9, result will be 0
+
+ -- octal string to natural
+ function o (x : string)
+ return natural;
+ -- if x is other than characters 0 to 7, result will be 0
+
+ -- binary string to natural
+ function b (x : string)
+ return natural;
+ -- if x is other than characters 0 to 1, result will be 0
+
+ -- natural to std_logic_vector
+ function to_slv (x : natural;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector;
+ -- if rtn_len is < than sizeof(x), result will be truncated on the left
+ -- see note above regarding possible formats for x
+
+ -- integer to std_logic_vector
+ function int_to_slv (x : integer;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector;
+ -- if rtn_len is < than sizeof(x), result will be truncated on the left
+ -- see note above regarding possible formats for x
+
+ -- natural to std_logic
+ function to_sl (x : natural)
+ return std_logic;
+
+ -- natural to time
+ function to_time (x : natural)
+ return time;
+ -- see note above regarding possible formats for x
+
+ -- std_logic_vector to integer
+ function to_int (x : std_logic_vector)
+ return integer;
+
+END conversions;
+--
+--------------------------------------------------------------------------------
+--
+
+PACKAGE BODY conversions IS
+
+ -- private declarations for this package
+ type basetype is (binary, octal, decimal, hex);
+
+ function max(x,y: integer) return integer is
+ begin
+ if x > y then return x; else return y; end if;
+ end max;
+
+ function min(x,y: integer) return integer is
+ begin
+ if x < y then return x; else return y; end if;
+ end min;
+
+ -- consider function sizeof for string/slv/???, return natural
+
+ -- function size(len: natural) return natural is
+ -- begin
+ -- if len=0 then
+ -- return 31;
+ -- else return len;
+ -- end if;
+ -- end size;
+
+ function nextmultof (x : positive;
+ size : positive) return positive is
+ begin
+ case x mod size is
+ when 0 => return size * x/size;
+ when others => return size * (x/size + 1);
+ end case;
+ end nextmultof;
+
+ function rtn_base (base : basetype) return character is
+ begin
+ case base is
+ when binary => return 'b';
+ when octal => return 'o';
+ when decimal => return 'd';
+ when hex => return 'h';
+ end case;
+ end rtn_base;
+
+ function format (r : string;
+ base : basetype;
+ rtn_len : natural ;
+ justify : justify_side;
+ basespec : b_spec) return string is
+ variable int_rtn_len : integer;
+ begin
+ if basespec=yes then
+ int_rtn_len := rtn_len - 3;
+ else
+ int_rtn_len := rtn_len;
+ end if;
+ if int_rtn_len <= r'length then
+ case basespec is
+ when no => return r ;
+ when yes => return rtn_base(base) & '"' & r & '"';
+ end case;
+ else
+ case justify is
+ when left =>
+ case basespec is
+ when no =>
+ return r & fill(' ',int_rtn_len - r'length);
+ when yes =>
+ return rtn_base(base) & '"' & r & '"' &
+ fill(' ',int_rtn_len - r'length);
+ end case;
+ when right =>
+ case basespec is
+ when no =>
+ return fill(' ',int_rtn_len - r'length) & r ;
+ when yes =>
+ return fill(' ',int_rtn_len - r'length) &
+ rtn_base(base) & '"' & r & '"';
+ end case;
+ end case;
+ end if;
+ end format;
+
+ -- convert numeric string of any base to natural
+ function cnvt_base (x : string;
+ inbase : natural range 2 to 16) return natural is
+ -- assumes x is an unsigned number string of base 'inbase'
+ -- values larger than natural'high are not supported
+ variable r,t : natural := 0;
+ variable place : positive := 1;
+ begin
+ for i in x'reverse_range loop
+ case x(i) is
+ when '0' => t := 0;
+ when '1' => t := 1;
+ when '2' => t := 2;
+ when '3' => t := 3;
+ when '4' => t := 4;
+ when '5' => t := 5;
+ when '6' => t := 6;
+ when '7' => t := 7;
+ when '8' => t := 8;
+ when '9' => t := 9;
+ when 'a'|'A' => t := 10;
+ when 'b'|'B' => t := 11;
+ when 'c'|'C' => t := 12;
+ when 'd'|'D' => t := 13;
+ when 'e'|'E' => t := 14;
+ when 'f'|'F' => t := 15;
+ when '_' => t := 0; -- ignore these characters
+ place := place / inbase;
+ when others =>
+ assert false
+ report lf &
+ "CNVT_BASE found input value larger than base: " & lf &
+ "Input value: " & x(i) &
+ " Base: " & to_int_str(inbase) & lf &
+ "converting input to integer 0"
+ severity warning;
+ return 0;
+ end case;
+ if t / inbase > 1 then -- invalid value for base
+ assert false
+ report lf &
+ "CNVT_BASE found input value larger than base: " & lf &
+ "Input value: " & x(i) &
+ " Base: " & to_int_str(inbase) & lf &
+ "converting input to integer 0"
+ severity warning;
+ return 0;
+ else
+ r := r + (t * place);
+ place := place * inbase;
+ end if;
+ end loop;
+ return r;
+ end cnvt_base;
+
+ function extend (x : std_logic;
+ len : positive) return std_logic_vector is
+ variable v : std_logic_vector(1 to len) := (others => x);
+ begin
+ return v;
+ end extend;
+
+
+ -- implementation of public declarations
+
+ function to_bin_str(x : std_logic_vector;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes) return string is
+
+ variable int : std_logic_vector(1 to x'length):=x;
+ variable r : string(1 to x'length):=(others=>'$');
+ begin
+ for i in int'range loop
+ r(i to i) := to_bin_str(int(i),basespec=>no);
+ end loop;
+ return format (r,binary,rtn_len,justify,basespec);
+ end to_bin_str;
+
+ function to_bin_str(x : std_logic;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes) return string is
+ variable r : string(1 to 1);
+ begin
+ case x is
+ when '0' => r(1) := '0';
+ when '1' => r(1) := '1';
+ when 'U' => r(1) := 'U';
+ when 'X' => r(1) := 'X';
+ when 'Z' => r(1) := 'Z';
+ when 'W' => r(1) := 'W';
+ when 'H' => r(1) := 'H';
+ when 'L' => r(1) := 'L';
+ when '-' => r(1) := '-';
+ end case;
+ return format (r,binary,rtn_len,justify,basespec);
+ end to_bin_str;
+
+ function to_bin_str(x : natural;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes) return string is
+ variable int : natural := x;
+ variable ptr : positive range 2 to 32 := 32;
+ variable r : string(2 to 32):=(others=>'$');
+ begin
+ if int = 0 then
+ return format ("0",binary,rtn_len,justify,basespec);
+ end if;
+
+ while int > 0 loop
+ case int rem 2 is
+ when 0 => r(ptr) := '0';
+ when 1 => r(ptr) := '1';
+ when others =>
+ assert false report lf & "TO_BIN_STR, shouldn't happen"
+ severity failure;
+ return "$";
+ null;
+ end case;
+ int := int / 2;
+ ptr := ptr - 1;
+ end loop;
+ return format (r(ptr+1 to 32),binary,rtn_len,justify,basespec);
+ end to_bin_str;
+
+ function to_hex_str(x : std_logic_vector;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes) return string is
+ -- will return x'length/4
+ variable nxt : positive := nextmultof(x'length,4);
+ variable int : std_logic_vector(1 to nxt):= (others => '0');
+ variable ptr : positive range 1 to (nxt/4)+1 := 1;
+ variable r : string(1 to nxt/4):=(others=>'$');
+ subtype slv4 is std_logic_vector(1 to 4);
+ variable slv4_val : slv4;
+ begin
+ int(nxt-x'length+1 to nxt) := x;
+ if nxt-x'length > 0 and x(x'left) /= '1' then
+ int(1 to nxt-x'length) := extend(x(x'left),nxt-x'length);
+ end if;
+ for i in int'range loop
+ next when i rem 4 /= 1;
+ slv4_val := int(i to i+3);
+ case slv4_val is
+ when "0000" => r(ptr) := '0';
+ when "0001" => r(ptr) := '1';
+ when "0010" => r(ptr) := '2';
+ when "0011" => r(ptr) := '3';
+ when "0100" => r(ptr) := '4';
+ when "0101" => r(ptr) := '5';
+ when "0110" => r(ptr) := '6';
+ when "0111" => r(ptr) := '7';
+ when "1000" => r(ptr) := '8';
+ when "1001" => r(ptr) := '9';
+ when "1010" => r(ptr) := 'A';
+ when "1011" => r(ptr) := 'B';
+ when "1100" => r(ptr) := 'C';
+ when "1101" => r(ptr) := 'D';
+ when "1110" => r(ptr) := 'E';
+ when "1111" => r(ptr) := 'F';
+ when "ZZZZ" => r(ptr) := 'Z';
+ when "WWWW" => r(ptr) := 'W';
+ when "LLLL" => r(ptr) := 'L';
+ when "HHHH" => r(ptr) := 'H';
+ when "UUUU" => r(ptr) := 'U';
+ when "XXXX" => r(ptr) := 'X';
+ when "----" => r(ptr) := '-';
+ when others =>
+ assert false
+ report lf &
+ "TO_HEX_STR found illegal value: " &
+ to_bin_str(int(i to i+3)) & lf &
+ "converting input to '-'"
+ severity warning;
+ r(ptr) := '-';
+ end case;
+ ptr := ptr + 1;
+ end loop;
+ return format (r,hex,rtn_len,justify,basespec);
+ end to_hex_str;
+
+ function to_hex_str(x : natural;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes) return string is
+ variable int : natural := x;
+ variable ptr : positive range 1 to 20 := 20;
+ variable r : string(1 to 20):=(others=>'$');
+ begin
+ if x=0 then return format ("0",hex,rtn_len,justify,basespec); end if;
+ while int > 0 loop
+ case int rem 16 is
+ when 0 => r(ptr) := '0';
+ when 1 => r(ptr) := '1';
+ when 2 => r(ptr) := '2';
+ when 3 => r(ptr) := '3';
+ when 4 => r(ptr) := '4';
+ when 5 => r(ptr) := '5';
+ when 6 => r(ptr) := '6';
+ when 7 => r(ptr) := '7';
+ when 8 => r(ptr) := '8';
+ when 9 => r(ptr) := '9';
+ when 10 => r(ptr) := 'A';
+ when 11 => r(ptr) := 'B';
+ when 12 => r(ptr) := 'C';
+ when 13 => r(ptr) := 'D';
+ when 14 => r(ptr) := 'E';
+ when 15 => r(ptr) := 'F';
+ when others =>
+ assert false report lf & "TO_HEX_STR, shouldn't happen"
+ severity failure;
+ return "$";
+ end case;
+ int := int / 16;
+ ptr := ptr - 1;
+ end loop;
+ return format (r(ptr+1 to 20),hex,rtn_len,justify,basespec);
+ end to_hex_str;
+
+ function to_oct_str(x : std_logic_vector;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes) return string is
+ -- will return x'length/3
+ variable nxt : positive := nextmultof(x'length,3);
+ variable int : std_logic_vector(1 to nxt):= (others => '0');
+ variable ptr : positive range 1 to (nxt/3)+1 := 1;
+ variable r : string(1 to nxt/3):=(others=>'$');
+ subtype slv3 is std_logic_vector(1 to 3);
+ begin
+ int(nxt-x'length+1 to nxt) := x;
+ if nxt-x'length > 0 and x(x'left) /= '1' then
+ int(1 to nxt-x'length) := extend(x(x'left),nxt-x'length);
+ end if;
+ for i in int'range loop
+ next when i rem 3 /= 1;
+ case slv3'(int(i to i+2)) is
+ when "000" => r(ptr) := '0';
+ when "001" => r(ptr) := '1';
+ when "010" => r(ptr) := '2';
+ when "011" => r(ptr) := '3';
+ when "100" => r(ptr) := '4';
+ when "101" => r(ptr) := '5';
+ when "110" => r(ptr) := '6';
+ when "111" => r(ptr) := '7';
+ when "ZZZ" => r(ptr) := 'Z';
+ when "WWW" => r(ptr) := 'W';
+ when "LLL" => r(ptr) := 'L';
+ when "HHH" => r(ptr) := 'H';
+ when "UUU" => r(ptr) := 'U';
+ when "XXX" => r(ptr) := 'X';
+ when "---" => r(ptr) := '-';
+ when others =>
+ assert false
+ report lf &
+ "TO_OCT_STR found illegal value: " &
+ to_bin_str(int(i to i+2)) & lf &
+ "converting input to '-'"
+ severity warning;
+ r(ptr) := '-';
+ end case;
+ ptr := ptr + 1;
+ end loop;
+ return format (r,octal,rtn_len,justify,basespec);
+ end to_oct_str;
+
+ function to_oct_str(x : natural;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes) return string is
+ variable int : natural := x;
+ variable ptr : positive range 1 to 20 := 20;
+ variable r : string(1 to 20):=(others=>'$');
+ begin
+ if x=0 then return format ("0",octal,rtn_len,justify,basespec); end if;
+ while int > 0 loop
+ case int rem 8 is
+ when 0 => r(ptr) := '0';
+ when 1 => r(ptr) := '1';
+ when 2 => r(ptr) := '2';
+ when 3 => r(ptr) := '3';
+ when 4 => r(ptr) := '4';
+ when 5 => r(ptr) := '5';
+ when 6 => r(ptr) := '6';
+ when 7 => r(ptr) := '7';
+ when others =>
+ assert false report lf & "TO_OCT_STR, shouldn't happen"
+ severity failure;
+ return "$";
+ end case;
+ int := int / 8;
+ ptr := ptr - 1;
+ end loop;
+ return format (r(ptr+1 to 20),octal,rtn_len,justify,basespec);
+ end to_oct_str;
+
+ function to_int_str(x : natural;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes) return string is
+ variable int : natural := x;
+ variable ptr : positive range 1 to 32 := 32;
+ variable r : string(1 to 32):=(others=>'$');
+ begin
+ if x=0 then return format ("0",decimal,rtn_len,justify,basespec);
+ else
+ while int > 0 loop
+ case int rem 10 is
+ when 0 => r(ptr) := '0';
+ when 1 => r(ptr) := '1';
+ when 2 => r(ptr) := '2';
+ when 3 => r(ptr) := '3';
+ when 4 => r(ptr) := '4';
+ when 5 => r(ptr) := '5';
+ when 6 => r(ptr) := '6';
+ when 7 => r(ptr) := '7';
+ when 8 => r(ptr) := '8';
+ when 9 => r(ptr) := '9';
+ when others =>
+ assert false report lf & "TO_INT_STR, shouldn't happen"
+ severity failure;
+ return "$";
+ end case;
+ int := int / 10;
+ ptr := ptr - 1;
+ end loop;
+ return format (r(ptr+1 to 32),decimal,rtn_len,justify,basespec);
+ end if;
+ end to_int_str;
+
+ function to_int_str(x : std_logic_vector;
+ rtn_len : natural := 0;
+ justify : justify_side := right;
+ basespec : b_spec := yes)
+ return string is
+ begin
+ return to_int_str(to_nat(x),rtn_len,justify,basespec);
+ end to_int_str;
+
+
+ function to_time_str (x : time)
+ return string is
+ begin
+ return to_int_str(to_nat(x),basespec=>no) & " ns";
+ end to_time_str;
+
+ function fill (fill_char : character := '*';
+ rtn_len : integer := 1)
+ return string is
+ variable r : string(1 to max(rtn_len,1)) := (others => fill_char);
+ variable len : integer;
+ begin
+ if rtn_len < 2 then -- always returns at least 1 fill char
+ len := 1;
+ else
+ len := rtn_len;
+ end if;
+ return r(1 to len);
+ end fill;
+
+ function to_nat(x : std_logic_vector) return natural is
+ -- assumes x is an unsigned number, lsb on right,
+ -- more than 31 bits are truncated on left
+ variable t : std_logic_vector(1 to x'length) := x;
+ variable int : std_logic_vector(1 to 31) := (others => '0');
+ variable r : natural := 0;
+ variable place : positive := 1;
+ begin
+ if x'length < 32 then
+ int(max(32-x'length,1) to 31) := t(1 to x'length);
+ else -- x'length >= 32
+ int(1 to 31) := t(x'length-30 to x'length);
+ end if;
+ for i in int'reverse_range loop
+ case int(i) is
+ when '1' | 'H' => r := r + place;
+ when '0' | 'L' => null;
+ when others =>
+ assert false
+ report lf &
+ "TO_NAT found illegal value: " & to_bin_str(int(i)) & lf &
+ "converting input to integer 0"
+ severity warning;
+ return 0;
+ end case;
+ exit when i=1;
+ place := place * 2;
+ end loop;
+ return r;
+ end to_nat;
+
+ function to_nat (x : std_logic)
+ return natural is
+ begin
+ case x is
+ when '0' => return 0 ;
+ when '1' => return 1 ;
+ when others =>
+ assert false
+ report lf &
+ "TO_NAT found illegal value: " & to_bin_str(x) & lf &
+ "converting input to integer 0"
+ severity warning;
+ return 0;
+ end case;
+ end to_nat;
+
+ function to_nat (x : time)
+ return natural is
+ begin
+ return x / 1 ns;
+ end to_nat;
+
+ function h(x : string;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector is
+ -- if rtn_len is < than x'length*4, result will be truncated on the left
+ -- if x is other than characters 0 to 9 or a,A to f,F or
+ -- x,X,z,Z,u,U,-,w,W,
+ -- those result bits will be set to 0
+ variable int : string(1 to x'length) := x;
+ variable size: positive := max(x'length*4,rtn_len);
+ variable ptr : integer range -3 to size := size;
+ variable r : std_logic_vector(1 to size) := (others=>'0');
+ begin
+ for i in int'reverse_range loop
+ case int(i) is
+ when '0' => r(ptr-3 to ptr) := "0000";
+ when '1' => r(ptr-3 to ptr) := "0001";
+ when '2' => r(ptr-3 to ptr) := "0010";
+ when '3' => r(ptr-3 to ptr) := "0011";
+ when '4' => r(ptr-3 to ptr) := "0100";
+ when '5' => r(ptr-3 to ptr) := "0101";
+ when '6' => r(ptr-3 to ptr) := "0110";
+ when '7' => r(ptr-3 to ptr) := "0111";
+ when '8' => r(ptr-3 to ptr) := "1000";
+ when '9' => r(ptr-3 to ptr) := "1001";
+ when 'a'|'A' => r(ptr-3 to ptr) := "1010";
+ when 'b'|'B' => r(ptr-3 to ptr) := "1011";
+ when 'c'|'C' => r(ptr-3 to ptr) := "1100";
+ when 'd'|'D' => r(ptr-3 to ptr) := "1101";
+ when 'e'|'E' => r(ptr-3 to ptr) := "1110";
+ when 'f'|'F' => r(ptr-3 to ptr) := "1111";
+ when 'U' => r(ptr-3 to ptr) := "UUUU";
+ when 'X' => r(ptr-3 to ptr) := "XXXX";
+ when 'Z' => r(ptr-3 to ptr) := "ZZZZ";
+ when 'W' => r(ptr-3 to ptr) := "WWWW";
+ when 'H' => r(ptr-3 to ptr) := "HHHH";
+ when 'L' => r(ptr-3 to ptr) := "LLLL";
+ when '-' => r(ptr-3 to ptr) := "----";
+ when '_' => ptr := ptr + 4;
+ when others =>
+ assert false
+ report lf &
+ "O conversion found illegal input character: " &
+ int(i) & lf & "converting character to '----'"
+ severity warning;
+ r(ptr-3 to ptr) := "----";
+ end case;
+ ptr := ptr - 4;
+ end loop;
+ return r(size-rtn_len+1 to size);
+ end h;
+
+ function d (x : string;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector is
+ -- if rtn_len is < than binary length of x, result will be truncated on
+ -- the left
+ -- if x is other than characters 0 to 9, result will be 0
+ begin
+ return to_slv(cnvt_base(x,10),rtn_len);
+ end d;
+
+ function o (x : string;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector is
+ -- if rtn_len is < than x'length*3, result will be truncated on the left
+ -- if x is other than characters 0 to 7 or or x,X,z,Z,u,U,-,w,W,
+ -- those result bits will be set to 0
+ variable int : string(1 to x'length) := x;
+ variable size: positive := max(x'length*3,rtn_len);
+ variable ptr : integer range -2 to size := size;
+ variable r : std_logic_vector(1 to size) := (others=>'0');
+ begin
+ for i in int'reverse_range loop
+ case int(i) is
+ when '0' => r(ptr-2 to ptr) := "000";
+ when '1' => r(ptr-2 to ptr) := "001";
+ when '2' => r(ptr-2 to ptr) := "010";
+ when '3' => r(ptr-2 to ptr) := "011";
+ when '4' => r(ptr-2 to ptr) := "100";
+ when '5' => r(ptr-2 to ptr) := "101";
+ when '6' => r(ptr-2 to ptr) := "110";
+ when '7' => r(ptr-2 to ptr) := "111";
+ when 'U' => r(ptr-2 to ptr) := "UUU";
+ when 'X' => r(ptr-2 to ptr) := "XXX";
+ when 'Z' => r(ptr-2 to ptr) := "ZZZ";
+ when 'W' => r(ptr-2 to ptr) := "WWW";
+ when 'H' => r(ptr-2 to ptr) := "HHH";
+ when 'L' => r(ptr-2 to ptr) := "LLL";
+ when '-' => r(ptr-2 to ptr) := "---";
+ when '_' => ptr := ptr + 3;
+ when others =>
+ assert false
+ report lf &
+ "O conversion found illegal input character: " &
+ int(i) & lf & "converting character to '---'"
+ severity warning;
+ r(ptr-2 to ptr) := "---";
+ end case;
+ ptr := ptr - 3;
+ end loop;
+ return r(size-rtn_len+1 to size);
+ end o;
+
+ function b (x : string;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector is
+ -- if rtn_len is < than x'length, result will be truncated on the left
+ -- if x is other than characters 0 to 1 or x,X,z,Z,u,U,-,w,W,
+ -- those result bits will be set to 0
+ variable int : string(1 to x'length) := x;
+ variable size: positive := max(x'length,rtn_len);
+ variable ptr : integer range 0 to size+1 := size; -- csa
+ variable r : std_logic_vector(1 to size) := (others=>'0');
+ begin
+ for i in int'reverse_range loop
+ case int(i) is
+ when '0' => r(ptr) := '0';
+ when '1' => r(ptr) := '1';
+ when 'U' => r(ptr) := 'U';
+ when 'X' => r(ptr) := 'X';
+ when 'Z' => r(ptr) := 'Z';
+ when 'W' => r(ptr) := 'W';
+ when 'H' => r(ptr) := 'H';
+ when 'L' => r(ptr) := 'L';
+ when '-' => r(ptr) := '-';
+ when '_' => ptr := ptr + 1;
+ when others =>
+ assert false
+ report lf &
+ "B conversion found illegal input character: " &
+ int(i) & lf & "converting character to '-'"
+ severity warning;
+ r(ptr) := '-';
+ end case;
+ ptr := ptr - 1;
+ end loop;
+ return r(size-rtn_len+1 to size);
+ end b;
+
+ function h (x : string)
+ return natural is
+ -- only following characters are allowed, otherwise result will be 0
+ -- 0 to 9
+ -- a,A to f,F
+ -- blanks, underscore
+ begin
+ return cnvt_base(x,16);
+ end h;
+
+ function d (x : string)
+ return natural is
+ -- only following characters are allowed, otherwise result will be 0
+ -- 0 to 9
+ -- blanks, underscore
+ begin
+ return cnvt_base(x,10);
+ end d;
+
+ function o (x : string)
+ return natural is
+ -- only following characters are allowed, otherwise result will be 0
+ -- 0 to 7
+ -- blanks, underscore
+ begin
+ return cnvt_base(x,8);
+ end o;
+
+ function b (x : string)
+ return natural is
+ -- only following characters are allowed, otherwise result will be 0
+ -- 0 to 1
+ -- blanks, underscore
+ begin
+ return cnvt_base(x,2);
+ end b;
+
+ function to_slv(x : natural;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector is
+ -- if rtn_len is < than sizeof(x), result will be truncated on the left
+ variable int : natural := x;
+ variable ptr : positive := 32;
+ variable r : std_logic_vector(1 to 32) := (others=>'0');
+ begin
+ while int > 0 loop
+ case int rem 2 is
+ when 0 => r(ptr) := '0';
+ when 1 => r(ptr) := '1';
+ when others =>
+ assert false report lf & "TO_SLV, shouldn't happen"
+ severity failure;
+ return "0";
+ end case;
+ int := int / 2;
+ ptr := ptr - 1;
+ end loop;
+ return r(33-rtn_len to 32);
+ end to_slv;
+
+ function to_sl(x : natural)
+ return std_logic is
+ variable r : std_logic := '0';
+ begin
+ case x is
+ when 0 => null;
+ when 1 => r := '1';
+ when others =>
+ assert false
+ report lf &
+ "TO_SL found illegal input character: " &
+ to_int_str(x) & lf & "converting character to '-'"
+ severity warning;
+ return '-';
+ end case;
+ return r;
+ end to_sl;
+
+ function int_to_slv(x : integer;
+ rtn_len : positive range 1 to 32 := 32)
+ return std_logic_vector is
+ -- if rtn_len is < than sizeof(x), result will be truncated on the left
+ variable int : integer := x;
+ variable ptr : positive := 32;
+ variable r : std_logic_vector(1 to 32) := (others=>'0');
+ begin
+ if int >= 0 or int = 0 then
+ while int > 0 loop
+ case int rem 2 is
+ when 0 => r(ptr) := '0';
+ when 1 => r(ptr) := '1';
+ when others =>
+ assert false report lf & " shouldn't happen"
+ severity failure;
+ return "0";
+ end case;
+ int := int / 2;
+ ptr := ptr - 1;
+ end loop;
+ return r(33-rtn_len to 32);
+ else
+ int := 2**(rtn_len - 1) + int;
+ while int > 0 loop
+ case int rem 2 is
+ when 0 => r(ptr) := '0';
+ when 1 => r(ptr) := '1';
+ when others =>
+ assert false report lf & " shouldn't happen"
+ severity failure;
+ return "0";
+ end case;
+ int := int / 2;
+ ptr := ptr - 1;
+ end loop;
+ r(33-rtn_len) := '1';
+ return r(33-rtn_len to 32);
+ end if;
+ end int_to_slv;
+
+ function to_time (x: natural) return time is
+ begin
+ return x * 1 ns;
+ end to_time;
+
+ function to_int(x : std_logic_vector) return integer is
+ -- assumes x is an signed number
+ -- more than 32 bits are truncated on left
+ variable t : std_logic_vector(x'length downto 1) := x;
+ variable int : std_logic_vector(32 downto 1) := (others => '0');
+ variable sign : std_logic := '0';
+ variable size : integer := 0;
+ variable inv : boolean := false;
+ variable r : integer := 0;
+ variable place : positive := 1;
+ begin
+ if x'length < 33 then
+ sign := t(x'length);
+ for i in t'reverse_range loop
+ if sign = '1' then
+ if inv = true then
+ t(i) := not(t(i));
+ elsif t(i) = '1' then
+ inv := true;
+ end if;
+ end if;
+ size := size +1;
+ end loop;
+ inv := false;
+ for i in 1 to size - 1 loop
+ case t(i) is
+ when '1' | 'H' => r := r + place;
+ when '0' | 'L' => null;
+ when others =>
+ assert false
+ report lf &
+ " TO_INT found illegal value "
+ severity warning;
+ return 0;
+ end case;
+ place := place * 2;
+ end loop;
+ if sign = '1' THEN
+ return (- r);
+ else
+ return r;
+ end if;
+ else -- x'length >= 33
+ int := t(32 downto 1);
+ sign := t(32);
+ for i in 1 to 31 loop
+ if sign = '1' then
+ if inv = true then
+ int(i) := not(int(i));
+ elsif int(i) = '1' then
+ inv := true;
+ end if;
+ end if;
+ end loop;
+ inv := false;
+ for i in 1 to 31 loop
+ case int(i) is
+ when '1' | 'H' => r := r + place;
+ when '0' | 'L' => null;
+ when others =>
+ assert false
+ report lf &
+ " TO_INT found illegal value "
+ severity warning;
+ return 0;
+ end case;
+ place := place * 2;
+ end loop;
+ if sign = '1' THEN
+ return (- r);
+ else
+ return r;
+ end if;
+ end if;
+ end to_int;
+
+END conversions;