[SOLVED] VHDL Simulation error using Xilinx ISE14.7

Status
Not open for further replies.

MSAKARIM

Full Member level 3
Joined
Jun 2, 2015
Messages
154
Helped
1
Reputation
2
Reaction score
4
Trophy points
1,298
Activity points
2,528
Dear all, Plz i need some help.
I have an error with this code but unfortunately i can't recognize it.I'm using Xilinx ISE14.7 as a tool
behavioral check syntax is performed successfully , but Simulate behavioral model is stopped due to these errors:
ERROR: Index 64 out of bound 63 downto 0.
ERROR: In process sha256_exp_unit.vhd:33
----------------------------------------------------------------------------------------------------------------------------------
Code:
Code:
library ieee;
	use ieee.std_logic_1164.all;
	use ieee.std_logic_unsigned.all;
	use ieee.numeric_std.all;
	use work.sha256_pkg.all;

entity sha256_exp_unit is
	port(
		clk :		in	std_ulogic;
		rst :		in	std_ulogic;
		en	:		in std_ulogic;
		mi	:		in	word;
		sel :		in std_ulogic;
		wi	:		out word
	);

end entity sha256_exp_unit;

architecture arch of sha256_exp_unit is

type wi_array is array(15 downto 0) of word;
signal wi_ff : wi_array;
signal wi_ff_0, sum_out : word;

begin 
	with sel select 
	wi_ff_0 <= mi when '0',
		wi_ff(15) when '1',
		(others => '0') when others;

	sum_out <= std_ulogic_vector(unsigned(wi_ff(14)) + unsigned(sigma_lower0(wi_ff(13))) + unsigned(wi_ff(5)) + unsigned(sigma_lower1(wi_ff(0)))); --can be optimized
	wi <= wi_ff_0;

	proc_fifo : process(clk, wi_ff_0)
		begin
			if clk = '1' and clk'event then
				if rst = '1' then
					for i in 0 to 15 loop
						wi_ff(i) <= (others => '0');
					end loop;
				elsif(en='1') then
					wi_ff(0) <= wi_ff_0;
					for i in 1 to 15 loop
						if i = 15 then
							wi_ff(i) <= sum_out;
						else
							wi_ff(i) <= wi_ff(i-1);
						end if;
					end loop;
				end if;
			end if;
	end process;
					
end architecture arch;

P.S. Line 33 starts at this line sum_out <=


[ATTACH=CONFIG]157522._xfImport[/ATTACH][ATTACH=CONFIG]157523._xfImport[/ATTACH]
 

VHDL does not have a data type of "word". Is this defined in your package, which you haven't shown us?
 
VHDL does not have a data type of "word". Is this defined in your package, which you haven't shown us?

Yes i defined it in my package, and i'm sure that the package works well.
 

Assuming word is defined as a 64-bit (i.e. 63 downto 0)

Xilinx's VHDL simulators will usually error when there are N-bit values added together and assigned to an N-bit value as the add operation increases the bit width. In your case you are adding 4 things together, which could conceivably grow by 2-bits.

e.g. adding four 2-bit numbers..
11 + 11 + 11 + 11 = 1100

the result is 4-bits.

As I recall ISE's simulator was really picky about the assignment widths (vivado seems pretty picky too), modelsim I think just warns you, and many synthesis tools don't care and just inform you it's dropping the bit (or maybe it might warn you about it).
 

Yes I get it, i tried this solution but i still have the same problem.
Code:
-- expansion unit to generate 64 Wi from 16 Mi

library ieee;
	use ieee.std_logic_1164.all;
	use ieee.std_logic_unsigned.all;
	use ieee.numeric_std.all;
	use work.sha256_pkg.all;

entity sha256_exp_unit is
	port(
		clk :		in	std_ulogic;
		rst :		in	std_ulogic;
		en	:		in std_ulogic;
		mi	:		in	word;
		sel :		in std_ulogic;
		wi	:		out word
	);

end entity sha256_exp_unit;

architecture arch of sha256_exp_unit is

type wi_array is array(15 downto 0) of word;
signal wi_ff : wi_array;
signal wi_ff_0 : word;
signal sum_out: std_ulogic_vector(67 downto 0);

