From 71caf242ed53d8de99b24e969b8d536408f5f4d2 Mon Sep 17 00:00:00 2001
From: Tristan Gingold <tgingold@free.fr>
Date: Sat, 26 May 2018 08:14:17 +0200
Subject: Add testcase for #578

---
 testsuite/gna/issue578/generics.vhdl | 515 +++++++++++++++++++++++++++++++++++
 1 file changed, 515 insertions(+)
 create mode 100644 testsuite/gna/issue578/generics.vhdl

(limited to 'testsuite/gna/issue578/generics.vhdl')

diff --git a/testsuite/gna/issue578/generics.vhdl b/testsuite/gna/issue578/generics.vhdl
new file mode 100644
index 000000000..f90a74d81
--- /dev/null
+++ b/testsuite/gna/issue578/generics.vhdl
@@ -0,0 +1,515 @@
+library ieee;
+use ieee.std_logic_1164.all;
+--use ieee.math_real.all;
+use ieee.numeric_std.all;
+
+package generics is
+	constant synthesis : boolean := true
+									-- synthesis translate_off
+									and false
+									-- synthesis translate_on
+									;
+
+	function sim_cond(cond : boolean) return boolean;
+
+	function istr(v : integer) return string;
+	
+	function as_std_logic(v : boolean) return std_logic;
+
+	function rot_l(v : std_logic_vector; n : integer := 1) return std_logic_vector;
+	function rot_r(v : std_logic_vector; n : integer := 1) return std_logic_vector;
+	function sh_l(v : std_logic_vector; n : integer := 1) return std_logic_vector;
+	function sh_r(v : std_logic_vector; n : integer := 1) return std_logic_vector;
+
+	function log2_int(v : integer) return integer;
+	function log2(v : integer) return integer;
+	function is_log2(v : integer) return boolean;
+	
+	function binary_flatten(v : std_logic_vector; n : integer) return std_logic_vector;
+	function min(a : integer; b : integer) return integer;
+	function max(a : integer; b : integer) return integer;
+	
+	function find_first_bit(v : std_logic_vector) return integer;
+	function mask_first_bit(v : std_logic_vector) return std_logic_vector;
+	function next_multiple(v : integer; m : integer) return integer;
+	function reverse_vector(inp : std_logic_vector) return std_logic_vector;
+	function reorder_vector(inp : std_logic_vector) return std_logic_vector;
+	function htonl(inp : std_logic_vector) return std_logic_vector;
+	function ntohl(inp : std_logic_vector) return std_logic_vector;
+	function vector_all_valid(i : std_logic_vector) return boolean;
+	function to_integer(i : std_logic) return integer;
+	
+	function integer_reverse_bits(i : integer; bits : integer) return integer;
+	
+	function dbg_collapse16(d : in std_logic_vector) return std_logic_vector;			
+
+	function bram_we_width(aw : integer) return integer;
+
+	function chr(sl: std_logic) return character;
+	function chr(i : integer) return character;
+	function chr(b : boolean) return character;
+	function vector_to_string(v : std_logic_vector) return string;
+	function vector_to_hex_string(v : std_logic_vector) return string;
+
+	
+	function to_std_logic_vector(v : integer; size : integer) return std_logic_vector;
+
+	function popcnt(v : std_logic_vector) return integer;
+	function popcnt(v : integer; bits : integer) return integer;
+	function popcnt_x(v : std_logic_vector) return integer;
+	
+	function maxlen_lfsr_advance(reg : std_logic_vector) return std_logic_vector;
+	function random_vector(len : integer; seed : integer) return std_logic_vector;
+	function random(max : integer; seed : integer) return integer;
+		
+	function reverse_any_vector(a : in std_logic_vector) return std_logic_vector;
+
+	function sel(cond : boolean; if_true : integer; if_false : integer) return integer;
+	function sel(cond : boolean; if_true : std_logic_vector; if_false : std_logic_vector) return std_logic_vector;
+	function sel(cond : boolean; if_true : std_logic; if_false : std_logic) return std_logic;
+	function sel(cond : boolean; if_true : string; if_false : string) return string;
+	procedure clkp(signal clk : in std_logic; n : in integer);
+
+	function vector_mux(sel : std_logic_vector; i1 : std_logic_vector; i2 : std_logic_vector) return std_logic_vector;
+	function div_ceil(a : integer; b : integer) return integer;
+
+	function int_strlen(vv : integer) return natural;
+end generics;
+
+package body generics is
+	function chr(b : boolean) return character is
+	begin
+		if b then
+			return 't';
+		end if;
+		return 'f';
+	end function;
+
+	function chr(i : integer) return character is
+		variable s : string(1 to 10) := "0123456789";
+	begin
+		if i < 10 then
+			return s(i + 1);
+		else
+			return 'X';
+		end if;
+	end function;
+
+	function istr(v : integer) return string is
+	begin
+		return integer'image(v);
+	end function;
+	
+
+	function as_std_logic(v : boolean) return std_logic is
+	begin
+		if v then return '1'; end if;
+		return '0';
+	end function;
+
+	function int_strlen(vv : integer) return natural is
+		variable ret : natural := 0;
+		variable v : integer := vv;
+	begin
+		if v < 0 then
+			ret := ret + 1;
+			v := -v;
+		end if;
+		while v >= 10 loop
+			v := v / 10;
+			ret := ret + 1;
+		end loop;
+		return ret + 1;
+	end function;
+	
+	function rot_l(v : std_logic_vector; n : integer := 1) return std_logic_vector is
+	begin
+		return std_logic_vector(rotate_left(unsigned(v), n));
+	end function;
+	function rot_r(v : std_logic_vector; n : integer := 1) return std_logic_vector is
+	begin
+		return std_logic_vector(rotate_right(unsigned(v), n));
+	end function;
+	function sh_l(v : std_logic_vector; n : integer := 1) return std_logic_vector is
+	begin
+		return std_logic_vector(shift_left(unsigned(v), n));
+	end function;
+	function sh_r(v : std_logic_vector; n : integer := 1) return std_logic_vector is
+	begin
+		return std_logic_vector(shift_right(unsigned(v), n));
+	end function;
+	function log2(v : integer) return integer is
+	begin
+		return log2_int(v);
+	end function;
+	function is_log2(v : integer) return boolean is
+	begin
+		return 2 ** log2(v) = v;
+	end function;
+	function to_integer(i : std_logic) return integer is
+	begin
+		if i = '1' then
+			return 1;
+		elsif i = '0' then
+			return 0;
+		else
+			return -1;
+		end if;
+	end function;
+	function dbg_collapse16(d : in std_logic_vector) return std_logic_vector is
+		variable ret : std_logic_vector(0 to 15);
+		variable oi : integer;
+	begin
+		oi := 0;
+		ret := (others => '0');
+		for i in d'range loop
+			ret(oi) := ret(oi) xor d(i);
+			if oi < 15 then
+				oi := oi + 1;
+			else
+				oi := 0;
+			end if;
+		end loop;
+		return ret;
+	end function;
+	function random(max : integer; seed : integer) return integer is
+	begin
+		if max = 0 then return 0; end if;
+		return to_integer(unsigned(random_vector(log2_int(max) + 1, seed))) mod max;
+	end function;
+	function sel(cond : boolean; if_true : std_logic; if_false : std_logic) return std_logic is
+	begin
+		if cond then
+			return if_true;
+		end if;
+		return if_false;
+	end function;
+	function sel(cond : boolean; if_true : string; if_false : string) return string is
+	begin
+		if cond then
+			return if_true;
+		else
+			return if_false;
+		end if;
+	end function;
+	function div_ceil(a : integer; b : integer) return integer is
+	begin
+		return a / b + sel(a mod b /= 0, 1, 0);
+	end function;
+
+
+
+	function sim_cond(cond : boolean) return boolean is
+	begin
+		if synthesis then
+			return true;
+		else
+			return cond;
+		end if;
+	end function;
+	
+	function integer_reverse_bits(i : integer; bits : integer) return integer is
+		variable m : std_logic_vector(0 to bits - 1);
+	begin
+		m := std_logic_vector(to_unsigned(i, bits));
+		m := reverse_any_vector(m);
+		return to_integer(unsigned(m));
+	end function;
+
+	function vector_mux(sel : std_logic_vector; i1 : std_logic_vector; i2 : std_logic_vector) return std_logic_vector is
+		variable ret : std_logic_vector(0 to sel'length - 1);
+	begin
+		for i in 0 to sel'length - 1 loop
+			if sel(sel'left + i) = '1' then
+				ret(i) := i1(i1'left + i);
+			else
+				ret(i) := i2(i2'left + i);
+			end if;
+		end loop;
+		return ret;
+	end function;
+
+
+	procedure clkp(signal clk : in std_logic; n : in integer) is
+	begin
+		for i in 1 to n loop
+			wait until rising_edge(clk);
+		end loop;
+		wait for 1 ps;
+	end procedure;
+
+	function random_vector(len : integer; seed : integer) return std_logic_vector is
+		variable lfsr : std_logic_vector(0 to 7) := std_logic_vector(to_unsigned(seed, 8));
+		variable ret : std_logic_vector(0 to len - 1);
+	begin
+		for i in 0 to len / 8 loop
+			lfsr := maxlen_lfsr_advance(lfsr);
+			lfsr := maxlen_lfsr_advance(lfsr);
+			lfsr := maxlen_lfsr_advance(lfsr);
+			lfsr := maxlen_lfsr_advance(lfsr);
+			ret(i * 8 to min(ret'length, (i + 1) * 8) - 1) := lfsr(0 to min(8, ret'length - i * 8) - 1);
+		end loop;
+		return ret;
+	end function;
+	function sel(cond : boolean; if_true : integer; if_false : integer) return integer is
+	begin
+		if cond then return if_true; else return if_false; end if;
+	end function;
+	function sel(cond : boolean; if_true : std_logic_vector; if_false : std_logic_vector) return std_logic_vector is
+	begin
+		if cond then return if_true; else return if_false; end if;
+	end function;
+
+	function popcnt(v : integer; bits : integer) return integer is
+	begin
+		return popcnt(std_logic_vector(to_unsigned(v, bits)));
+	end function;
+
+	function reverse_any_vector (a: in std_logic_vector) return std_logic_vector is
+		variable result: std_logic_vector(a'range);
+		alias aa: std_logic_vector(a'reverse_range) is a;
+	begin
+		for i in aa'range loop
+			result(i) := aa(i);
+		end loop;
+		return result;
+	end;
+	function maxlen_lfsr_advance(reg : std_logic_vector) return std_logic_vector is
+		variable ret : std_logic_vector(reg'range);
+	begin
+		if ret'left > ret'right then
+			ret(reg'left downto 1) := reg(reg'left - 1 downto 0);
+		else
+			ret(1 to reg'right) := reg(0 to reg'right - 1);
+		end if;
+		if reg'length = 3 then
+			ret(0) := reg(2) xnor reg(1);
+		elsif reg'length = 4 then
+			ret(0) := reg(3) xnor reg(2);
+		elsif reg'length = 8 then
+			ret(0) := reg(7) xnor reg(5) xnor reg(4) xnor reg(3);
+		elsif reg'length = 57 then
+			ret(0) := reg(56) xnor reg(49);
+		else
+			assert false report "no matching shift register configured for length " & integer'image(reg'length) severity failure;
+		end if;
+		return ret;
+	end function;
+
+
+
+	function vector_all_valid(i : std_logic_vector) return boolean is
+	begin
+		for j in i'range loop
+			if i(j) /= '1' and i(j) /= '0' then
+				return false;
+			end if;
+		end loop;
+		return true;
+	end function;
+
+	function popcnt_x(v : std_logic_vector) return integer is
+		variable ret : integer;
+	begin
+		ret := 0;
+		for i in v'range loop
+			if v(i) = 'X' then
+				ret := ret + 1;
+			end if;
+		end loop;
+		return ret;
+	end function;
+	
+	function popcnt(v : std_logic_vector) return integer is
+		variable res : integer;
+	begin
+		res := 0;
+		for i in v'range loop
+			if v(i) = '1' then
+				res := res + 1;
+			end if;
+		end loop;
+		return res;
+	end function;
+	function to_std_logic_vector(v : integer; size : integer) return std_logic_vector is
+		variable ret : std_logic_vector(size - 1 downto 0);
+		variable tmp : unsigned(size - 1 downto 0);
+	begin
+		tmp := to_unsigned(v, size);
+		return std_logic_vector(tmp);
+	end function;
+
+
+	function chr(sl: std_logic) return character is
+		variable c: character;
+    begin
+		case sl is
+			when 'U' => c:= 'U';
+			when 'X' => c:= 'X';
+			when '0' => c:= '0';
+			when '1' => c:= '1';
+			when 'Z' => c:= 'Z';
+			when 'W' => c:= 'W';
+			when 'L' => c:= 'L';
+			when 'H' => c:= 'H';
+			when '-' => c:= '-';
+		end case;
+		return c;
+	end chr;
+
+	function vector_to_hex_string(v : std_logic_vector) return string is
+		variable ret : string(1 to (v'length + 3) / 4);
+		type hchar_t is array(0 to 15) of character;
+		constant hchar : hchar_t := ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
+		variable off : integer := v'length mod 4;
+	begin
+		if off /= 0 then
+			ret(1) := hchar(to_integer(unsigned(v(0 to off - 1))));
+		end if;
+		for i in 0 to v'length / 4 - 1 loop
+			ret(i + sel(off = 0, 1, 2)) := hchar(to_integer(unsigned(v(off + i * 4 to off + i * 4 + 3))));
+		end loop;
+		return ret;
+	end function;
+
+	function vector_to_string(v : std_logic_vector) return string is
+		variable ret : string(1 to v'length);
+		variable at : integer;
+	begin
+		at := 1;
+		for i in v'range loop
+			ret(at) := chr(v(i));
+			at := at + 1;
+		end loop;
+		return ret;
+--		for i in 0 to v'length - 1 loop
+--			ret(i + 1) := chr(v(i));
+--		end loop;
+--		return ret;
+	end function;
+
+	function bram_we_width(aw : integer) return integer is
+	begin
+		if aw > 16 then
+			return 4;
+		elsif aw > 8 then
+			return 2;
+		else
+			return 1;
+		end if;
+	end function;
+
+	function htonl(inp : std_logic_vector) return std_logic_vector is
+		variable ret : std_logic_vector(inp'range);
+	begin
+		ret(31 downto 24) := inp(7 downto 0);
+		ret(23 downto 16) := inp(15 downto 8);
+		ret(15 downto 8)  := inp(23 downto 16);
+		ret(7 downto 0)   := inp(31 downto 24);
+		return ret;
+	end function;
+
+	function ntohl(inp : std_logic_vector) return std_logic_vector is
+	begin
+		return htonl(inp);
+	end function;
+
+	function reorder_vector(inp : std_logic_vector) return std_logic_vector is
+		variable ret : std_logic_vector(inp'reverse_range);
+	begin
+		return inp;
+		if inp'left < inp'right then
+			for i in inp'range loop
+				ret(inp'right - i) := inp(i);
+			end loop;
+		elsif inp'left > inp'right then
+			for i in inp'range loop
+				ret(inp'left - i) := inp(i);
+			end loop;
+		else
+			ret(inp'left) := inp(inp'left);
+		end if;
+		return ret;
+	end function;
+
+	function reverse_vector(inp : std_logic_vector) return std_logic_vector is
+		variable ret : std_logic_vector(inp'reverse_range);
+	begin
+		for i in inp'range loop
+			ret(i) := inp(i);
+		end loop;
+		return ret;
+	end function;
+
+	function next_multiple(v : integer; m : integer) return integer is
+	begin
+		if v mod m = 0 then
+			return v;
+		else
+			return v + m - v mod m;
+		end if;
+	end function;
+	function mask_first_bit(v : std_logic_vector) return std_logic_vector is
+		variable ret : std_logic_vector(v'range) := (others => '0');
+	begin
+		for i in 0 to v'length - 1 loop
+			if v(i) = '1' then
+				ret(i) := '1';
+				return ret;
+			end if;
+		end loop;
+		return ret;
+	end function;
+		
+	function find_first_bit(v : std_logic_vector) return integer is
+	begin
+		for i in 0 to v'length - 1 loop
+			if v(i) = '1' then return i; end if;
+		end loop;
+		return 0;
+	end function;
+
+	function min(a : integer; b : integer) return integer is
+	begin
+		if a < b then
+			return a;
+		end if;
+		return b;
+	end function;
+	function max(a : integer; b : integer) return integer is
+	begin
+		if a > b then
+			return a;
+		end if;
+		return b;
+	end function;
+
+	function binary_flatten(v : std_logic_vector; n : integer) return std_logic_vector is
+		variable res : std_logic_vector(n - 1 downto 0) := (others => '0');
+	begin
+		for i in 0 to n - 1 loop
+			if unsigned(v) = to_unsigned(i, v'length) then
+				res(i) := '1';
+				return res;
+			end if;
+		end loop;
+		return res;
+	end function;
+
+	function log2_int(v : integer) return integer is
+		variable vv, ret : integer;
+	begin
+		vv := v;
+		ret := 0;
+		while vv > 1 loop
+			ret := ret + 1;
+			vv  := vv / 2;
+		end loop;
+		if 2 ** ret = v then
+			return ret;
+		else
+			return ret + 1;
+		end if;
+		--return integer(ceil(log2(real(v))));
+	end function;
+end generics;
-- 
cgit v1.2.3