「sin、cos を再帰的に求める / 加法定理による方法 & IIR フィルターによる方法 / Python / それに意味のないとき - Qiita」のときに計算手順だけ確かめておいたのを今度は実際にVHDLでFPGAに実装してみたい。まずは整数化して計算できることをPythonで確かめておく。
うまい端数処理のしかたがわからない。
import math import matplotlib.pyplot as plt def scale_int(x, in_min, in_max, out_min, out_max): return int(((x - in_min) * (out_max - out_min)) / (in_max - in_min)) + out_min def SinCos(Δθ): res_out = (1 << 10) - 1 #最大出力値(DACへ与える最大値) shif_val = 16 #整数化の手段として2の何乗倍にするか res = 1 << shif_val sin_ = math.sin(Δθ) cos_ = math.cos(Δθ) A = int(2 * cos_ * res) S = int( sin_ * res) C = int( -cos_ * res) u = [0, int(res_out/2)] #内部計算での[sinの初期値, cosの初期値] def sincos(): sin_temp = int(S * u[0]) >> shif_val cos_temp = u[1] + (int(C * u[0]) >> shif_val) u[0], u[1] = u[1], (int(A * u[1]) >> shif_val) - u[0] #return sin_temp, cos_temp #↑一旦端数を全部切り捨ててsin、cosの最小値、最大値を求めてから、下のように無理矢理スケーリングする。 return scale_int(sin_temp, -520, 509 , 0, res_out), scale_int(cos_temp, -515, 514, 0, res_out) return sincos ######## # test # ######## Δθ = math.pi/32 sin_cos = SinCos(Δθ) # 初期値をセットした状態でクロージャを開いて、 θList = [] sinList = [] cosList = [] for i in range(200): sin, cos = sin_cos() # 外に出した函数を実行し続ける。実行するたびに sin、cos の値が更新される。 θList.append(i * Δθ) sinList.append(sin) cosList.append(cos) #print("θ: %.2f, sin: %.6f, cos: %.6f, amp: %.16f" % (i*Δθ, sin, cos, math.sqrt(sin**2 + cos**2))) print(min(sinList), max(sinList)) print(min(cosList), max(cosList)) plt.plot(θList,sinList, θList,cosList) plt.xlabel("radian") plt.ylabel("amplitude") plt.grid(color="lightblue") plt.show()