Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Vivado synthesis error

Status
Not open for further replies.

moeedmughal

Junior Member level 2
Joined
Oct 1, 2015
Messages
21
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Location
United Kingdom
Activity points
196
I have started to migrate our firmwares from ISE to Vivado (reason is upgrading from spartan3 to Artix7). While migrating first firmware i initially came across 4 errors after i run synthesis. which are as follow

1. [Synth 8-248] direction of slice does not match direction of prefix ["C:/Firmware/LibVHDL/src/UniPackage.vhd":1135]

2. [Synth 8-285] failed synthesizing module 'CommandsProcessor' ["C:/Firmware/Project/Magsus/Mag_02/src/CommandsProcessor.vhd":40]
3. [Synth 8-285] failed synthesizing module 'MagSusMeter' ["C:/Firmware/Project/Magsus/Mag_02/src/MagSusMeter.vhd":37]

4. [Common 17-69] Command failed: Synthesis failed - please see the console or run log file for details


Error#1 points to a function in file "UniPackage.vhd". The function converts ascii into binary.
Code:
function is as under:

	function conv_ascii_to_binary(value: std_logic_vector) return std_logic_vector is
		variable byte0  : std_logic_vector(7 downto 0);  
		variable byte1  : std_logic_vector(7 downto 0); 
		variable byte2  : std_logic_vector(7 downto 0); 
		variable binary : std_logic_vector(7 downto 0); 
	begin
		if (value'LENGTH > 24) then
			assert false
			report "conv_ascii_to_byte: argument's length is more than 23 bits"
			severity FAILURE;
		else
[COLOR="#FF0000"]ERROR ==>[/COLOR]       byte0 := value(23 downto 16) - x"30" ;
			                                        byte1 := (value(15 downto 8) - x"30") * x"0A";
			                                        byte2 := (value(7 downto 0) - x"30") * x"64";
			                                        binary := byte0 + byte1 + byte2;	
		end if;
		
		return binary;
	end conv_ascii_to_binary;

I guess the way it was done in ISE is not compatible in Vivado.

If you need any other information regarding Error#1 please ask freely. Any help in regard to resolve the errors will highly be appreciated.

Regards,
Moeed
 
Last edited by a moderator:

The Vivado compiler is more standards compliant than the one in ISE.
The error is likely coming about because the value is declared 0 to 23, and the function assumes value is downto.
This can happen if you call the function with a constant array as the default direction in VHDL is "to":

conv_asscii_to_binary(x"ABCD"); -- this is 0 to 23, not 23 downto 0

So, post the code where the function is called.
 

The Vivado compiler is more standards compliant than the one in ISE.
The error is likely coming about because the value is declared 0 to 23, and the function assumes value is downto.
This can happen if you call the function with a constant array as the default direction in VHDL is "to":

conv_asscii_to_binary(x"ABCD"); -- this is 0 to 23, not 23 downto 0

So, post the code where the function is called.

Thank you to reply,

code is here:
Code:
if Received_Bytes = 1 then
								MagSus_Samples_To_Acquire <= conv_ascii_to_binary(Rx_Data(7 downto 0) & x"3030");
							elsif Received_Bytes = 2 then
								MagSus_Samples_To_Acquire <= conv_ascii_to_binary(Rx_Data(15 downto 0) & x"30");
							elsif Received_Bytes = 3 then
								MagSus_Samples_To_Acquire <= conv_ascii_to_binary(Rx_Data(23 downto 0));
							end if;
 
Last edited by a moderator:

please attach files unipackage.vhd and CommandsProcessor.vhd
 
  • Like
Reactions: ads-ee

    ads-ee

    Points: 2
    Helpful Answer Positive Rating
How about modifying the CommandProcessor.vhd code with:

Code:
constant BYTE_X30 : std_logic_vector (7 downto 0) : "00110000";

        MagSus_Samples_To_Acquire <= conv_ascii_to_binary(Rx_Data(7 downto 0) &[COLOR="#FF0000"] BYTE_X30 & BYTE_X30[/COLOR]);
    elsif Received_Bytes = 2 then
        MagSus_Samples_To_Acquire <= conv_ascii_to_binary(Rx_Data(15 downto 0) &[COLOR="#FF0000"] BYTE_X30[/COLOR]);
    elsif Received_Bytes = 3 then

That way there is no room for interpreting the wrong direction.
 

This looks strange, how can a bitwise AND change the direction of an expression?

I reviewed the code, but stopped the analysis when I found that it uses incompatible numeric libraries IEEE.NUMERIC_STD and IEEE.STD_LOGIC_UNSIGNED.
 

This looks strange, how can a bitwise AND change the direction of an expression?

I reviewed the code, but stopped the analysis when I found that it uses incompatible numeric libraries IEEE.NUMERIC_STD and IEEE.STD_LOGIC_UNSIGNED.

These libraries are not incompatable and can be used in the same file. It is numeric_std and std_logic_arith that are non-compatable.

Having compiled the files in Quartus - the error comes about because of the following (not the lines you origionally pointed to):

byte1 := (value(15 downto 8) - x"30") * x"0A";

Here, you have 2 8 bit values multiplied together, giving a 16 bit result. byte1 is only 8 bits so cannot fit the 16 bit multiply result.

If it still complains about the original line, then I suspect a vivado bug.
 
These libraries are not incompatible and can be used in the same file.
Thanks. I must confess, I never did, but I see that the usage of std_logic_arith inside std_logic_unsigned is encapsulated.

Is it so that ISE tolerates the size mismatch in assignmnent and performs an implicit resize?
Similarly does it automatically normalize vector ranges in function calls as required for conv_to_big_endian()? The regular VHDL way is to make a normalized copy of the argument, as done in all IEEE library functions.
 

@FvM, std_logic_unsigned is designed to treat std_logic_vectors like unsigned values to the extent possible. The library gives VHDL semantics closer to what is used in Verilog. This includes some annoying things like being able to compare std_logic_vectors of unequal widths for equality -- this would normally be a warning. For this reason, I suggest only "safe" operators/functions be imported. Things like "+" and "-" -- not things like "=".

In terms of the change in direction, my guess here is that the intermediate expression created by the concatenation (not bitwise and) has VHDL's default (0 to N-1) size.
 
Yes, it's a concatenation. Somehow I've been reading a Verilog bitwise AND operator into it...

Surprisingly it changes the direction of the result. In the original code, this happens also in Quartus.

The OP silently changed the function body from post #1
Code:
function conv_ascii_to_binary(value: std_logic_vector) return std_logic_vector
into (post #5)
Code:
function conv_ascii_to_binary(value: std_logic_vector(23 downto 0)) return std_logic_vector
which enforces descending direction.

Why do you rarely experience similar problems? Because all standard VHDL library functions copy the argument to a "normalized" variable before accessing it bitwise.
 
These libraries are not incompatable and can be used in the same file. It is numeric_std and std_logic_arith that are non-compatable.

Having compiled the files in Quartus - the error comes about because of the following (not the lines you origionally pointed to):

byte1 := (value(15 downto 8) - x"30") * x"0A";

Here, you have 2 8 bit values multiplied together, giving a 16 bit result. byte1 is only 8 bits so cannot fit the 16 bit multiply result.

If it still complains about the original line, then I suspect a vivado bug.


@TrickyDicky & @FvM:

I rewrite the function and it works. Amended function is given below:

Code:
[SIZE=2][SIZE=4][SIZE=3]function conv_ascii_to_binary(value: std_logic_vector(23 downto 0)) return std_logic_vector is
	variable byte0  : std_logic_vector(7 downto 0);  
	variable byte1  : std_logic_vector(7 downto 0); 
	variable byte2  : std_logic_vector(7 downto 0); 
        variable test1  : std_logic_vector(7 downto 0); 
        variable test2  : std_logic_vector(7 downto 0); 
        variable test3  : std_logic_vector(15 downto 0); 
        variable test4  : std_logic_vector(15 downto 0); 
        variable binary : std_logic_vector(7 downto 0); 
	begin
		if (value'LENGTH > 24) then
			assert false
			report "conv_ascii_to_byte: argument's length is more than 23 bits"
			severity FAILURE;
		else
			byte0 := value(23 downto 16) - x"30" ;
			test1 := value(15 downto 8) - x"30";
			test3 := test1*x"0A";
			byte1 := test3(7 downto 0);
			--byte1 := (value(15 downto 8) - x"30") * x"0A";
			test2 := value(7 downto 0) - x"30";
			test4 := test2*x"64";
			byte2 := test4(7 downto 0);
			--byte2 := (value(7 downto 0) - x"30") * x"64";
			binary := byte0 + byte1 + byte2;	
		end if;
		
		return binary;
	end conv_ascii_to_binary;[/SIZE][/SIZE][/SIZE]

(Any comments on this modification are appreciated). After this amendment i encountered few other synthesis errors in UniPackage.vhdl but they were mostly due to the fact that width of variable wasn't declared in input argument.

Finally first firmware is synthesized and bitstream generated successfully. I hope it will actually work. :)

Many many thanks to all of you for your time and guidance.
 
Last edited:

vhdl but they were mostly due to the fact that width of variable wasn't declared in input argument.
That's possible but not the recommended way to write portable functions. Similarly you'll usually want a function like conv_ascii_to_binary() to work with different argument widths.

A simple case is conv_to_big_endian() which can be easily work with variable input width and range by copying value to a temporary variable v: std_logic_vector(value'LENGTH -1 downto 0). If you review the sources of IEEE libraries, you'll notice that they do the same in many functions.
 

That's possible but not the recommended way to write portable functions. Similarly you'll usually want a function like conv_ascii_to_binary() to work with different argument widths.

A simple case is conv_to_big_endian() which can be easily work with variable input width and range by copying value to a temporary variable v: std_logic_vector(value'LENGTH -1 downto 0). If you review the sources of IEEE libraries, you'll notice that they do the same in many functions.

Actually - usually by an alias:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
function do_something( s : std_logic_vector ) return std_logic_vector is
  alias slv_a : std_logic_vector(s'length-1 downto 0) is s;
  variable ret : std_logic_vector(s'length -1 downto 0);
begin
  -- do something using slv_a that is always downto
 
  return ret; -- always returns downto
end function;

 
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top