Hi sir, I have using the matlab 2012b version and i am getting an error that function call failed while converting my code to hdl
Show older comments
this my matlab code
function [ y] = tesr (x,n)
x = 10;
x_rad = (pi/180)*x;
b = 0;
y = zeros(1,n);
for i = 0:n
% for j = 1:length(x_rad)
if i<4
a = -1
disp(b)
c =x_rad
d =((2*i) +1)
y= power(a,b)*power(c,d)/(prod([1:d]))
b = b+1
end
end
this is wrapper.fxt codegen code
%#codegen
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% Generated by MATLAB 8.0, MATLAB Coder 2.3 and HDL Coder 3.1 %
5% %
6%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7function y = tesr_FixPt(x,n)
8 fm = hdlfimath;
9 x = fi( 10, 0, 14, 10, fm );
10 x_rad = fi( (pi*fi( 1/180, 0, 14, 21 ))*x, 0, 14, 16, fm );
11 b = fi( 0, 0, 3, 0, fm );
12 y = fi( zeros( 1, fi_toint( n ) ), 1, 14, 15, fm );
13 for i = 0:fi_toint( n )
14 % for j = 1:length(x_rad)
15 if i<4
16 a = fi( -1, 1, 2, 0, fm )
17 disp( b )
18 c = fi( x_rad, 0, 14, 16, fm )
19 d = fi( ((2*i) + 1), 0, 4, 0, fm )
20 y = fi( fi_div( power( fi_toint( a ), fi_toint( b ) )*power( fi_toint( c ), fi_toint( d ) ), (prod( [ 1:fi_toint( d ) ] )) ), 1, 14, 15, fm )
21 b = fi( b + fi( 1, 0, 1, 0 ), 0, 3, 0, fm )
22 end
23 end
24end
tesr_FixPt
line 20
Function 'prod' is not defined for values of class 'int32'.
2
tesr_FixPt
line 20
Function call failed.
tesr_wrapper_FixPt
line 5
Function call failed.
tesr_wrapper_FixPt
line 6
Undefined function or variable 'y_out'. The first assignment to a local variable determines its class.
i have already defined y in pgm, den also its showing error
so please let me know where i am going wrong.
Thanku
Answers (1)
Walter Roberson
on 22 Jan 2016
Each time your line
y= power(a,b)*power(c,d)/(prod([1:d]))
is executed, it writes over all of y with a value that looks to me to be a scalar.
You could consider assigning to y(i), but your i starts from 0, and indexing at 0 is not permitted. So you could consider assigning to y(i+1) which would fix the place to assign the first value. But then the last value, when i = n, would be written to y(n+1) but you only defined y as being n long.
On the other hand, I cannot tell what your intended output is for i >= 4.
Instead of prod(1:d) you could try factorial(d). If that does not work, then you will need to build up the factorial iterative:
d_fact = 1;
for i = 0 : n
...
y= power(a,b)*power(c,d)/d_fact;
d_fact = d_fact * (2*i+2) * (2*i+3);
end
the multiplication after use gets it set up properly for the next loop without having to special case 0!
6 Comments
somesh nandi
on 22 Jan 2016
Edited: Walter Roberson
on 22 Jan 2016
Walter Roberson
on 22 Jan 2016
Your "y" outside of the routine has nothing to do with your "y" inside of the routine. Your code inside the routine is trying to return a vector of length n, according to your line y = zeros(1,n); inside the routine.
It appears to me that you have copied a lot from outside the routine to inside the routine.
somesh nandi
on 22 Jan 2016
Walter Roberson
on 22 Jan 2016
Why are you looping both inside the routine and in your call to the routine, with nearly the same code in both?
Why do you set y to be zeros(1,n) which is length n, but you loop i from 0 to n which is n+1 results?
Why are you looping i from 0 to n, but you are only taking action inside "if i < 4" ?
somesh nandi
on 25 Jan 2016
Edited: Walter Roberson
on 25 Jan 2016
Walter Roberson
on 25 Jan 2016
With regards to the problem with RoundMode, the available RoundMode are listed and described at http://www.mathworks.com/help/fixedpoint/ug/precision-and-range.html#f6481 . (It appears to me that "fix" shows up in the table under the name Zero.)
If you look more closely at the generated code, it includes
power( fi_toint(a), i )
The value of "a" that you are passing happens to be an integer (-1) so that is okay in this instance. If "a" could become a non-integer then you would have a problem.
The generated code also includes
power( fi_toint(c), fi_toint(d) )
However, the value of c you are passing in is not an integer, so converting it to an integer like is done here is going to be a problem.
It appears to me that you should be running the .m code through the Fixed Point Designer and assigning attributes to all of the various items. For example you would probably get more efficient code if you used
fm = hdlfimath;
c = (pi/180)*x;
y = fi(0, fm, 'RoundingMode', 'Nearest');
one = int32(1);
two = int32(2);
three = int32(3);
d_fact = int32(1);
ai = int32(1);
cd = fi(1, fm, 'RoundingMode', 'Nearest');
for i = int32(0):int32(n)
y = y + ai*cd/d_fact;
ai = ai * (i + one);
cd = cd * c * c;
d_fact = d_fact*(two * i + two) * (two * i + three)
end
Remember, when you are working with HDL, you want efficiency.
I have constructed the above manually, with reading the documentation, and it might be wrong, especially with respect to the length of words you need.
You should not be leaving accuracy to chance. How many digits do you need? When you are doing the calculation, evaluate by hand with the smallest x and figure out the smallest contribution to the sum that you need to get the accuracy you need, and how many bits the fixed point calculation of that term will need to give you that contribution properly rounded.
The Fixed Point Designer is designed to help you with those kinds of analysis.
Extra unneeded bits mean extra FPGA space and slower execution, so you should be defining a required accuracy and using FI objects that meet that accuracy, but no more than that accuracy.
Categories
Find more on Map Display in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!