begin 
	with sel select 
	wi_ff_0 <= mi when '0',
		wi_ff(15) when '1',
		(others => '0') when others;

sum_out <= std_ulogic_vector(unsigned(wi_ff(14)) + unsigned(sigma_lower0(wi_ff(13))) + unsigned(wi_ff(5)) + unsigned(sigma_lower1(wi_ff(0)))); --can be optimized
wi <= wi_ff_0;

	proc_fifo : process(clk, wi_ff_0)
		begin
			if clk = '1' and clk'event then
				if rst = '1' then
					for i in 0 to 15 loop
						wi_ff(i) <= (others => '0');
					end loop;
				elsif(en='1') then
					wi_ff(0) <= wi_ff_0;
					for i in 1 to 15 loop
						if i = 15 then
							wi_ff(i) <= sum_out(63 downto 0);
						else
							wi_ff(i) <= wi_ff(i-1);
						end if;
					end loop;
				end if;
			end if;
	end process;
					
end architecture arch;
 

@Ads-ee - VHDL has no bit growth during aithmatic. The output will always be the length of the longest operand

@MSAKARIM
I dont see declaration of sigma_lower0/1 - please post ALL the code.
 
@Ads-ee - VHDL has no bit growth during aithmatic. The output will always be the length of the longest operand
Nice to know, I primarily use Verilog and Systemverilog, and only occasionally am forced to use VHDL. So I'll assume that VHDL truncates the word to the longest operand and then assigns that truncated value to the LHS? I guess that means if you don't want bit-growth to bite you in the rear you need to pre-pad the operands to account for this?

I should reread the VHDL spec it's been way too many years, since I last read it.
 
@Asd-ee

No truncation takes place. You'll get an error about size missmatch. The longest operand on the RHS MUST match the length of the LHS of the assignment.

consider the following:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
signal res : unsigned(7 downto 0);
signal co : std_logic;
signal a,b : unsigned(3 downto 0);
signal c,d : unsigned(7 downto 0);
signal e,f : unsigned(15 downto 0);
 
res <= a + b;  -- ERROR: a+b = 4 bits, missmatch in size.
res <= ("0000" & a) + b; -- Correct - B is expanded to 8 bits
 
res <= c + d;  -- correct. Be aware, value may overflow
 
-- this should work in VHDL 2008
(co, res) <= ('0'& c) + d;  -- carry out should be covered, no overflow required
 
res <= e + f;   -- ERROR. Result is 16 bits, does not fit into res

 
@Ads-ee - VHDL has no bit growth during aithmatic. The output will always be the length of the longest operand

@MSAKARIM
I dont see declaration of sigma_lower0/1 - please post ALL the code.

sigma_lower0/1 are functions declared in this package
package code:
Code:
library ieee;
	use ieee.std_logic_1164.all;
	use ieee.std_logic_unsigned.all;
	use ieee.numeric_std.all;

package sha256_pkg is

	subtype word is std_ulogic_vector(63 downto 0);
	type word_vector is array(integer range <>) of word;
	subtype sha_msg is std_ulogic_vector(1023 downto 0);
	subtype sha_hash is std_ulogic_vector(511 downto 0);
	type sha_array is array(integer range <>) of sha_msg;

