Library of reusable VHDL components
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

407 lines
14 KiB

--
-- File Name: TextUtilPkg.vhd
-- Design Unit Name: TextUtilPkg
-- Revision: STANDARD VERSION
--
-- Maintainer: Jim Lewis email: jim@synthworks.com
-- Contributor(s):
-- Jim Lewis jim@synthworks.com
--
--
-- Description:
-- Shared Utilities for handling text files
--
--
-- Developed for:
-- SynthWorks Design Inc.
-- VHDL Training Classes
-- 11898 SW 128th Ave. Tigard, Or 97223
-- http://www.SynthWorks.com
--
-- Revision History:
-- Date Version Description
-- 01/2015: 2015.05 Initial revision
-- 01/2016: 2016.01 Update for L.all(L'left)
-- 11/2016: 2016.11 Added IsUpper, IsLower, to_upper, to_lower
--
--
-- Copyright (c) 2015-2016 by SynthWorks Design Inc. All rights reserved.
--
-- Verbatim copies of this source file may be used and
-- distributed without restriction.
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the ARTISTIC License
-- as published by The Perl Foundation; either version 2.0 of
-- the License, or (at your option) any later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the Artistic License for details.
--
-- You should have received a copy of the license with this source.
-- If not download it from,
-- http://www.perlfoundation.org/artistic_license_2_0
--
use std.textio.all ;
library ieee ;
use ieee.std_logic_1164.all ;
package TextUtilPkg is
------------------------------------------------------------
function IsUpper (constant Char : character ) return boolean ;
function IsLower (constant Char : character ) return boolean ;
function to_lower (constant Char : character ) return character ;
function to_lower (constant Str : string ) return string ;
function to_upper (constant Char : character ) return character ;
function to_upper (constant Str : string ) return string ;
function ishex (constant Char : character ) return boolean ;
function isstd_logic (constant Char : character ) return boolean ;
------------------------------------------------------------
procedure SkipWhiteSpace (
------------------------------------------------------------
variable L : InOut line ;
variable Empty : out boolean
) ;
procedure SkipWhiteSpace (variable L : InOut line) ;
------------------------------------------------------------
procedure EmptyOrCommentLine (
------------------------------------------------------------
variable L : InOut line ;
variable Empty : InOut boolean ;
variable MultiLineComment : inout boolean
) ;
------------------------------------------------------------
procedure ReadHexToken (
-- Reads Upto Result'length values, less is ok.
-- Does not skip white space
------------------------------------------------------------
variable L : InOut line ;
variable Result : Out std_logic_vector ;
variable StrLen : Out integer
) ;
------------------------------------------------------------
procedure ReadBinaryToken (
-- Reads Upto Result'length values, less is ok.
-- Does not skip white space
------------------------------------------------------------
variable L : InOut line ;
variable Result : Out std_logic_vector ;
variable StrLen : Out integer
) ;
end TextUtilPkg ;
--- ///////////////////////////////////////////////////////////////////////////
--- ///////////////////////////////////////////////////////////////////////////
--- ///////////////////////////////////////////////////////////////////////////
package body TextUtilPkg is
constant LOWER_TO_UPPER_OFFSET : integer := character'POS('a') - character'POS('A') ;
------------------------------------------------------------
function "-" (R : character ; L : integer ) return character is
------------------------------------------------------------
begin
return character'VAL(character'pos(R) - L) ;
end function "-" ;
------------------------------------------------------------
function "+" (R : character ; L : integer ) return character is
------------------------------------------------------------
begin
return character'VAL(character'pos(R) + L) ;
end function "+" ;
------------------------------------------------------------
function IsUpper (constant Char : character ) return boolean is
------------------------------------------------------------
begin
if Char >= 'A' and Char <= 'Z' then
return TRUE ;
else
return FALSE ;
end if ;
end function IsUpper ;
------------------------------------------------------------
function IsLower (constant Char : character ) return boolean is
------------------------------------------------------------
begin
if Char >= 'a' and Char <= 'z' then
return TRUE ;
else
return FALSE ;
end if ;
end function IsLower ;
------------------------------------------------------------
function to_lower (constant Char : character ) return character is
------------------------------------------------------------
begin
if IsUpper(Char) then
return Char + LOWER_TO_UPPER_OFFSET ;
else
return Char ;
end if ;
end function to_lower ;
------------------------------------------------------------
function to_lower (constant Str : string ) return string is
------------------------------------------------------------
variable result : string(Str'range) ;
begin
for i in Str'range loop
result(i) := to_lower(Str(i)) ;
end loop ;
return result ;
end function to_lower ;
------------------------------------------------------------
function to_upper (constant Char : character ) return character is
------------------------------------------------------------
begin
if IsLower(Char) then
return Char - LOWER_TO_UPPER_OFFSET ;
else
return Char ;
end if ;
end function to_upper ;
------------------------------------------------------------
function to_upper (constant Str : string ) return string is
------------------------------------------------------------
variable result : string(Str'range) ;
begin
for i in Str'range loop
result(i) := to_upper(Str(i)) ;
end loop ;
return result ;
end function to_upper ;
------------------------------------------------------------
function ishex (constant Char : character ) return boolean is
------------------------------------------------------------
begin
if Char >= '0' and Char <= '9' then
return TRUE ;
elsif Char >= 'a' and Char <= 'f' then
return TRUE ;
elsif Char >= 'A' and Char <= 'F' then
return TRUE ;
else
return FALSE ;
end if ;
end function ishex ;
------------------------------------------------------------
function isstd_logic (constant Char : character ) return boolean is
------------------------------------------------------------
begin
case Char is
when 'U' | 'X' | '0' | '1' | 'Z' | 'W' | 'L' | 'H' | '-' =>
return TRUE ;
when others =>
return FALSE ;
end case ;
end function isstd_logic ;
-- ------------------------------------------------------------
-- function iscomment (constant Char : character ) return boolean is
-- ------------------------------------------------------------
-- begin
-- case Char is
-- when '#' | '/' | '-' =>
-- return TRUE ;
-- when others =>
-- return FALSE ;
-- end case ;
-- end function iscomment ;
------------------------------------------------------------
procedure SkipWhiteSpace (
------------------------------------------------------------
variable L : InOut line ;
variable Empty : out boolean
) is
variable Valid : boolean ;
variable Char : character ;
constant NBSP : CHARACTER := CHARACTER'val(160); -- space character
begin
Empty := TRUE ;
WhiteSpLoop : while L /= null and L.all'length > 0 loop
if (L.all(L'left) = ' ' or L.all(L'left) = NBSP or L.all(L'left) = HT) then
read (L, Char, Valid) ;
exit when not Valid ;
else
Empty := FALSE ;
return ;
end if ;
end loop WhiteSpLoop ;
end procedure SkipWhiteSpace ;
------------------------------------------------------------
procedure SkipWhiteSpace (
------------------------------------------------------------
variable L : InOut line
) is
variable Empty : boolean ;
begin
SkipWhiteSpace(L, Empty) ;
end procedure SkipWhiteSpace ;
------------------------------------------------------------
-- Package Local
procedure FindCommentEnd (
------------------------------------------------------------
variable L : InOut line ;
variable Empty : out boolean ;
variable MultiLineComment : inout boolean
) is
variable Valid : boolean ;
variable Char : character ;
begin
MultiLineComment := TRUE ;
Empty := TRUE ;
FindEndOfCommentLoop : while L /= null and L.all'length > 1 loop
read(L, Char, Valid) ;
if Char = '*' and L.all(L'left) = '/' then
read(L, Char, Valid) ;
Empty := FALSE ;
MultiLineComment := FALSE ;
exit FindEndOfCommentLoop ;
end if ;
end loop ;
end procedure FindCommentEnd ;
------------------------------------------------------------
procedure EmptyOrCommentLine (
------------------------------------------------------------
variable L : InOut line ;
variable Empty : InOut boolean ;
variable MultiLineComment : inout boolean
) is
variable Valid : boolean ;
variable Next2Char : string(1 to 2) ;
constant NBSP : CHARACTER := CHARACTER'val(160); -- space character
begin
if MultiLineComment then
FindCommentEnd(L, Empty, MultiLineComment) ;
end if ;
EmptyCheckLoop : while not MultiLineComment loop
SkipWhiteSpace(L, Empty) ;
exit when Empty ; -- line null or 0 in length detected by SkipWhite
Empty := TRUE ;
exit when L.all(L'left) = '#' ; -- shell style comment
if L.all'length >= 2 then
if L'ascending then
Next2Char := L.all(L'left to L'left+1) ;
else
Next2Char := L.all(L'left to L'left-1) ;
end if;
exit when Next2Char = "//" ; -- C style comment
exit when Next2Char = "--" ; -- VHDL style comment
if Next2Char = "/*" then -- C style multi line comment
FindCommentEnd(L, Empty, MultiLineComment) ;
exit when Empty ;
next EmptyCheckLoop ; -- Found end of comment, restart processing line
end if ;
end if ;
Empty := FALSE ;
exit ;
end loop EmptyCheckLoop ;
end procedure EmptyOrCommentLine ;
------------------------------------------------------------
procedure ReadHexToken (
-- Reads Upto Result'length values, less is ok.
-- Does not skip white space
------------------------------------------------------------
variable L : InOut line ;
variable Result : Out std_logic_vector ;
variable StrLen : Out integer
) is
constant NumHexChars : integer := (Result'length+3)/4 ;
constant ResultNormLen : integer := NumHexChars * 4 ;
variable NextChar : character ;
variable CharCount : integer ;
variable ReturnVal : std_logic_vector(ResultNormLen-1 downto 0) ;
variable ReadVal : std_logic_vector(3 downto 0) ;
variable ReadValid : boolean ;
begin
ReturnVal := (others => '0') ;
CharCount := 0 ;
ReadLoop : while L /= null and L.all'length > 0 loop
NextChar := L.all(L'left) ;
if ishex(NextChar) or NextChar = 'X' or NextChar = 'Z' then
hread(L, ReadVal, ReadValid) ;
ReturnVal := ReturnVal(ResultNormLen-5 downto 0) & ReadVal ;
CharCount := CharCount + 1 ;
exit ReadLoop when CharCount >= NumHexChars ;
elsif NextChar = '_' then
read(L, NextChar, ReadValid) ;
else
exit ;
end if ;
end loop ReadLoop ;
if CharCount >= NumHexChars then
StrLen := Result'length ;
else
StrLen := CharCount * 4 ;
end if ;
Result := ReturnVal(Result'length-1 downto 0) ;
end procedure ReadHexToken ;
------------------------------------------------------------
procedure ReadBinaryToken (
-- Reads Upto Result'length values, less is ok.
-- Does not skip white space
------------------------------------------------------------
variable L : InOut line ;
variable Result : Out std_logic_vector ;
variable StrLen : Out integer
) is
variable NextChar : character ;
variable CharCount : integer ;
variable ReadVal : std_logic ;
variable ReturnVal : std_logic_vector(Result'length-1 downto 0) ;
variable ReadValid : boolean ;
begin
ReturnVal := (others => '0') ;
CharCount := 0 ;
ReadLoop : while L /= null and L.all'length > 0 loop
NextChar := L.all(L'left) ;
if isstd_logic(NextChar) then
read(L, ReadVal, ReadValid) ;
ReturnVal := ReturnVal(Result'length-2 downto 0) & ReadVal ;
CharCount := CharCount + 1 ;
exit ReadLoop when CharCount >= Result'length ;
elsif NextChar = '_' then
read(L, NextChar, ReadValid) ;
else
exit ;
end if ;
end loop ReadLoop ;
StrLen := CharCount ;
Result := ReturnVal ;
end procedure ReadBinaryToken ;
end package body TextUtilPkg ;