Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,371 Views

How to read signed values from FPGA in VHDL to Nios II system

Hi, 

 

 

I am reading a 14-bit signed value from a 14-bit vhdl port into a 16 bit signed variable in Nios II. There is no way for me to define it as 14 bits since the standard are alt_8, alt_16 and alt_32.  

 

 

So, I define it as 

 

 

alt_16 value=0;  

And I read the value using: 

value =IORD_ALTERA_AVALON_PIO_DATA(base);  

 

 

 

The problem is it always give me positive value every time it is read from this line even though I am sure it has both positive and negative value from VHDL code. 

 

 

printf("\n value= %.2f \n", (float) value);  

 

 

In the vhdl code, the 14 bits data is defined as follows: the msb represents the signed bit, the following 6 bits represent the magnitude, and the following 6 bits. 

 

 

signal a : sfixed(7 downto -6);  

 

 

 

 

 

I want to know,  

 

 

1. How could I check if the value is positive or negative cause I have no idea how to read each of the binary bit in Nios C code? 

2. Is it using 2's complement? 

 

How could I do that in C code? I am using C code to program Nios II. 

Thank you in advance.
0 Kudos
7 Replies
Altera_Forum
Honored Contributor I
79 Views

As the NIOS II is a microprocessor, the structure does not support any other than 8, 16, 32 Bits width.  

 

Nevertheless... I'd suggest to rescale the 14Bit VHDL value to a 16Bit VHDL value prior reading it by the NIOSII by multiplying with "4" :-) 

Depending on the data representation this might be by a simple concatenate &"00" (for signed vector) or typing a "*4" to implement the multiplication. This also depends on the VHDL package you are using (which functions are defined and thus synthesizable)
Altera_Forum
Honored Contributor I
79 Views

You are aligning the data on the LSB. Don't do that - you want to align it on the sign bit. 

 

For a 32-bit signed integer, bit-31 is the sign bit. For a 14-bit signed number, bit-13 is the sign bit: out <= in & "00" 

 

Alternatively, you can propagate the sign bit to all of the high bits: out <= (12 downto 0 => in(12 downto 0), others => in(13)) - or something like that.
Altera_Forum
Honored Contributor I
79 Views

Altera_Forum
Honored Contributor I
79 Views

I thought of a better way - you shouldn't (can't) multiply because that preserves the sign, which is wrong. Shifting is OK, but it's too specific. 

 

Use the built-in type conversions - convert the 14-bit to an integer (which should preserve the sign), then convert that integer to a std_logic_vector with the proper size for the Avalon port: 

 

port <= to_std_logic_vector(to_integer(data),port'size); 

 

You get to fix the syntax errors.
Altera_Forum
Honored Contributor I
79 Views

Why not just sign extend? 

 

output <= resize(a, a'high+2, a'low);
Altera_Forum
Honored Contributor I
79 Views

 

--- Quote Start ---  

Why not just sign extend? 

output <= resize(a, a'high+2, a'low); 

--- Quote End ---  

 

 

When using integer conversion one doesn't need to know the size difference when writing the code - it's more portable. 

 

Eventually one will forget why 'high+2 was used. 

 

Odds are the synthesis output is the same for both.
Altera_Forum
Honored Contributor I
79 Views

 

--- Quote Start ---  

When using integer conversion one doesn't need to know the size difference when writing the code - it's more portable. 

 

Eventually one will forget why 'high+2 was used. 

 

Odds are the synthesis output is the same for both. 

--- Quote End ---  

 

 

But the OP is using the sfixed type, and this function exists exactly for this purpose. Using the to_integer function from sfixed directly will remove the fractional part, so you need to use appropriate type conversions. 

Your code also used the non-standard std_logic_arith library to convert the value.
Reply