From 4341334801df81f31bcca25ab4840be2f8c95c22 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Tue, 7 Sep 2021 21:15:44 +0200 Subject: testsuite/gna: add a test for #795 --- testsuite/gna/issue795/ex.vhdl | 71 ++++++++++ testsuite/gna/issue795/file_reader_pkg.vhdl | 205 ++++++++++++++++++++++++++++ testsuite/gna/issue795/input.txt | 1 + testsuite/gna/issue795/repro.vhdl | 18 +++ testsuite/gna/issue795/repro2.vhdl | 19 +++ testsuite/gna/issue795/tb_ex.vhdl | 30 ++++ testsuite/gna/issue795/testsuite.sh | 16 +++ 7 files changed, 360 insertions(+) create mode 100644 testsuite/gna/issue795/ex.vhdl create mode 100644 testsuite/gna/issue795/file_reader_pkg.vhdl create mode 100644 testsuite/gna/issue795/input.txt create mode 100644 testsuite/gna/issue795/repro.vhdl create mode 100644 testsuite/gna/issue795/repro2.vhdl create mode 100644 testsuite/gna/issue795/tb_ex.vhdl create mode 100755 testsuite/gna/issue795/testsuite.sh (limited to 'testsuite') diff --git a/testsuite/gna/issue795/ex.vhdl b/testsuite/gna/issue795/ex.vhdl new file mode 100644 index 000000000..4a8654ff5 --- /dev/null +++ b/testsuite/gna/issue795/ex.vhdl @@ -0,0 +1,71 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.csv_file_reader_pkg.all; +-- csv file should be in format +-- sync period,v1hexvalue,v2integervalue,v3hexvalue,comment +-- eg 123445,AD45,234,F00D,"test line, for crash example" +-- +entity crashExample is + port ( + vctrFlNm : in string; + fEnd : out boolean; + syncCount : out integer; + syncPulse : out std_logic; + v1 : out std_logic_vector(15 downto 0); + v2 : out std_logic_vector(15 downto 0); + v3 : out std_logic_vector(15 downto 0); + vctrCmt : out string + ); +end entity crashExample; + +architecture BEHAVIORAL of crashExample is + signal commentString : string(1 to LINE_LENGTH_MAX); + signal syncCntInt : integer; + constant SYN_PLSE_PRD : time := 4000 ns; +begin + + -- comment map + vctrCmt <= commentString; + + -- Vector Process + prcs_VctrRead : process + variable csv : csv_file_reader_type; + variable syncPeriod : time; + begin + -- initialse end flag + fEnd <= false; + -- open file + csv.initialize(vctrFlNm); + -- read first line of file which should be a comment + csv.readline; + -- initalise variables/signals + syncCntInt <= 0; + -- while (not end of file) + while not csv.end_of_file loop + -- read information until next SYN command is found + csv.readline; + -- read Sync period + syncPeriod := csv.read_integer * 1 ns; + -- read Hex integer + v1 <= std_logic_vector(to_unsigned(csv.read_hex, v1'length)); + -- read normal integer + v2 <= std_logic_vector(to_unsigned(csv.read_integer, v2'length)); + -- read Hex integer + v3 <= std_logic_vector(to_unsigned(csv.read_hex, v3'length)); + -- read String comment + commentString <= csv.read_string; + -- Make sync pulse + syncPulse <= '1'; + syncCount <= syncCntInt; + wait for SYN_PLSE_PRD; + syncPulse <= '0'; + -- wait for the sync period + wait for (syncPeriod - SYN_PLSE_PRD); + syncCntInt <= syncCntInt + 1; + end loop; + fEnd <= true; + wait; -- end simulation + end process prcs_VctrRead; + +end BEHAVIORAL; diff --git a/testsuite/gna/issue795/file_reader_pkg.vhdl b/testsuite/gna/issue795/file_reader_pkg.vhdl new file mode 100644 index 000000000..99e167ac9 --- /dev/null +++ b/testsuite/gna/issue795/file_reader_pkg.vhdl @@ -0,0 +1,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; + diff --git a/testsuite/gna/issue795/input.txt b/testsuite/gna/issue795/input.txt new file mode 100644 index 000000000..941af9634 --- /dev/null +++ b/testsuite/gna/issue795/input.txt @@ -0,0 +1 @@ +123445,AD45,234,F00D,"test line, for crash example" diff --git a/testsuite/gna/issue795/repro.vhdl b/testsuite/gna/issue795/repro.vhdl new file mode 100644 index 000000000..6802184eb --- /dev/null +++ b/testsuite/gna/issue795/repro.vhdl @@ -0,0 +1,18 @@ +entity repro1 is + port (p : string); +end repro1; + +architecture behav of repro1 is +begin + assert p = "hello" severity failure; +end behav; + +entity repro is + generic (g : string := "hello"); +end repro; + +architecture behav of repro is +begin + + comp : entity work.repro1 port map (p => g); +end behav; diff --git a/testsuite/gna/issue795/repro2.vhdl b/testsuite/gna/issue795/repro2.vhdl new file mode 100644 index 000000000..8bdc8097f --- /dev/null +++ b/testsuite/gna/issue795/repro2.vhdl @@ -0,0 +1,19 @@ +entity repro2s is + generic (g : string := "hello"); + port (p : string := g); +end repro2s; + +architecture behav of repro2s is +begin + assert p = "hello" severity failure; +end behav; + +entity repro2 is + generic (g : string := "hello"); +end repro2; + +architecture behav of repro2 is +begin + + comp : entity work.repro2s port map (p => open); +end behav; diff --git a/testsuite/gna/issue795/tb_ex.vhdl b/testsuite/gna/issue795/tb_ex.vhdl new file mode 100644 index 000000000..2e0f694c7 --- /dev/null +++ b/testsuite/gna/issue795/tb_ex.vhdl @@ -0,0 +1,30 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.all; +entity tbCrashExample2 is + generic ( + vectorFilename : string + ); +end entity tbCrashExample2; + +architecture BEHAVORIAL of tbCrashExample2 is + --! General Simulation variables/signals + signal fVctrEnd : boolean; --! Flag from vector reader to indicate file end + signal vctrCmt : string(1 to 256); --! Current vector line comment + signal syncPulse : std_logic; --! Main Sync Signal + signal syncCount : integer; --! Sync count + signal val1 : std_logic_vector(15 downto 0); + signal val2 : std_logic_vector(15 downto 0); + signal val3 : std_logic_vector(15 downto 0); +begin + cmp_TestVector : entity crashExample(BEHAVIORAL) + port map ( vctrFlNm => vectorFilename, + fEnd => fVctrEnd, + syncPulse => syncPulse, + syncCount => syncCount, + v1 => val1, + v2 => val2, + v3 => val3, + vctrCmt => vctrCmt); +end BEHAVORIAL; diff --git a/testsuite/gna/issue795/testsuite.sh b/testsuite/gna/issue795/testsuite.sh new file mode 100755 index 000000000..17658d266 --- /dev/null +++ b/testsuite/gna/issue795/testsuite.sh @@ -0,0 +1,16 @@ +#! /bin/sh + +. ../../testenv.sh + +analyze repro.vhdl +elab_simulate repro + +clean + +export GHDL_STD_FLAGS=--std=02 +analyze file_reader_pkg.vhdl ex.vhdl tb_ex.vhdl +elab_simulate tbcrashexample2 -gvectorfilename=input.txt + +clean + +echo "Test successful" -- cgit v1.2.3