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

How to read a 24-bit signed signal from VHDL block fed in Nios II system - always +ve

HI, I have a very simple question but I have no idea what went wrong. Basically I have a 24-bit signed signal from VHDL block fed into Nios II system. I use C code for NIos II system. This is my code: value =IORD_ALTERA_AVALON_PIO_DATA(base); to read the 24-bit signed signal. I define it as alt_32 value=0; The problem is it always give me positive value every time read from this line even though I am sure it is negative value from VHDL code. printf("\n value= %d \n", value); Any idea what went wrong??? sorry for the simple question... Thank you in advance 

0 Kudos
6 Replies
Altera_Forum
Honored Contributor I
33 Views

If I understand you correctly, you are reading a 24 bit signed value from a 24 bit port into a 32 bit signed variable then you have extend the most significant bit into bits 24 through 31. 

 

1 represented with 24 bits is 0x000001, which when read as a 32 bit number is 0x00000001 which is the same. 

-1 represented with 24 bits is 0xffffff, which when read as a 32 bit number if 0x00ffffff which is a positive value of 16777215. 

When the msb is extended into bits 24 thru 31 you get 0xffffffff which is -1.
Altera_Forum
Honored Contributor I
33 Views

 

--- Quote Start ---  

If I understand you correctly, you are reading a 24 bit signed value from a 24 bit port into a 32 bit signed variable then you have extend the most significant bit into bits 24 through 31. 

 

1 represented with 24 bits is 0x000001, which when read as a 32 bit number is 0x00000001 which is the same. 

-1 represented with 24 bits is 0xffffff, which when read as a 32 bit number if 0x00ffffff which is a positive value of 16777215. 

When the msb is extended into bits 24 thru 31 you get 0xffffffff which is -1. 

--- Quote End ---  

 

 

Hi kflynn, 

 

Thanks so much for your reply. 

 

Yes, you understand it correctly. But, there is no way for me to define it as 24 bits since the standard are alt_8, alt_16 and alt_32. Thanks for telling me that I should extend the msb from 24 bits through 31 bits . "When the msb is extended into bits 24 thru 31 you get 0xffffffff which is -1." 

 

Could you suggest to me what can be done in order to extend the msb from 24 bits through 31 bits in C code? I program the Nios in C code. Any link or resources would be much appreciated, really thanks for your precious time. 

 

Thanks in advance.
Altera_Forum
Honored Contributor I
33 Views

Multiple ways, 

 

alt_32 n; 

// read the 24 bit signed signal 

n = read_port; 

// if the sign bit is set extend it to bit 31 

if (n & 0x08000000) 

n |= 0xf0000000; 

 

Is the pio module your custom vhdl code or is it a qsys library module?
Altera_Forum
Honored Contributor I
33 Views

The easiest way to sign extend a number is: 

 

wire numAs24 = -24'd1245 wire numAs32 = {{(8){numAs24}},numAs24};  

 

Granted the above is in Verilog, but it should be easy to turn it into the equivalent VHDL. Basically all it does is copy bit 23 into all of the upper bits.
Altera_Forum
Honored Contributor I
33 Views

 

--- Quote Start ---  

Multiple ways, 

 

alt_32 n; 

// read the 24 bit signed signal 

n = read_port; 

// if the sign bit is set extend it to bit 31 

if (n & 0x08000000) 

n |= 0xf0000000; 

 

Is the pio module your custom vhdl code or is it a qsys library module? 

--- Quote End ---  

 

 

Thanks kflynn for your reply... To answer your question, it is the standard qsys pio module. 

 

If I understand correctly, guess it is typo from you? it should be as follow: 

 

if (n & 0x00800000) n |= 0xff000000; 

 

Please correct me if I am wrong, thank you!
Altera_Forum
Honored Contributor I
33 Views

Yes that was a typo and yours is the correct version. 

 

Is the qsys generated hdl file your top level or do you instantiate it in another source file. If you instantiate it in another file you can use the idea from TCWORLD to sign extend the reading in the hardware automatically. Then your reads of the 24 bit signal will always be extended to 32 bits. 

If the qsys output is named MyNios then a top level file would work like this 

 

constant cA2dDataBusMSB :natural := 23; 

constant cNiosBusMSB : natural := 31; 

 

sAdcData(cA2dDataBusMSB : 0 <= adc_pins(cA2dDataBusMSB downto 0); 

 

-- Bridge the difference between the NIOS bus width and the ADC bus width. 

BridgeBus: 

for busbit in 1 to (cNiosBusMSB-cA2dDataBusMSB ) generate -- Generate 8 bits 

sAdcData(busbit+cA2dDataBusMSB ) <= not adc_pins(cA2dDataBusMSB); -- replicate bit 23 onto bits 24 through 31. 

end generate; 

 

Hope this helps
Reply