Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers

Number Scaling

Altera_Forum
Honored Contributor II
2,800 Views

Hi, 

 

What is the most efficient way to scale numbers into the range of -1, 1 in Verilog using Cyclone II? That is the fastest code with least resources? are there any free IP cores from Altera or others which do so? 

 

I am currently doing it using the NIOS II processor (scaling and casting into fixed point), Is there any hardware solution? 

 

I have downloaded an IP core from IP genious which casts from FP to int, this will do the trick to convert to fixed point and shifting, all that remains now is the scaling?? 

 

thanks
0 Kudos
11 Replies
Altera_Forum
Honored Contributor II
784 Views

 

--- Quote Start ---  

 

What is the most efficient way to scale numbers into the range of -1, 1 in Verilog using Cyclone II?  

--- Quote End ---  

You do not state the numeric format that you are using. 

 

The conversion of signed fixed-point B-bit integers to fractional integers is conceptual only, so no conversion is required. 

 

For example, a 3-bit signed integer has can represent the integer values -4, -3, -2, -1, 0, 1, 2, 3, with 2's compliment binary representation 100b, 101b, 110b, 111b, 001b, 010b, 011b. In fractional integer format, this is a Q2.0 number. 

 

You can divide this number by 2 to get a Q1.1 representation, i.e., -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, or divide by 4 to get a Q0.2 representation, i.e., -1.0, -0.75, -0.50, -0.25, 0.0, 0.25, 0.50, 0.75. 

 

In all cases, the binary representation is the same (ok, there's a slight difference in that you can put a binary-point between the bits, but that does not exist in the hardware implementation). 

 

If you want a B-bit number to represent -1.0 to (almost) 1.0, then you just need to interpret it as a Q0.(B-1) fractional integer format number. It will have the range -1.0 to 1.0-1/(2^(B-1)). 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
784 Views

Hi Dave,  

Thanks .. 

 

The thing is that I have a random Integer input in the 0 - 579 range, without any fractions, simply integers :) ...(xmin-xmax)  

 

This need be scaled to the -1 to 1 range (ymin-ymax) following this rule  

y = (ymax-ymin)*(x-xmin)/(xmax-xmin) + ymin; 

In my application it is: 

y = (2*x)/579-1 

 

So based on what you said, to implement the above formula, all I need to do is shift my integer 10 bits to the right?? and then subtract one? 

 

Note that the following Hardware stages are in signed fixed point format with <S, M, N> = <1 sign,5 integer,10 fraction>, is the result readily available for use in the following stages?? or scaling is further needed? 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
784 Views

Apologies to Dave 

if I understood the original post, you want 0~579 represented as 

-1 ~ +1 onto 16 bits signed. Here is my magic formula: 

 

y = x*113 - 32767 ... thats all 

 

 

Explanation: 

 

y = x * (2^16-1)/579 - 32767.5 

 

= x*113 - 32767 

 

accuracy is affected by value 113 and losing .5 of 32767.5 but can be improved by multiplying by larger than 113 then shift dividing.
0 Kudos
Altera_Forum
Honored Contributor II
784 Views

 

--- Quote Start ---  

 

The thing is that I have a random Integer input in the 0 - 579 range, without any fractions, simply integers :) ...(xmin-xmax)  

 

This need be scaled to the -1 to 1 range 

 

--- Quote End ---  

What is the data being generated from? And what is being done to it afterwards? 

 

If the number is being filtered or processed, perhaps you don't need to change the input, but rather, change the filter gain, so that the filtered number has the right power levels. 

 

A method like the one Kaz suggested should work fine. If you want more accuracy in the least-significant bits, then as he suggests, just add more bits. 

 

If you can describe what you are doing, we can probably give you alternative solutions. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
784 Views

Hi,  

 

Sorry for late reply .. got busy with another HW problem! 

 

Well, the data represents the number of black pixels in certain zones in a binary image .. 

The data is an input to a neural network for classification which requires a normalized input in the range of -1 to 1! 

 

Well, i tried Kaz's method in C, the fixed point representation as displayed in hex format doesn't match the value!! What I did is multiply the floating point number by 1024 (10 bit fraction accuracy) and cast to integer .. it didn't match :S 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
784 Views

 

--- Quote Start ---  

 

Well, the data represents the number of black pixels in certain zones in a binary image .. 

 

The data is an input to a neural network for classification which requires a normalized input in the range of -1 to 1! 

 

--- Quote End ---  

Ok, thanks. 

 

 

--- Quote Start ---  

 

Well, i tried Kaz's method in C, the fixed point representation as displayed in hex format doesn't match the value!! What I did is multiply the floating point number by 1024 (10 bit fraction accuracy) and cast to integer .. it didn't match 

--- Quote End ---  

Why don't you post a couple of examples of the number of black pixels, the corresponding value in floating-point normalized to between -1.0 and 1.0, and then the corresponding 10-bit Q0.9 format number. 

 

I suspect by the time you repeat this, you will realize your mistake. 

 

Cheers, 

Dave
0 Kudos
Altera_Forum
Honored Contributor II
784 Views

you need to explain when you say it does not match the value, which value? Accuracy can be increased by better rounding the term: 

(2^16-1)/579 which = 113.18652849740932642487046632124... 

e.g. maultiply by 2^10 = 115903.005 = 115903 then truncate 10 LSBs from result then subtract 32767. 

Your format of 1 sign 5 integer 10 fraction is not covered in above equation as I assume 1 sign 15 fraction since you hardly need 1 bit for integer(-1 ~ +1)
0 Kudos
Altera_Forum
Honored Contributor II
784 Views

Hey,  

 

Sorry for late reply .. !! Got connection problems!! 

I needed the 1 sign 5 integer and 10 fraction format for many of the numbers are to be multiplied with each other and summed .. possible sequential summation needed the integer part for it well goes beyond the -1, 1 range :) 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
784 Views

for 10 bit fraction use this: 

y = x * (2^11-1)/579 - 2^10 

 

the term (2^11-1)/579 = 3.53540..... 

to reduce error multiply this fraction by 2^13 => 28962 

then discard 13 lsb and then subtract 1024 from result
0 Kudos
Altera_Forum
Honored Contributor II
784 Views

Thanks kaz .. thanks all .. it's working like a charm .. all my system is :)

0 Kudos
Altera_Forum
Honored Contributor II
784 Views

try writing a 'mapping' function maybe.. the idea is to take a string of numbers and map them to a range. 

 

ex: 

 

map(0, 1023, 0.0 , 8.0) // takes any positive integer in 0-1023 range // and maps it to a float in range 0.0 - 8.0..
0 Kudos
Reply