Nios® II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
12421 Discussions

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

Altera_Forum
Honored Contributor II
1,074 Views

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 II
113 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 II
113 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 II
113 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 II
113 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 II
113 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 II
113 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