----------------------------------
--array of round constants
----------------------------------

	constant K_constants :  word_vector(0 to 79) := (  X"428a2f98d728ae22" , X"7137449123ef65cd", X"b5c0fbcfec4d3b2f" , X"e9b5dba58189dbbc" ,
		                    X"3956c25bf348b538" ,X"59f111f1b605d019" , X"923f82a4af194f9b" , X"ab1c5ed5da6d8118" ,X"d807aa98a3030242" ,
		                    X"12835b0145706fbe" , X"243185be4ee4b28c" ,X"550c7dc3d5ffb4e2" , X"72be5d74f27b896f" ,X"80deb1fe3b1696b1" ,
		                    X"9bdc06a725c71235" ,X"c19bf174cf692694" , X"e49b69c19ef14ad2" ,X"efbe4786384f25e3" ,X"0fc19dc68b8cd5b5" ,
		                    X"240ca1cc77ac9c65" ,X"2de92c6f592b0275" ,X"4a7484aa6ea6e483" ,X"5cb0a9dcbd41fbd4" ,X"76f988da831153b5" ,
                                    X"983e5152ee66dfab" ,X"a831c66d2db43210" , X"b00327c898fb213f" , X"bf597fc7beef0ee4" ,X"c6e00bf33da88fc2",
		                    X"d5a79147930aa725" ,X"06ca6351e003826f" ,X"142929670a0e6e70" ,X"27b70a8546d22ffc" ,X"2e1b21385c26c926" ,
		                    X"4d2c6dfc5ac42aed" , X"53380d139d95b3df" , X"650a73548baf63de" , X"766a0abb3c77b2a8" ,X"81c2c92e47edaee6" ,
		                    X"92722c851482353b" , X"a2bfe8a14cf10364" , X"a81a664bbc423001" ,X"c24b8b70d0f89791" ,X"c76c51a30654be30" ,
		                    X"d192e819d6ef5218" ,X"d69906245565a910" ,X"f40e35855771202a" ,X"106aa07032bbd1b8" ,X"19a4c116b8d2d0c8" ,
		                    X"1e376c085141ab53" ,X"2748774cdf8eeb99" ,X"34b0bcb5e19b48a8", X"391c0cb3c5c95a63" ,X"4ed8aa4ae3418acb" ,
		                    X"5b9cca4f7763e373" , X"682e6ff3d6b2b8a3" ,X"748f82ee5defb2fc" , X"78a5636f43172f60" , X"84c87814a1f0ab72",
                                    X"8cc702081a6439ec" ,X"90befffa23631e28" ,X"a4506cebde82bde9" ,X"bef9a3f7b2c67915" , X"c67178f2e372532b" ,
                                    X"ca273eceea26619c" ,X"d186b8c721c0c207" ,X"eada7dd6cde0eb1e" ,X"f57d4f7fee6ed178" ,X"06f067aa72176fba" ,
                                    X"0a637dc5a2c898a6",X"113f9804bef90dae" , X"1b710b35131c471b" ,X"28db77f523047d84" , X"32caab7b40c72493" ,
                                    X"3c9ebe0a15c9bebc" ,X"431d67c49c100d4c" ,X"4cc5d4becb3e42b6" ,X"597f299cfc657e2a" , X"5fcb6fab3ad6faec" , 
                                    X"6c44198c4a475817"  );

----------------------------------
--array of initial hash values
----------------------------------
	constant H_init : word_vector(0 to 7) := (
		x"6a09e667f3bcc908",
		x"bb67ae8584caa73b",
		x"3c6ef372fe94f82b",
		x"a54ff53a5f1d36f1",
		x"510e527fade682d1",
		x"9b05688c2b3e6c1f",
		x"1f83d9abfb41bd6b",
		x"5be0cd19137e2179"
	);


----------------------------------
--function definitions
----------------------------------

function shr(x : word; n : natural) return word;
function rotr(x : word; n : natural) return word;
function rotl(x : word; n : natural) return word;
function Ch(x,y,z : word) return word;
function Maj(x,y,z : word) return word;
function sigma_lower0(x : word) return word; --std_ulogic_vector;
function sigma_lower1(x : word) return word; --std_ulogic_vector;
function sigma_upper0(x : word) return word; --std_ulogic_vector;
function sigma_upper1(x : word) return word; --std_ulogic_vector;
function expand_msg_blocks(w : word_vector(15 downto 0)) return word_vector;
function break_chunks(msg : sha_msg) return word_vector;
function return_chunk(msg : sha_msg; i : natural) return std_ulogic_vector;
procedure compression(variable a, b, c, d, e, f, g, h, t1, t2, exp_w : inout word; i : in natural);


procedure sha256_onechunk(msg : in sha_msg; variable h0, h1, h2, h3, h4, h5, h6, h7 : inout word);  ---one message
function sha256(blocks : sha_array; length : natural) return std_ulogic_vector;     ---array of mesgs

end sha256_pkg;

package body sha256_pkg is
	
