| |
之前,利用cordix原理,用FPGA来实现计算三角函数的值。突发奇想,既然能计算每个三角函数的值,那就可以让输入的值,不断的自增,那输出的结果不就是三角函数的图像了。
想到了,就开始写程序实现了。其实只要编写测试文件,让输入的值,一直加一就可以了。但是利用迭加的原理,输入的角度范围,为-90°到90°。
以下是写好的测试代码的核心部分:
always #5 clk =
~clk;
reg [7:0] i;
initial begin
// Initialize Inputs
clk = 0;
phi = 0;
while(1)
begin
for(i=0;i<=84;i=i+1)
begin
@(negedge clk)
phi = (phi + (1<<8));
end
for(i=84;i>=10;i=i-1)
begin
@(negedge clk)
phi = (phi - (1<<8));
end
end
end
利用modelsim仿真。因为modelsin可以将数据改成模拟数据显示。
从仿真图中,可看出,输出的波形的样子很像是三角函数的波形。但是发现,中间会莫名奇妙出现一些很大的负值。这当然就不对了,就说明写的程序有问题。
发现问题了,然后就要去找问题,看问题是出在什么地方了:
用ISE的自带仿真ISIM观察波形:
从输出cos和sin的值第一次变成负数分析:
从图中,可看出,当输入角度大于22016(86°)输出的值就开始不正确了,而且输出的是负值。开始研究输入的值为86的中间迭代过程的值。
首先,从图中可看出,
X0
= 39797 y0 = 0 z0 = 22013
X1
= 39797 y1 = 39797 z1 = 10496
X2
= 19899 y2 = 59695 z2 = 3697
X3
= 4975 y3 = 64669 z3 = 103
X4
= -3107 y4= 65291 z4 = -1722
X5
= 623 y5 = -58832 z5 = -805
就从这几个数据,就感觉从第五次迭代就有问题了。怎么会出现这么大的负值了。
开始计算每个值
按照伪代码
当z>0 x[i+1] = x[i] - y[i]*2^(-i)
y[i+1] = y[i] +
x[i]*2^(-i)
否则 x[i+1] = x[i] + y[i]*2^(-i)
y[i+1] = y[i] - x[i]*2^(-i)
这里就不计算z的值了。但是要考虑Z的符号,从图中,看出,当z大于3后,就小于0了。因此迭代第5次的时候,x和y的运算要变号了。
首先 x[0] = 39797 y[0] = 0
迭代第一次 x[1] = x[0]–y[0] = 39797
y[1] = y[0] + x[0] = 39797 正确
迭代第二次 x[2] = x[1]- y[1]/2 = 19899
y[2] = y[1] + x[0]/2 = 59695 正确
迭代第三次 x[3] = x[2]- y[2]/4 = 4976
y[3] = y[2] + x[2]/4 = 64669 正确
迭代第四次 x[4] = x[3]- y[3]/8 =-3107
y[4] = y[3] + x[3]/8 = 65291 正确
迭代第五次 x[5] = x[4]+ y[4]/16= 973
y[5] = y[4]-x[4]/16 = 65097
从分析迭代第五次结果,就发现,计算出来的值和仿真出来的值不一样。图中,x[5]的值为623,不等于计算出来的973。但是突然发现到,623 = 59695/16-3107 也就是x[5]=x[4] + y[2]/16;发现这个后,马上返回程序查看。
if(z[4][N_Z-1])
begin
x[5] = x[4] +
{{4{y[4][W-1]}},y[2][W-1:4]};
y[5] = y[4] - {{4{x[4][W-1]}},x[2][W-1:4]};
z[5] = z[4] + 16'd916; //3.58° = 0_0000011_10010100 = 916
end
这下,发现错误了。程序中的y[4]写成y[2]了。。真是,找了半天的错误,竟然发现是当初写程序的时候,没注意,一个下标写错了。哎,今天找这错误,找了一下午。所以,各位,以后写程序的时候,要注意这些细节啊。不然,到时候调试错误的时候,很花精力的。
改正后,用ISIM仿真看看结果有没有正确
从仿真图中,看出。这下结果正确了。。不容易啊。一个小错误。然后再用modelsim看我们的完美三角波形图。
这下,出来的三角函数波形图就完美了。上面余弦,下面是正弦,是不是很酷啊。哈哈