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
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;
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.
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;
please attach files unipackage.vhd and CommandsProcessor.vhd
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
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.
Thanks. I must confess, I never did, but I see that the usage of std_logic_arith inside std_logic_unsigned is encapsulated.These libraries are not incompatible and can be used in the same file.
function conv_ascii_to_binary(value: std_logic_vector) return std_logic_vector
function conv_ascii_to_binary(value: std_logic_vector(23 downto 0)) return std_logic_vector
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.
[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]
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.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.
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;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?