----------------------------------
--function implementations
----------------------------------

	function shr(x : word; n : natural) return word is
		begin
			return std_ulogic_vector(shift_right(unsigned(x), n));
	end function;

	function rotr(x : word; n : natural) return word is
		begin
			return std_ulogic_vector(rotate_right(unsigned(x), n));
	end function;

	function rotl(x : word; n : natural) return word is
		begin
			return std_ulogic_vector(rotate_left(unsigned(x), n));
	end function;


	function Ch(x,y,z : word) return word is      ---was std_ulogic_vector
		begin	
			return (x and y) xor (not(x) and z);
	end function;

	function Maj(x,y,z : word) return word is
		begin
			return (x and y) xor (x and z) xor (y and z);
	end function;
	
  -----?0(x) && ?1(x)
	function sigma_lower0(x : word) return word is
		begin
			return rotr(x, 1) xor rotr(x, 8) xor shr(x, 7);
	end function;

	function sigma_lower1(x : word) return word is
		begin
			return rotr(x, 19) xor rotr(x, 61) xor shr(x, 6);
	end function;
   -------  ?0(x) &   ?1(x)
	function sigma_upper0(x : word) return word is
		begin
			return rotr(x, 28) xor rotr(x, 34) xor rotr(x, 39);
	end function;

	function sigma_upper1(x : word) return word is
		begin
			return rotr(x, 14) xor rotr(x, 18) xor rotr(x, 41);
	end function;
    --- Wt equation
	function expand_msg_blocks(w : word_vector(15 downto 0)) return word_vector is
		variable exp_w : word_vector(79 downto 0);

		begin
			for i in 0 to 79 loop  --rounds=79
				if i < 16 then
					exp_w(i) := w(i);
				else
					exp_w(i) := std_ulogic_vector(unsigned(exp_w(i-16)) + unsigned(sigma_lower0(exp_w(i-15))) + unsigned(exp_w(i-7)) + unsigned(sigma_lower1(exp_w(i-2))));
				end if;
			end loop;
			return exp_w;
	end function;
   ---- divide message to wt  from 0:15
	function break_chunks(msg : sha_msg) return word_vector is
		variable w : word_vector(15 downto 0);

		begin
			for i in 0 to 15 loop     
				w(i) := msg(1024-(i*64+1) downto 1024-(i*64+64));
			end loop;
			return w;
	end function;

	function return_chunk(msg : sha_msg; i : natural) return std_ulogic_vector is  
		begin
			return msg(1024-(i*64+1) downto 1024-(i*64+64));
	end function;
           
	procedure compression(variable a, b, c, d, e, f, g, h, t1, t2, exp_w : inout word; i : in natural) is	
			begin
				t2 := std_ulogic_vector(unsigned(sigma_upper0(a)) + unsigned(Maj(a, b, c)));
				t1 := std_ulogic_vector(unsigned(h) + unsigned(sigma_upper1(e)) + unsigned(Ch(e, f, g)) + unsigned(K_constants(i)) + unsigned(exp_w));
				h := g;
				g := f;
				f := e;
				e := std_ulogic_vector(unsigned(d) + unsigned(t1));
				d := c;
				c := b;
				b := a;
				a := std_ulogic_vector(unsigned(t1) + unsigned(t2));
	end procedure;
		
	procedure sha256_onechunk(msg : in sha_msg; variable h0, h1, h2, h3, h4, h5, h6, h7 : inout word) is
		variable w : word_vector(15 downto 0);
		variable exp_w : word_vector(79 downto 0);
		variable a, b, c, d, e, f, g, h, t1, t2 : word;
		

		begin
			w := break_chunks(msg);  --- take block 1024 bit and gives 16 words
			exp_w := expand_msg_blocks(w);   ---take 16 words and gives from 16 to 79 

			a := h0;  
			b := h1;
			c := h2;
			d := h3;
			e := h4;
			f := h5;
			g := h6;
			h := h7;


			for i in 0 to 79 loop
				
				compression(a, b, c, d, e, f, g, h, t1, t2, exp_w(i), i);
				
			end loop;

			h0 := std_ulogic_vector(unsigned(h0) + unsigned(a));
			h1 := std_ulogic_vector(unsigned(h1) + unsigned(b));
			h2 := std_ulogic_vector(unsigned(h2) + unsigned(c));
			h3 := std_ulogic_vector(unsigned(h3) + unsigned(d));
			h4 := std_ulogic_vector(unsigned(h4) + unsigned(e));
			h5 := std_ulogic_vector(unsigned(h5) + unsigned(f));
			h6 := std_ulogic_vector(unsigned(h6) + unsigned(g));
			h7 := std_ulogic_vector(unsigned(h7) + unsigned(h));

	end procedure;

	function sha256(blocks : sha_array; length : natural) return std_ulogic_vector is     ---- compute hash for more than one block  
		variable h0, h1, h2, h3, h4, h5, h6, h7 : word;
		
		begin
			h0 := H_init(0);
			h1 := H_init(1);
			h2 := H_init(2);
			h3 := H_init(3);
			h4 := H_init(4);
			h5 := H_init(5);
			h6 := H_init(6);
			h7 := H_init(7);

			for i in length-1 downto 0 loop
				
				sha256_onechunk(blocks(i), h0, h1, h2, h3, h4, h5, h6, h7);
				
			end loop;

			return h0 & h1 & h2 & h3 & h4 & h5 & h6 & h7;
	end function sha256;
