Int to float - Page 1
Forum section: electronics / general

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 26, 2021, 08:26:17 am
content: Hi,I want to know if you know an open source integer to float HDL code

author: Daixiwen
author_rank: Frequent Contributor
timestamp: January 26, 2021, 08:54:36 am
content: Opencores has an FPU project (https://opencores.org/projects/fpu) that includes int to float and float to int conversions, in addition to floating point operations

author: gnuarm
author_rank: Super Contributor
timestamp: January 26, 2021, 09:13:39 am
content: If you have hardware that is working on floating point numbers, the conversion between ints and floats can be done using that same hardware. To convert an int to float you just need to find the highest bit set to a 1 and assure that bit is shifted to the msb of the mantissa, which is actually a hidden bit in the IEEE format. The exponent is set according to this shift count. This is an operation that has to be done at the end of every floating point addition, renormalizing the result.Converting from float to int is the initial step of a floating point addition, denormalizing the mantissa to match the exponents. In the case of a float to int conversion the idea is to denormalize the mantissa to achieve an exponent of zero.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 26, 2021, 09:32:19 am
content: QuoteThanks, I have seen this, but it lacks the int to float and float to int, in the codes, it's just in the description

author: BrianHG
author_rank: Super Contributor
timestamp: January 26, 2021, 11:19:50 am
content: If you are using Quartus, there is a LPM function for it, both directions.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 26, 2021, 11:57:49 am
content: QuoteThanks, I'm using gowinIs there any good open source out there?

author: BrianHG
author_rank: Super Contributor
timestamp: January 26, 2021, 04:45:08 pm
content: How many bits?Which float format?

author: Wiljan
author_rank: Regular Contributor
timestamp: January 26, 2021, 08:25:10 pm
content: Intel / Altera does have a cookbook with examples and there are many nice cool codeshttps://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/manual/stx_cookbook.pdfand the codehttps://github.com/thomasrussellmurphy/stx_cookbookThe one you might look for "fixed_to_float.v"Code:module fixed_to_float (fixed_sign,fixed_mag,float_out);parameter FIXED_WIDTH = 8; // must not be > 32parameter FIXED_FRACTIONAL = 4;input fixed_sign;input [FIXED_WIDTH-1:0] fixed_mag;output [31:0] float_out;wire [7:0] exponent;wire [31:0] unscaled_mantissa = fixed_mag << (32-FIXED_WIDTH);wire [31:0] scaled_mantissa;wire [4:0] scale_distance;scale_up sc (.in(unscaled_mantissa),.out(scaled_mantissa),.distance(scale_distance));defparam sc .WIDTH = 32;defparam sc .WIDTH_DIST = 5;assign exponent = 8'd127 + (FIXED_WIDTH-FIXED_FRACTIONAL) - 1- scale_distance;// Zero is special and gets an exponent of 0, not "something very small"assign float_out = &scale_distance ? {fixed_sign,31'h0} :{fixed_sign, exponent, scaled_mantissa[30:8]};endmodule

author: BrianHG
author_rank: Super Contributor
timestamp: January 26, 2021, 08:52:25 pm
content: Quote from: Wiljan on January 26, 2021, 08:25:10 pmThe source code for module 'scale_up' is missing in your example.

author: Wiljan
author_rank: Regular Contributor
timestamp: January 26, 2021, 10:28:29 pm
content: Code:module scale_up (in,out,distance);parameter WIDTH = 16;parameter WIDTH_DIST = 4;input [WIDTH-1:0] in;output [WIDTH-1:0] out;output [WIDTH_DIST-1:0] distance;wire [(WIDTH_DIST+1) * WIDTH-1:0] shift_layers;assign shift_layers [WIDTH-1:0] = in;genvar i;generatefor (i=0;i<WIDTH_DIST;i=i+1)begin : shftwire [WIDTH-1:0] layer_in;wire [WIDTH-1:0] shifted_out;wire [WIDTH-1:0] layer_out;assign layer_in = shift_layers[(i+1)*WIDTH-1:i*WIDTH];// are there ones in the upper part?wire shift_desired = ~|(layer_in[WIDTH-1:WIDTH-(1 << (WIDTH_DIST-1-i))]);assign distance[(WIDTH_DIST-1-i)] = shift_desired;// barrel shifterassign shifted_out = layer_in << (1 << (WIDTH_DIST-1-i));assign layer_out = shift_desired ? shifted_out : layer_in;assign shift_layers[(i+2)*WIDTH-1:(i+1)*WIDTH] = layer_out;endendgenerateassign out = shift_layers[(WIDTH_DIST+1)*WIDTH-1 : WIDTH_DIST*WIDTH];endmodule

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 27, 2021, 12:05:02 am
content: Not necessarily what you're looking for, but it's interesting to note that VHDL-2008 comes with packages which support fixed point and floating point, both supposed (from the standard) to be synthesizable!For instance, there is the 'float_generic_pkg', which supports many FP operations, including a series of 'to_float' functions.I don't know how well this is supported by FPGA tools though, knowing that full VHDL-2008 support is not always that great to begin with. I'll have to try that one of these days.

author: BrianHG
author_rank: Super Contributor
timestamp: January 27, 2021, 01:19:09 am
content: Remember my question...Quote from: BrianHG on January 26, 2021, 04:45:08 pmIf you have a <24bit int to 32bit 754 float, it's just a direct wiring + fixed wired exponent + the polarity bit.Same goes if you have a <53 bit int going to a 64bit float. (IE, no converter needed.)If your int is signed, you just need to invert the 2's complement when negative and feed the polarity bit.(If I remember correctly, 754 uses absolute value + the polarity, not 2's compliment. This also means 1 extra bit on the int side. IE, a 24bit ADC feeds a 32 bit float without loss, almost directly wired.)This is why I hate it when the OP doesn't specify anything at all...

author: gnuarm
author_rank: Super Contributor
timestamp: January 27, 2021, 02:43:49 am
content: Quote from: BrianHG on January 27, 2021, 01:19:09 amYes, IEEE floating point is sign magnitude with a biased exponent. You can't just direct connect an Integer format data to the mantissa of the floating point number. In floating point the mantissa is left justified and in IEEE the most significant 1 is assumed. So the shift is variable depending on where the most significant 1 bit is. That also impacts the exponent.I am currently designing a floating point math unit and converting to and from Int is the easy part, just just treat it like the appropriate portions of the ADD instruction that has to denormalize the mantissa before the ADD or normalizes the result after the ADD operation.

author: BrianHG
author_rank: Super Contributor
timestamp: January 27, 2021, 03:51:06 am
content: Quote from: gnuarm on January 27, 2021, 02:43:49 amYes, this is the correct way to assure the maximum definition.I could have sworn that fixing the exponent so that is it a fixed +23 bit integer offset and filling in the mantissa with a 23 bit integer number would still work so long as you do not go any larger than 23 bits. Otherwise a hidden bit 24 would always be assumed to be 1 no matter what and 0 would be impossible unless there is a specific pattern for 0 which I completely forgot about. Maybe it had something to do with the old assembly PIC16 floating point math routines I used from 20 years back that certain exceptions were accommodated.

author: ejeffrey
author_rank: Super Contributor
timestamp: January 27, 2021, 05:06:29 am
content: Quote from: BrianHG on January 27, 2021, 03:51:06 amIn IEEE floating point there aren't multiple representations of the same value (except for NaNs) although -0 is distinct but equal to +0. If the exponent is non-zero a leading 1 is implicit. If the exponent is all zeros then you have a denormal number which doesn't have an implicit leading 1. Thus conveniently the all-bits-zero pattern is also floating point zero.Non-zero integers are never denormal so there is no need to worry about that, just handle zero specifically. If the number is zero just output zero. Otherwise find the first one and shift it into position 24 (the implicit leading 1 that will be dropped when packed into the output register)) and set the exponent based on how far you had to shift.

author: BrianHG
author_rank: Super Contributor
timestamp: January 27, 2021, 05:55:42 am
content: Quote from: ejeffrey on January 27, 2021, 05:06:29 amThanks. Forgot that there was an implied hidden 1 always there.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 27, 2021, 07:18:27 am
content: Thanks for all the feedback,Actually I have two scenarios in my design, first one is easier, I got 24 bit data from ADC, and I want to convert it to Float (32bit),BrianHG I'm not sure if a direct connection from 24bit (23bit + 1sign bit) to float is possible, do you have any sample code?Also I have a nice Cordic design from Zicpu, that would produce 32bit results for me, I wanted to convert the output of this module to Float (32bit) too. this Cordic core from Zipcpu have a max frequency of around 100MHz in gowin, I wonder if there are cores that have better speed performance.I like opensource designs, Gowin has Cordic core, But I prefer opensource

author: gnuarm
author_rank: Super Contributor
timestamp: January 27, 2021, 08:13:56 am
content: So you want to convert values to float, but not do any math on them? Is this data going to a CPU with floating point capability? Why not let the CPU do the conversion?I guess my point in talking about how to do the conversion is that this is not hard code to write. It consists of a priority encoder and a barrel shifter. An integer multiplier can be used as the barrel shifter. The exponent is just the priority encoder output subtracted from a constant. As someone else has mentioned the mantissa must be positive. So if your CORDIC output is signed, it needs to be complemented for negative values. Do you think you can't write this easily enough?

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 27, 2021, 08:25:44 am
content: I have written some DSP stuff in float inside FPGA and they are working as expected, also the end result should got to Cortex M7 for further process, because this algorithm is so math intensive, I decided to do some parts of it inside the FPGA, since it has enough room and it's relatively cheap, I can get gowin with 20K lut and 48 DSP and 48 Block ram and 32MB Internal SDRAM under 5$, so why not.I have written a test bench for the Wiljan code sample,But it seems it has wrong results, in positive and negative numbers,Sample Test bench,Code:module fixed_to_float_tb ();parameter MAIN_CLK_DELAY = 20; // 25 MHzreg r_Rst_L = 1'b0;reg r_Clk = 1'b0;// Clock Generators:always #(MAIN_CLK_DELAY) r_Clk = ~r_Clk;reg [31:0] r_a;wire [31:0] w_Out;fixed_to_float DUT(.fixed_sign(r_a),.fixed_mag(r_a[30:0]),.float_out(w_Out));initialbeginr_Rst_L = 1'b1;repeat(1) @(posedge r_Clk);r_Rst_L = 1'b0;repeat(3) @(posedge r_Clk);r_a = 32'd1250302788;repeat(1) @(posedge r_Clk);r_a = 32'd8388608;repeat(1) @(posedge r_Clk);r_a = 32'd536870911;//32'h1fffffff;repeat(1) @(posedge r_Clk);r_a = 32'h00000001;repeat(1) @(posedge r_Clk);r_a = 32'd2147483520;//32'h7fffff80;repeat(1) @(posedge r_Clk);r_a = 32'd2147483584;//32'h7fffffc0;repeat(1) @(posedge r_Clk);r_a = 32'h80000000; //-2147483648repeat(1) @(posedge r_Clk);r_a = 32'h80000040;//-2147483584repeat(1) @(posedge r_Clk);r_a = 32'hffffffff;//-1repeat(1) @(posedge r_Clk);r_a = 32'h00000000;end // initial beginendmodule// parameters of the code,Code:parameter FIXED_WIDTH = 31; // must not be > 32parameter FIXED_FRACTIONAL = 0;For example this input 1250302788 should produce 0x4e950c37, But it would produce 0x4e950c36, I know it's small value, But I want a perfect int to float conversion, since I would do lot's of float add and Mul, and it would increase the error.I will test my data and it's result with this online calchttps://www.h-schmidt.net/FloatConverter/IEEE754.html

author: BrianHG
author_rank: Super Contributor
timestamp: January 27, 2021, 12:09:36 pm
content: Quote from: ali_asadzadeh on January 27, 2021, 08:25:44 amNot possible unless your integer is only 24bits ~16million high, or, you are using 64bit double.Computer 32 bit floating point only stores 24bits as described here:It gets worse if you add a full 16million value 24bit integer with a fraction. That fraction will usually disappear.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 27, 2021, 04:35:38 pm
content: Quote from: ali_asadzadeh on January 27, 2021, 07:18:27 amI don't see any reason for converting to floats. All you describe can be done in (scaled) integers. Will work faster and will take less logic.24-bit ADC cannot be very fast, so you should be able to keep up with it even if you do floats.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 28, 2021, 01:06:16 pm
content: QuoteMy algorithm is like this, I have 8 channels of 24bit simultaneous ADC with 16Ksps each, I need to do a 256 point FFT on each adc channel, compute phase and amplitude from FFT using cordic, also compute RMS on a 256 sample windows on each channel, also I need to calculate a division to find the ratio between the first and second harmonics of each channel from FFT, and finally I should pass the phase and amplitude to a 16 point calibration unit (it will use a float MUL and ADD something like m*x + a), which basically curve fit (interpolate) to a line, so the final result is calibrated,and please note that all these calculations should be repeated at 16Ksps for each new sample that comes in, since the Cortex M7 should decide to do some fast decisions based on the results of all these calculations and all ADC channels are sampled at the same time.your points are correct, But I do not know how to convert my whole algorithm to fixed point to be used, since the final results should be in floating point, because the customer/user would use these values for setting the parameters for CM7 algorithm. which are a lot of parameters(in the order of 500 variables)

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 28, 2021, 02:55:27 pm
content: All of this can be done with fixed point indeed.Off-loading the fixed-point to floating-point to the "client" MCU would make more sense. It would add only marginal complexity on the MCU's side.Not sure how you intended to make all of this work, but if providing end values in FP is the goal and you can't have the customer make the above modication, then doing everything in fixed point in the FPGA and only converting the end values to FP, instead of computing everything in FP, would take fewer resources on the FPGA.To begin with, surely you didn't intend on implementing a FP FFT? So your FFT outputs are NOT FP? Or did you?

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 28, 2021, 03:30:34 pm
content: The FFT and CORDIC are fixed point, the result of CORDIC should convert to float, and the harmonics ratio division, and curve fitting should be done in float, But if I know how it can be done in fixed point, it would help a lot. since my floating coefficient for curve fitting are like this.These are real numbers that I have measured,For example Suppose that the input to the calibrate function is called data and I should use a line formula for curve fitting, Data is 32bit integer from CORDIC, (it's magnitude) ,I calculate result with this formularesult = 4.5453* data + 0.0034128;or the first harmonic Mag from CORDIC is 1950345 and the second harmonic is 45338, so the ratio is like this45338/1950345 = 0.0232461436How these two formulas (the first one a MUL and an ADD and the second one only a DIV) can be done in fixed point?

author: ejeffrey
author_rank: Super Contributor
timestamp: January 28, 2021, 03:51:26 pm
content: If I understand you correctly my first approach here would be to do up through the FFT and the 256 sample mean square in fixed point on the FPGA and then pass the results to the MCU that does the float conversion and final analysis. It sounds like you are only using a few points out of the FFT like a fundamental and one or more harmonics?With a bigger FFT I would prefer to do floating point but for only 256 points it's not a big deal. Quantization noise will be in the ~29th bit. In principle a floating point FFT would let you get that much dynamic range while still using 24 bit multipliers but chances are your noise floor is nowhere near there anyway. If you were limited to smaller multipliers than 24 bit a floating point algorithm might let you conserve dynamic range and multiplier resources at the cost of additional complexity and LUT logic.Doing 255 point overlap is usually overkill. You could probably get away with doing the FFT only after every 64 new samples, but if your customer wants to redo the full fft every sample you may not have a choice.I didn't see a windowing step, you probably need one.

author: BrianHG
author_rank: Super Contributor
timestamp: January 28, 2021, 03:53:22 pm
content: Doing it the manual way:The divides become multiples of a factor left shifted by 24 or 32 bits, then after an integer multiply, the results are right shifted by 24 or 32 bits.IE, your fractional factors are multiplied by 16777216 or 4294967296, the the result after the multiplication is right shifted/or use the upper bits of the result.IE: 32bits X 32bit actually has a 64bit result. You are just using the top 32 bits of the result as your new bottom 32bits.Unless you want a 64bit accumulation in you core instead of a 32 bit. This would actually have even more precision than summing floats which only have 24bits of precision.

author: BrianHG
author_rank: Super Contributor
timestamp: January 28, 2021, 04:04:29 pm
content: Quote from: ali_asadzadeh on January 28, 2021, 03:30:34 pmExample:result = ( (4.5453*16777216) * data + (0.0034128*16777216) ) >> 24;...2^24=16777216or, use 2^32=4294967296 in place of 16777216 to get extra precision.However, when doing this in C, make sure you are using 64bit ints as 32bit will shave off the MSBs.This is not a problem in an FPGA...

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 28, 2021, 08:15:26 pm
content: BrianHG thanks for clarification,So lets consider a real example,Suppose the data is 1950345 , and we would use 32bit's ie 4294967296So you say I do it like this(4.5453*4294967296) * 1950345 + (0.0034128*4294967296) >> 32?So the final result is like this19521914850 * 1950345 + 14657864 = 38074469032781114‬ >>32so the final result using fixed point is this 8864903and if I use floating point I would get this4.5453*1950345 + 0.0034128 = 8864903.1319128‬it's good enough, for this high data input,Now a lower input datafor example Data = 123float version4.5453*123 + 0.0034128 = 559.0753128The fixed point version(4.5453*4294967296) * 123 + (0.0034128*4294967296) >> 32equals to 19521914850 * 123 + 14657864 = 2401210184414 >>32 = 559still not bad,And finally something lower4.5453*23 + 0.0034128 = 104.5453128The fixed point version(4.5453*4294967296) * 23 + (0.0034128*4294967296) >> 32equals to 19521914850 * 23 + 14657864 = 449018699414 >> 32 = 104if I put a lower data as input the final result may miss some information, is there a workaround?also regarding resource usage, is it lower than float version? since I have found a FPU MUL unit that uses around 210Luts and 4 DSP slices, it's in opencores.How about calculating the ratio division for finding the (second harmonic) / (first harmonic )like these sample numbers from the CORDIC core45338/1950345 = 0.0232461436How should I do this calculation?

author: NorthGuy
author_rank: Super Contributor
timestamp: January 28, 2021, 10:46:41 pm
content: When you do the calculation, you don't need to always shift by 32 (or 24). Say, if you multiply 2 32-bit numbers, you can get higher precision if you shift right by 24 instead of 32 (but the result will be longer - 40-bit instead of 32). So, you write down all your formulae, and for every item in your calculation you decide how much it is shifted, and by selecting the shifts you make sure you get the desired precision.If you go to floats, you basically give up your privilege of selection what shift is used. Instead, for every number you store, you also store another number (called exponent) which shows how much the number is shifted. These are floats - a pair of numbers - mantissa and exponent. This doesn't guarantee any accuracy and you lose control of the shifts. Thus achieving the desired accuracy becoming more difficult. What do you get in return - you get a hardware FPU which can process floating numbers very quickly.There's no FPU in FPGA, so there's no benefits in using floating numbers. Instead, there is an overhead. For example, if you need to add two numbers, you need one (or two) barrel shifters to align the numbers to each other, only then you can add. This is unnecessary overhead. In contrast, fixed shift costs nothing in FPGA.The division requires lots of resources and will be very slow - it is slow in MCUs too - whether you use floating point or fixed integers. Technically you approach is the same as multiplication.A/B = A*4294967296/B >> 32.

author: BrianHG
author_rank: Super Contributor
timestamp: January 28, 2021, 11:08:54 pm
content: I'm assuming:4.5453* #That the ' # ' is the 24bit adc. Remember, you have chosen 32/64bits, you can always left shift the ADC by 8 bit (making the ADC source 32bit), IE multiply by 256. This means the data out is 0,256,512,1024... And if 123 is still not bad, you will have double that minimum precision on the output as the ADC number of +/-1, which will now be +/-256, more than twice your 123. If after all the combined filtering, if you want 24 bit out, you can just divide the result by 256.This is just another round about way of 'NorthGuy' post just 1 above, when choosing the bits of precision, you may control the shift.

author: BrianHG
author_rank: Super Contributor
timestamp: January 29, 2021, 02:39:17 am
content: Quote from: NorthGuy on January 28, 2021, 10:46:41 pmWell, since we are obviously talking about bit shifting.....A/B = ((A<<32)/B) >>32.I think to get a reasonable fmax, a 64bit int divided by a 32bit int would have something like at least a 11 clock latency if not double. However, this is not bad if your code is piping in a stream of uninterrupted divides.

author: gnuarm
author_rank: Super Contributor
timestamp: January 29, 2021, 06:55:29 am
content: Quote from: BrianHG on January 27, 2021, 03:51:06 amThere's nothing to say you couldn't do this for an arbitrary floating point format. In IEEE format the hidden '1' will muck up the value.

author: gnuarm
author_rank: Super Contributor
timestamp: January 29, 2021, 07:51:16 am
content: Quote from: NorthGuy on January 28, 2021, 10:46:41 pmI can't follow that reasoning. You don't give up any control, you simply have it done automatically to preserve the maximum resolution possible rather than storing a bunch of leading zeros. Since the exponent takes bits, the question is it better to use some of the bits for an exponent extending the range or is it better to use them as more significant bits? I think the examples shown indicate the preference is for the exponent.QuoteAgain, I don't follow. Floating point takes more hardware, but if that is what is required, that's what is required. A shift is also known as a multiply. I'm working a design now that is using a single 36 x 18 multiplier for a non-IEEE math unit. It will iteratively do the denormalize, the operation and the normalize. For a multiply there is no denormalize of course, but all three steps use the same multiplier. I have to add an optional shift by 18 at the output to handle the full range of possible shifts. For math the two mantissas are fed into the multiplier. For shifting one of the inputs is a shift parameter with a single 1 and the rest zeros.If you need to do this without iteration it needs three multipliers. Yes, more hardware, but most multipliers in FPGAs go unused anyway. If the processing is not every clock cycle, then iterative conversions are practical.QuoteI think the hard part of this is the divide. I'm using an Newton-Raphson iteration. In my case I only need 18 bits of resolution. A single block RAM will give me a seed accurate to at least 9 bits and one turn of the NR crank gives me 18 bits. IEEE 32 bit format resolution requires a second turn of the NR crank. The significant bits double on each iteration so it converges quickly. These iterations are not on full floating point words, just the mantissas, or the integers if you want fixed point.Oh, almost forgot. NR calculates the inverse of D, so you still need to multiply the N by this inverse, but again just the mantissa, not a full floating point multiply.I believe for NR you need to start with values between 0.5 and 1 or 1 and 2 depending on how you look at it. So a sort of denormalization and normalization has to happen in fixed point as well I expect. I haven't really considered the fixed point option so much.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 29, 2021, 10:08:02 am
content: Thanks for the points BrianHG, do you recommend any DIV algorithm?gnuarm thanks for your feedback, is your FPU open? can we take a look at it?

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 29, 2021, 02:58:03 pm
content: Quote from: ali_asadzadeh on January 29, 2021, 10:08:02 amIf a latency of N bits is OK, you can implement a basic restoring, or non-restoring division:https://en.wikipedia.org/wiki/Division_algorithmThey are pretty simple to implement in HDL.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 29, 2021, 07:33:27 pm
content: Quote from: gnuarm on January 29, 2021, 07:51:16 amFloatiung point has some mantissa size, say 23-bit for singles. With scaled integers you have full control over the size of the numbers. For example, you can do multiple MACs accumulating the result. You get better precision if your use longer accumulator then chop it off at the end.You certainly can do the same with floats - say use 64-bit IEEE floats for accumulator. So, you will have to convert arguments from 32-bit floats to 64-bit ones then do the MAC. This is lots of unnecessary work, you can try to simplify it. In the process of the simplification you'll come to a simpler solution - scaled integers.Quote from: gnuarm on January 29, 2021, 07:51:16 amRequired? By whom? Sure there may be situations where floats are extremely beneficial, such as inversion of nearly singular matrices. But such situations are rather rare. The majority of DSP tasks can be done without floats faster and with less resources.

author: gnuarm
author_rank: Super Contributor
timestamp: January 30, 2021, 12:28:55 am
content: Quote from: ali_asadzadeh on January 29, 2021, 10:08:02 amYeah, it's part of an open source project to build a ventilator, but it's not code yet. It's still block diagrams and Forth evaluation code.

author: gnuarm
author_rank: Super Contributor
timestamp: January 30, 2021, 12:48:35 am
content: Quote from: NorthGuy on January 29, 2021, 07:33:27 pmSorry, I have no idea what you are talking about. You seem to be constructing examples to prove a point, but the examples are not part of any problem anyone is trying to solve.QuoteThe OP has provided an example where the final result does not have enough resolution when using integers. I don't want to put words in your mouth, but I expect you might say he could extend the precision of the intermediate fixed point computations to get more resolution in the result... or I suggest he can use floating point. Either way uses more hardware than a simple fixed point approach. Which is better? Depends on the details.I chose float because I need to handle a wide range of data using the same hardware. Some of the computations are specified with constants of A*10^-6 and such so that I just got tired of trying to track the durn scale factors. It was going to be harder to manage the tracking in fixed point than it is to just build the durn floating point hardware. The division algorithm requires normalization and keeping track of a real time scale factor which is essentially the same as floating point, so it is not really so large a leap to just use the durn floating point and give up on the manual scaling.Here is an example of the calculations I've been asked to perform.

author: gnuarm
author_rank: Super Contributor
timestamp: January 30, 2021, 12:55:44 am
content: Image didn't load correctly, let's try again.Freaking Google Drive is so retarded. They can't just give you a link to a file with a file name and an extension.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 30, 2021, 02:43:14 am
content: Quote from: gnuarm on January 30, 2021, 12:48:35 amIt doesn't work that way. Say, OP has 24-bit ADC readings. This is a 24-bit integer. What happens to the precision when you convert it to 32-bit floats which have 23-bit mantissa. For the upper half of the range (8388608 to 16777215), you lose one bit of resolution. 24-bit become 23-bit. For the lower half of the range, the resolution is increased. Say, for ADC reading of 1, floating point presentation adds 23 zeroes, which are totally meaningless.When you perform linear transformation, such as FIR or FFT, it stays that way. Floating point numbers provide excess resolution for smaller values, and at the same time truncate resolution for larger numbers. Moreover, there's rounding error, which accumulates, so the more calculations you do, the more resolution you lose. The end result - you do more calculations, and get less resolution.In contrast, integers have the same resolution accross the scale - if ADC measures to 1 mV, integers will give you your 1 mV resolution whether you measure 10 mV or 1000 V.Quote from: gnuarm on January 30, 2021, 12:48:35 amI don't think this is an example of wide range of data. Wide range would be if the flow was changing between fractions of ml and millions of liters. Even then, 32-bit integers give you a very large range - you can represent up to roughly 4000 l/s with 1 ul/s resolution. This is way beyond what is practically needed.Most of the constants have very modest effective resolution, probably somewhere around 16 bit, which means that the required accuracy of the final calculations is somewhere in the same range. So you wouldn't need big integers anyway.There's a lot of other things that can be done to simplify the formulae. For example, the majority of the divisions are divisions by a constant which can be replaced with multiplications.Of course, you can just grab floating point libraries and it all works off the bat, especially if you don't need fast calculations and use an FPGA with tons of DSPs.

author: gnuarm
author_rank: Super Contributor
timestamp: January 30, 2021, 03:09:39 am
content: Quote from: NorthGuy on January 30, 2021, 02:43:14 amHmmm... you start off with a fallacy. IEEE 32 bit floating point has 24 significant bits in the significand.https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_single-precision_binary_floating-point_format:_binary32So I guess you'll need to invent a 25 bit input to make this argument. But it's not terribly relevant. In an FPGA the significand can be 25 bits, or 20 bits or any number you want. This is not a CPU where you are stuck with whatever the CPU gives you.QuoteWhen you do math, there can be growth of the bits. Addition can produce what you would call overflow but in a floating point is called an addition.QuoteUntil you do an operation that exceeds the range or do a divide that requires fractions which have to be truncated. What is 2,000,000 divided by 3,000,000 in fixed point? Zero. Oh, adjust the radix point in your head and its... 0.666,667, but now we have to track the moved radix point outside the real time calculation. Even then the same point in the calculations might produce 0.000,007 and we have lost significant resolution.Quote from: gnuarm on January 30, 2021, 12:48:35 amI don't think this is an example of wide range of data. Wide range would be if the flow was changing between fractions of ml and millions of liters. Even then, 32-bit integers give you a very large range - you can represent up to roughly 4000 l/s with 1 ul/s resolution. This is way beyond what is practically needed.Please show me how to do these calculations in fixed point. I didn't say they could not be done. I said it was too big a PITA to bother with. Much easier to design the floating point hardware (which really isn't that big a deal) than to try to manage the scale factors to track all the calculations. This is just one of several. It is by far the most complex, but others have divides and subtractions that result in the classic small difference between two large numbers.One that isn't shown is a quadratic correction for temperature. So T in °K has to be squared and multiplied by a coefficient in the ppm range. Rather ugly in fixed point. Each one of these calculations requires shifting to manage the radix point which you seemed to think was a downside of floating point. The reality is floating point is doing exactly the same thing as fixed point, it's just doing it automatically without my being involved in planning it.QuoteIf they were constant divisions I would not have mentioned them. Off the top of my head I know division is used in scaling sensor readings for the calibration that is done periodically. The machine either has to do the division when it calculates the scale factor or when it uses the scale factor. Pick one. Other divides are done because that's the algorithm. The equations I showed you are full of those.QuoteThere are libraries? Oh, you mean for CPUs! Never mind.

author: hamster_nz
author_rank: Super Contributor
timestamp: January 30, 2021, 04:29:16 am
content: Maybe somebody (ie the OP) should write some code and evaluate its performance?Not HDL, just C or Python or something... they will most likely need to do this for validation of their design anyway.Maybe if they can give us a file with representative data we can write our own and report back.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 30, 2021, 05:47:24 am
content: Quote from: gnuarm on January 30, 2021, 03:09:39 amI don't know what's in the top of your head. I look at the formulae you posted. Things like "Percentage of Oxygen in Dry air" or "Molecular mass of oxygen" ...

author: BrianHG
author_rank: Super Contributor
timestamp: January 30, 2021, 12:23:57 pm
content: Quote from: NorthGuy on January 28, 2021, 10:46:41 pmHow can I be so stupid as to forget. When using a divider in HDL, do not shift bits around like that, it wastes gates and clock cycles/speed to divide a 64bit by a 32bit. The just do a 32bit divide by a 32 bit, and the output you get is the quotient, BUT, don't forget, you also get a separate 32bit 'remainder' as well without any extra gates... This is where your precision lies.Ok, early morning lemon thought... But yes, the remainder is useful.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 30, 2021, 02:49:05 pm
content: BrianHG thanks for the update, but the example numbers propose 0.0232461436How can this be done in fixed point? by multiplying the first number by 4294967296?Then after all this how should I tell Cortex M7 how to treat numbers efficiently or accept them as float? specially when the costumer has about 500 floating parameters in CM7.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 30, 2021, 03:20:31 pm
content: Quote from: gnuarm on January 30, 2021, 03:09:39 amOk. I'll try to explain. Math is done with values. What we discussing are different presentations of the same value. It's all binary, but I use decimals for clarity.Say, I have 20 dollars.Floating point: 2.0E+1Fixed point: 20.00For scaled integers, I shift the position of the decimal point to the right, by two. Another way, I measure in cents, not dollars:Scaled integers: 2000Same thing for 0.01 dollarsFloating point: 1.0E-2Fixed point: 0.01Scaled integers: 1Let's now do some math.Addition:Floating point: 2.0E+1 + 1.0E-2 = 2000.0E-2 + 1.0E-2 = 2001.0E-2 = 2.001E+1Fixed point: 20.00 + 0.01 = 20.01Scaled integers: 2000 + 1 = 2001Note how floating pint requires two extra step - a shift to align mantissas and normalization at the endMultiplication:I buy something for 205.40 cents and I need to pay 5.0% tax on it. How much is that?Presentation of the amount:Floating point: 2.054E+2Fixed point: 205.40Scaled integers: 20540Presentation of the tax rate:Floating point: 5.0E-2Fixed point: 0.05Scaled integers: 50 - I have chosen to shift right by 3 decimal points - one unit is 0.1%Multiplication proceeds as followsFloating point: 2.054E+2 x 5.0E-2 = (2.054*5.0)E(+2-2) = 10.27E0 = 1.027E+1Fixed point: 205.40 x 0.05 = 10.27Scaled integers: 20540 x 50 >>> 3 = 1027000 >>> 3 = 1027Here ">>> 3" means shift right by 3 decimal digits.Note that floating point multiplication is easy, but there's still an overhead - normalization at the end.Scaled integers require a shift. It is decimal in the example, but it is binary in hardware. The amount of the shift is the same every time. Thus, in FPGA, it's nothing more than using a different set of wires - no overhead.Division:I buy something for 205.40 cents and I need to pay 10.27 in taxes. What is the tax rate?Floating point: 1.027E+1 / 2.054E+2 = (1.027 / 2.054)E(+1-2) = 0.5E-2 = 5.0E-1Fixed point: 10.27/205.40 = 0.05 (5%)Scaled integers: 1027 <<< 3 / 20540 = 1027000 / 20540 = 50Here "<<< 3" means shift left by 3 decimal digits.Of course, here everything is dominated by the division which will take long time. Otherwise, it's the same as multiplication - normalization overhead for floats, no overhead for scaled integers.In short - you can do any math with scaled integers and it takes less operations than with floats, especially in FPGA.Dynamic range:If you have numbers which differs in magnitude, you need very long integers to represent. For example, us national debt isFloating point: 2.785208840732531E+13Fixed point: 27852088407325.31Scaled integers: 2785208840732531 (not really that big - only 52 bits)If we want to deal with smaller numbers, we can use floats and chop of precision. Say, we chop it to 6 digits after decimal point:Floating point: 2.785209E+13Fixed point: 27852088407325.31Scaled integers: 2785208840732531Now we can get away with smaller numbers (for example 32-bit floats instead of 52-bit integers), but we did this by deliberately removing resolution, so the resolution will be less (not more). Floating point numbers is an approximation.This can lead to troubles with calculations. Say, we record the debt 10 minutes later:Floating point: 2.785213E+13Fixed point: 27852126073450.61Scaled integers: 2785212607345061How much money was borrowed during these 10 minutes:Floating point: 2.785213E+13 - 2.785209E+13 = 4.000000E+7Fixed point: 27852126073450.61 - 27852088407325.31 = 37666125.30Scaled integers: 2785212607345061 - 2785208840732531 = 3766612530See what happens. Most of the digits produced by floating point calculation are totally bogus. If you just apply floating point calculations without thinking of precision, the result may be less accurate than you think, if not outright wrong.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 30, 2021, 07:08:37 pm
content: Thanks for the great example,I get most of it, expect how you decide to choose 3 for >> and << for MUL and DIV?

author: BrianHG
author_rank: Super Contributor
timestamp: January 30, 2021, 08:12:49 pm
content: Quote from: ali_asadzadeh on January 30, 2021, 07:08:37 pmI'm curious, do you know what M.N math is?Say you want a 24 bit integer with 24 bit fraction range.When you add, subtract, multiply, divide, the first 24 bits to the left of the '.' is your integer portion, the 24 bits on the right is your fraction. The difference is that all the 0/1's on the left are power of 2's, IE 1,2,4,8,16,... To the right of the decimal place, the .N, is it fractions powers of 2, IE 1/2, 1/4, 1/8, 1/16,...When doing addition/subtraction/multiplication/division, you just treat the 24bitM, 24bitN as 1 huge 48 bit integer. When getting the result from a multiply, you need to right shift the result by 48 bits to recenter the decimal point. With divide, you need to left shift the dividend by 48 bits. Addition and subtraction have no shift.It is no different in decimal math. It's just that you decided to do everything in integer, but, your integer has (decimal example) 16 digits, but, you imagine that there is a dummy decimal place in the middle, so 8 digits integer, 8 digits after the decimal point in floating point.The authentic IEE754 floating point math does the same has only the 24 bit N, but has a 8 bit exponent which tells you how to shift that N number to in binary to the left or right. For adding/multiplying... 2 small fraction in IEE754 means you will get a precise result. But, when adding/subtracting... 1 huge number with a fraction, that fraction may completely get ignored/disappear since the exponent left and right shift may be more than 24 shifts/bits apart. Exponents in binary just left and right shift the bits, IE like in M.N math, it just moves the binary decimal place. (binary exponent is 2^expwhere as in decimal, the exponent is 10^exp(This is the 'E#' on your calculator in base 10 decimal math) Now when multiplying/dividing, the exponents between a huge number and small number are first summed, then, a smaller 24bit multiply/divide is done while the new exponent is just the sum/difference of the 8bit exponents.Back to your earlier question about the what to shift. Working in integer 48bit may be good enough for your app if you target keeping that binary decimal point in the middle.My issue is where do you get a divide for GOWIN? I know all the math routines, floating point and fixed point are all available for Altera FPGAs, including sine/cos/tan/square root/complex plane multiply, but, I never had to deal with a vendor limiting my ability to do basic math before as well as int<>float conversion unless we are talking over 15 years ago.Just googling around, here is an integer and M.N fixed point divider code, but, it cannot be pipelined. You basically send it your numbers and wait for a result with an unknown number of clock cycles to compute.It does support dividing a smaller number by a larger number. (The second M.N 'FIXED' point version on the page.) You would need to implement your own negative number support, but, that's a simple task.https://projectf.io/posts/division-in-verilog/(Sorry, everything today is in SystemVerilog.)div_int is integer divide only.div -> supports a total WIDTH for your binary numbers and FIXED location FBITS which sets the location of the '.' in your M.N number with it's total WIDTH. It looks like a WIDTH of 48, and a FBITS of 24 gives you a M.N of 24bitsINT.24bitsFRACTION. (IE: You do not need to shift the dividend, it appears to be designed to deal with that fixed decimal point of the M.N style math.)Solved with the above divider in FIXED width mode so long as you have FBITS with a significant enough number above 0:Quote from: ali_asadzadeh on January 28, 2021, 08:15:26 pmSince you already have a multiply, using the fixed point M.N style, you can run your floating point number code.Using a a parameter to set the overall width and FBITS to set your fixed overall decimal point with the above divide, you can do all the math in SystemVerilog except for negative numbers in the divide function. To fix that, you need an absolute value function and to keep track of the 2 source number polarities, and flip the polarity of the output number if needed.As for FMAX and gate count, well, I never used that function, so, I do not know.Also, if the gate count is small, you can run many in parallel and cheat simulate a fixed delay pipelined version to get continuous divides on every single clock cycle, but, you may not need such speed.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 30, 2021, 09:13:34 pm
content: Quote from: ali_asadzadeh on January 30, 2021, 07:08:37 pmSay, you calculateC = A x BThe shift of C (Sc) is equal to shift of A (Sa) plus shift of B (Sb), which is, of course, the same as with floats.In the example aboveSa = 2Sb = 3ThereforeSc = Sa + Sb = 2 + 3 = 5but we wanted the shift of the result to be 2, not 5. Hence we had to shift right by 3 to transform the shift from 5 into 2.Similarly, with the division,Sc = Sa - Sbwhere Sa = 2 and Sb = 2If we didn't apply the shift to A, the result would have a shift of zero (Sc = Sa - Sb = 2 - 2 = 0). But we want it to be 3 (one unit is equal to 0.001 or 0.1%). Hence we had to increase Sa to 5. Then Sc = Sa - Sb = 5 - 2 = 3. A already had shift Sa = 2. To make it into 5 we had to shift Sa by 3 to the left.That's the same as M.N notation that BrianHG is talking about. N is the shift (only binary, not decimal). M + N is the total length of the integer you use. Usually it is preceded by Q. CPUs are limited to numbers of fixed size, so the most common format is Q1.15 (or simply Q15 format) , but in FPGA you're not restricted and you can use any M and N as you see fit. So you can choose its own M and N for any given number and get the exact resolution you need. The efficiency of multiplications would depend on the size used in DSP blocks, but additions can be done in fabric without restrictions.

author: BrianHG
author_rank: Super Contributor
timestamp: January 30, 2021, 09:21:59 pm
content: BTW, I used 48bits in my above example sing the ADC is 24 bits integer value and when doing FFTs, the 24 bits fraction for the math should achieve a good output definition. Using an M.N of 24.32 would retain perfect rounding definition (in a number of cases, this will render better results than 32bit floats, IE wide dynamic range source factors, as NorthGuy was trying to get his point across) if you are summing up to 256 factors together, IE 24+32=56bit fixed point precision. (Weird, has someone else mentioned that 56bit number...)

author: hamster_nz
author_rank: Super Contributor
timestamp: January 31, 2021, 02:19:58 am
content: Attached is some C code that compares:- Generates 256 random complex numbers, between +/-2^23- FFTs using doubles- FFTs using floats- FFTs using fixed point (implemented using "long longs") also using scaled sine/cos values.- Prints the resultsNo external libraries are used - so "gcc -o my_fft my_fft.c -lm" will work.Code:Input integer data ranges from -8341031 to 8386818Transform of 256 random complex numbers=========================================bin ==== Doubles ========== ==== Floats =========== == err (double-float) == ====== Fixed point ==== == err (double-fixed) ==0, (-311468.32, -113157.76), (-311468.34,-113157.78), ( 0.02, 0.02), (-311468.25,-113157.75), ( 0.07, 0.01)1, (-450432.59, 73399.90), (-450432.56, 73399.89), ( 0.03, 0.01), (-450432.25, 73399.75), ( 0.34, 0.15)2, ( 67731.35, -153482.60), ( 67731.34,-153482.58), ( 0.01, 0.03), ( 67731.25,-153482.50), ( 0.10, 0.10)3, ( 217357.98, 225662.18), ( 217357.98, 225662.14), ( 0.01, 0.04), ( 217357.75, 225661.75), ( 0.23, 0.43)4, ( 83580.10, 536216.31), ( 83580.08, 536216.31), ( 0.03, 0.00), ( 83580.00, 536216.00), ( 0.10, 0.31)5, ( 28770.92, -132197.57), ( 28770.92,-132197.56), ( 0.00, 0.01), ( 28770.75,-132197.50), ( 0.17, 0.07)...You can play with scaling factors on the double => fixed point conversion, as well has the scaling factor used in the sine / cosine table, and see what effects it has on the errors.

author: BrianHG
author_rank: Super Contributor
timestamp: January 31, 2021, 02:51:40 am
content: Quote from: hamster_nz on January 30, 2021, 04:29:16 amQuote from: hamster_nz on January 31, 2021, 02:19:58 amAre you trapped in the C19 zone...I've also been doing a ton of things for the 8bit GPU thread.

author: hamster_nz
author_rank: Super Contributor
timestamp: January 31, 2021, 03:00:44 am
content: Quote from: BrianHG on January 31, 2021, 02:51:40 amNot as much as trapped, more loitering with intent and actively looking for trouble.It is a slow Sunday, and I happened to have some FFT code handy....

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 31, 2021, 07:06:33 am
content: Guy thanks all for the feedbackQuoteGowin has lost of good IP cores, You can check a list in the attached pictures, But it does not have anything for floating points,I managed to find several good Open FPU out there,like this oneshttps://opencores.org/projects/fpu100Also I'm doing verilog or systemverilog , since it's very much like C and I have more than 20 year experince in C, though this is the first serious Big project I'm doing on a FPGA and I choose Gowin because of it's price and because the end result is a comercial product and it needed to be as cheap as possible.oh, And I found this new link, it's super fantastic, It has all kind of float that you need!https://github.com/dawsonjon/verilog-mathThough there is one minor problem, the python scripts do not run! but hopefully all the code is generated already.I tried them in my command prompt like thispython float.pyAnd I can run this simple python script tough,Code:print("ASiDesigner")I have very limited experience in python, like a beginner. so maybe I'm doing something wrong.

author: BrianHG
author_rank: Super Contributor
timestamp: January 31, 2021, 07:33:25 am
content: In you second photo IP, you have a fixed point divider. So, I don't see your problem...Just set the width and the fraction bits position to where you like and divide away...Altera's LPM_DIVIDE has the same controls & I'm sure Xilinx also has the same. It just calling the instance & parameter names will be different.Multiply can be done straight inline in verilog, only divide was an issue.In fact, you have a fir filter there as well as complex domain multiply. Only the floating point and trig functions are missing.

author: BrianHG
author_rank: Super Contributor
timestamp: January 31, 2021, 07:57:36 am
content: Using this guy means you wont have to worry about converting between ints and floats, but you still get the floating point support, less gates and less clock cycles: (However, you highest number is 29bits, and your smallest fraction is -24bits, way above what you seem to need.)https://opencores.org/projects/qfp32

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: January 31, 2021, 08:14:48 am
content: Thanks, Now all the pieces of the puzzle that I needed are complete, I'm writing the FSM for the whole DSP part For now,Thanks for your help and support, I think I will post some results with in a few hours.

author: rs20
author_rank: Super Contributor
timestamp: January 31, 2021, 11:37:04 am
content: Just to troll and make people cry out in pain, how about this idea to the OP's question:For int value x, create the denormal number x * 2^(-126) (which is easy to create with simple wiring directly & without scanning for a leading 1, because it's guaranteed denormal*), and then just pass it through a float32 multiplier with a hard-coded float32 value 2^126. Hoorah, an int-to-float32 converter with naught but simple wiring and a dead standard float32 multiplier unit!I'll see myself out.PS/ * Yes, I know this only works for 23 bit integers, not 24 bit integers. :-)

author: BrianHG
author_rank: Super Contributor
timestamp: February 01, 2021, 01:26:52 am
content: Quote from: rs20 on January 31, 2021, 11:37:04 amThat's a nasty trick... I like...And it does work for 24bit signed integers, as in you feed the absolute value 23 bit int while feeding the sign/polarity, bit 24 into bit 32.

author: ali_asadzadeh
author_rank: Super Contributor
timestamp: February 01, 2021, 07:09:45 am
content: The Attached file contains the Synthesize and max clock Frequency for some of the operations, I wonder if I could find a low resource 24-bit 256 bin FFT core and a faster CORDIC core so I can Increase the overall system Clock.

author: gnuarm
author_rank: Super Contributor
timestamp: February 01, 2021, 10:44:00 am
content: Quote from: rs20 on January 31, 2021, 11:37:04 amOnly works for IEEE format. I'm not bothering with IEEE format because it is great overkill for my task.Interesting idea though. Thing is, it's not really any less logic. A direct to FP conversion uses all the same circuitry as the IEEE math, just programmed to do the conversion without the math. In the general case it would use the adder because the adder has to support the full range of shifting while a multiply uses much less shifting unless it is designed to handle denorm numbers like in IEEE format, if the full spec is implemented. I'm not implementing NaN either.

author: BrianHG
author_rank: Super Contributor
timestamp: February 02, 2021, 10:24:40 pm
content: Quote from: gnuarm on February 01, 2021, 10:44:00 amFunny, the cores the OP is looking at are IEEE format.

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 03, 2021, 02:49:13 pm
content: Quote from: BrianHG on February 01, 2021, 01:26:52 amBut you still need a FP multiplier. That's not cheap. Isn't just scaling, which is the main (and only?) thing needed here for int to FP conversion (unless I missed something), much simpler than a full multiplier?(Of course if you already have the multiplier, that's a moot point.)

author: BrianHG
author_rank: Super Contributor
timestamp: February 03, 2021, 08:33:37 pm
content: Quote from: SiliconWizard on February 03, 2021, 02:49:13 pmJust a few posts up, we have the op linked to a full FP 754 unit and I added a link to a limited one with the range of 2^-24 to 2^29 exponent floating point unit which only takes 2 clocks to add/subtract/multiply & 31 clocks to divide, but uses less gates, less FPGA resources.

author: hamster_nz
author_rank: Super Contributor
timestamp: February 03, 2021, 09:52:21 pm
content: Quote from: BrianHG on February 03, 2021, 08:33:37 pmI am left wondering, is it common for FP units to have specific optimizations for "divide by a power of two", or is there too many corner cases to make it worthwhile...

author: gnuarm
author_rank: Super Contributor
timestamp: February 03, 2021, 10:02:50 pm
content: Quote from: SiliconWizard on February 03, 2021, 02:49:13 pmNot sure. It greatly depends on the design of the floating point multiplier. My present design uses a fixed point multiplier and an accumulator to perform all the operations for floating point other than the manipulations of the exponent and sign bit and a 2 input mux to shift the scale for normalizing vs. denormalizing.The multiplier is a logic block in an FPGA, while a barrel shifter has to be made from the fabric (unless the tools are very crafty). It's a bit analogous to the DFT vs. the FFT. If you need all the possible shifts or frequency bins, then you use the multiplier or FFT. If you only need a few possible shifts or frequency bins then you use the mux or the DFT.