end package body sha256_pkg;
 

I ran this code with a basic testbench with no errors.
Did you have a specific testbench that causes the issue?
There is the possibility this is an ISIM bug that will not be fixed. So you'll need to use a simulator thats been updated in the last 6 years. You can use GHDL for free as it is open source.
 
These statements seem to mismatch
@Asd-ee
No truncation takes place. You'll get an error about size missmatch. The longest operand on the RHS MUST match the length of the LHS of the assignment.
@Asd-ee

Code VHDL - [expand]
1
2
3
4
signal res : unsigned(7 downto 0);
signal c,d : unsigned(7 downto 0);
 
res <= c + d;  -- correct. Be aware, value may overflow


The code comment says correct value may overflow, which means the result of c+d may be truncated (carry is lopped off or truncated) or am I misinterpreting your first statement?

Apparently I need to read the VHDL spec again.
 
If you do the following:


Code VHDL - [expand]
1
res <= x"80" + x"80";



result will be 0. There will be no warning in simulation because there is no overflow bit, hence no issue. It just assumes you sized everything correctly.

Its different if you do the following:


Code VHDL - [expand]
1
res <= to_unsigned(256, 8);



Because here, it knows that 256 is too large to fit into 8 bits, so you'll get a warning that the resulting vector was truncated because it expected at least a 9 bit result, but you've forced it 8 bits.

- - - Updated - - -

And heres the proof:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity trunc_test is
end entity;
 
architecture sim of trunc_test is
begin
 
  process
    variable u : unsigned(7 downto 0);
  begin
    u := x"80" + x"80";
 
    report to_hstring(u);
 
    u := to_unsigned(256, 8);
    report to_hstring(u);
 
    wait;
  end process;
 
end architecture sim;



Output:

Code:
EXECUTION:: NOTE   : 00
EXECUTION:: Time: 0 ps,  Iteration: 0,  Instance: /trunc_test,  Process: line__11.
KERNEL: WARNING: NUMERIC_STD.TO_UNSIGNED: vector truncated
KERNEL: Time: 0 ps,  Iteration: 0,  Instance: /trunc_test,  Process: line__11.
EXECUTION:: NOTE   : 00
EXECUTION:: Time: 0 ps,  Iteration: 0,  Instance: /trunc_test,  Process: line__11.
KERNEL: Simulation has finished. There are no more test vectors to simulate.
 
Tricky thanks for the explanation, though it makes me think Verilog math is really inherently easier, at least in Verilog you have to handle overflow bits, width, sign extension, etc all on your own and don't have to think about whether or not the language is going to enforce some rule or not (you already know you have to do it yourself).

So many VHDL coders over the years have hassled me about how superior VHDL is at math, but every time it comes down to coding math operations the Verilog code I write is shorter and easier to read/understand (and doesn't require harrd to read type conversions).
 
I think if you need too many type conversions you're doing it wrong. The problem comes because people seem to think all ports need to be std_logic_vector.
Even then, VHDL 2008 has numeric_std_unsigned to standardise the handling of slvs as unsigned values.
 

@TrickyDicky
I used vivado 2017.4 and yes the error disappeared, Thanks.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…