Vivado cordic IP コアのローテーションとトランスレートの詳細説明 (コード付き)
目次
2. Cordic IP コアを使用するために必要な予備知識
序文
与えられた回転を使用すると、行列を直交行列と三角行列に分解できます.FPGAで上記の行列の分解操作を実現するには、Cordic IPコアの回転モードと変換モードを使用する必要があります. この記事では、公式の Cordic データ シートと独自の経験を組み合わせて、Cordic IP コアで回転モードと変換モードを使用する方法を詳細に紹介します。
ヒント: 以下はこの記事の本文です. 記事を書くのは簡単ではありません. 参考になれば幸いです. 転載の際はリンクを添付してください.
1.コーディックの紹介
CORDIC (Coordinate Rotation Digital Computer) アルゴリズムは、1959 年に JDVolder1 によって最初に提案された座標回転デジタル計算方法であり、主に三角関数、双曲線、指数、および対数の計算に使用されます。このアルゴリズムでは、乗算演算が基本的な加算とシフト演算に置き換えられるため、ベクトルの回転と方向の計算には、三角関数、乗算、平方根、逆三角関数、指数などの関数は不要になります。
CORDIC IP コアでサポートされるモードを図 0 に示します。この記事では最初の 2 つを紹介します。
CORDIC アルゴリズムの具体的な紹介と平方根モードの動作については、記事の最後に添付されているリンクを参照してください.この記事では、Cordic IP コアの使用に焦点を当てているため、ここでは原則を繰り返しません.
2. Cordic IP コアを使用するために必要な予備知識
以下の説明のほとんどは、公式の Cordic IP コアが提供する英語のデータ マニュアルからのものであり、一部の説明は、誰もが理解できるようにここに記載されています。
1. データポート
図 1 を見ると、入力データ (位相入力に関係なく) と出力データ用のポートが 1 つしかないことがわかりますが、回転モードと移動モードで操作する数値はベクトルでなければなりません。つまり、次のようになります。座標であり、入力と出力はダブル ペアである必要がありますが、図 1 に示されているのは 1 つのポートだけです。これはなぜですか?
この IP コアを使用する際に注意すべき点は、データの入出力がポートに接続されていることです。図 2 および図 3 に示すように。
図 2 と図 3 を読んだ後、データのスプライシング時に、低い位置の座標 x と高い位置の座標 y または位相出力に注意を払う必要があります。
2.Q 数値形式
Cordic IP コアのオペランドは固定小数点数で、座標 x、y の入出力と位相の入出力の形式が異なります。
まず、XQN 形式を知る必要があります. いわゆる XQN 形式は、1+X+N ビットの補数の 2 進数、1 ビットの符号ビット、それに続く X 整数ビット、それに続く N ビットの仮数 (分数)。
Cordic IP コアの座標は 1QN 形式で、位相角は 2QN 形式です. 実は、この形式はデータ範囲と一定の関係があります. 位相角範囲は座標範囲よりも広いため、1 つあります.より交差する整数。
入力ベクトル (Xin, Yin) と出力ベクトル (Xout, Yout) は、2 ビット幅の整数の 2 の補数のペアとして表されます (1QN 形式)。入力回転角度、ピン ラジアン。これも固定の 2 の補数として表されますが、幅は 3 ビットです (2QN 形式)。
3.ベクトル変換
図 5 と図 6 の位相を比較すると、10 ビット エラーが比較的大きいことがわかります。
4.ベクトル回転
図 8 は、入力 (x, y) を座標軸に沿って -pi/2 だけ回転させます。
3. IP コアの設定手順
1.翻訳する
機能選択: ここで翻訳を選択
アーキテクチャ構成: CORDIC コアには、パラレルとワード シリアルの 2 つのアーキテクチャ構成があります。ここではパラレルを選択します。
パイプライン モード: CORDIC コアは、[なし]、[最適]、および [最大] の 3 つのパイプライン モードを提供します。パイプライン モードの選択は、機能構成とアーキテクチャ構成の選択に基づいています。使用できないパイプライン モードは、CORDIC GUI でグレー表示されます。
なし: CORDIC コアはパイプライン処理なしで実装されます。
最適化: CORDIC コアは、追加の LUT を使用せずに、できるだけ多くのパイプライン ステージを実装します。
最大: CORDIC コアには、各シフト加算サブフェーズの後にパイプライン実装があります。
ここで最適化を選択します。
データ形式: デフォルトでは、翻訳はオプションではありません。
位相フォーマット: CORDIC コアは、2 つの位相フォーマット オプションを提供します。
ラジアン: 位相は、ラジアンで表される 3 ビット整数幅固定小数点の 2 の補数として表されます。例: 01100000 は 3.0 ラジアンを表します。
スケーリングされたラジアン: 位相は、π ラジアンの単位で、3 ビット整数幅の固定小数点の 2 の補数として表されます。スケーリングされた 1 ラジアンは、π * 1 ラジアンに相当します。例: 11110000 は -0.5 * Pi ラジアンを意味します。
ここではラジアンを選択します。
入力幅: 入力座標のビット幅。
出力幅: 出力座標のビット幅。
Round Mode : CORDIC コアは 4 つの丸めモードを提供します。
Truncate: X_OUT、Y_OUT、および PHASE_OUT 出力が切り捨てられます。
正の無限大: X_OUT、Y_OUT、および PHASE_OUT 出力は、
1/2 が (正の無限大に向かって) 切り上げられるように丸められます。これは、MATLAB
関数 floor(x + 0.5)と同等です。
Pos Neg Infinity: 出力 X_OUT、Y_OUT、および PHASE_OUT は、 1/2 が (正の無限に向かって) 切り上げられ、-1/2 が(負の無限に向かって)
切り捨てられるよう に丸められます。これは、MATLAB 関数 round(x) と同等です。Nearest Even: X_OUT、Y_OUT、および PHASE_OUT 出力は、 1/2 が切り捨てられ、3/2 が切り上げられるように、最も近い偶数に丸められます。
ここでは Round Pos Neg Inf が選択されています。
Iterations and Precision : 選択されていない場合は、0 に設定します。IP コアは、他の設定に従ってデフォルトで設定されます。
Coarse Rotation : Coarse Rotation をオフにすると、入出力範囲が第 1 象限 (-Pi/4 ~ +Pi/4) に制限されます。したがって、チェックする必要があります。
補正スケーリング: 補正方法。
スケール補正なし: 出力 X と Y は補正されず、生成され、Zi によってスケーリングされます。
LUT ベース: 出力 X および Y 補正は、LUT ベースの定数係数乗算器を使用します。
BRAM: 出力 X および Y は、ブロック RAM ベースの定数係数乗算器を使用して補正されます。
Embedded Multiplier: 出力 X と Y は、DSP スライスを使用して補正されます。
ここで「いいえ」を選択すると、補正が行われず、間違った出力結果になります。正しい結果を保証するには、補正方法を選択する必要があります。ここでは、デフォルトで LUT ベースが選択されています。
2 ページ目の構成はすべて無視され、デフォルトで問題なく、ほとんど効果がありません。
2.回転
回転設定は移動と同じです。モードとして回転を選択します。
四、翻訳シミュレーション
1. トップレベルのコード
`timescale 1ns / 1ps
//
// Company: cq university
// Engineer: clg
// Create Date: 2023/01/10 13:04:52
// Design Name:
// Module Name: cordic_translate_test
// Project Name:
// Target Devices:
// Tool Versions: 2017.4
// Description:
// Dependencies:
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
module cordic_translate_test(
input clk, //输入时钟信号
input start, //输入开始计算信号
input [31:0] x_in, //输入坐标x
input [31:0] y_in, //输入坐标y
output wire over, //输出计算完成标志
output wire [31:0] x_out, //输出坐标x
output wire [31:0] pha_out //输出相角
);
cordic_translate_ip u_cordic_translate_ip(
.aclk(clk), // input wire aclk
.s_axis_cartesian_tvalid(start), // input wire s_axis_cartesian_tvalid
.s_axis_cartesian_tdata({y_in,x_in}), // input wire [63 : 0] s_axis_cartesian_tdata
.m_axis_dout_tvalid(over), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata({pha_out,x_out}) // output wire [63 : 0] m_axis_dout_tdata
);
endmodule
2. シミュレーションコード
`timescale 1ns / 1ps
//
// Company: cq university
// Engineer: clg
// Create Date: 2023/01/10 13:06:20
// Design Name:
// Module Name: cordic_translate_test_tb
// Project Name:
// Target Devices:
// Tool Versions: 2017.4
// Description:
// Dependencies:
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
module cordic_translate_test_tb();
// cordic_translate_test Parameters
parameter PERIOD = 2;
// cordic_translate_test Inputs
reg clk = 0 ;
reg start = 0 ;
reg [31:0] x_in = 0 ;
reg [31:0] y_in = 0 ;
// cordic_translate_test Outputs
wire over ;
wire [31:0] x_out ;
wire [31:0] pha_out ;
initial
begin
forever #(PERIOD/2) clk=~clk;
end
cordic_translate_test u_cordic_translate_test (
.clk ( clk ),
.start ( start ),
.x_in ( x_in [31:0] ),
.y_in ( y_in [31:0] ),
.over ( over ),
.x_out ( x_out [31:0] ),
.pha_out ( pha_out [31:0] )
);
initial
begin
#5 start<=1;
x_in<=32'b00110000000000000000000000000000;
y_in<=32'b00110000000000000000000000000000;
#2
x_in<=32'b11100000000000000000000000000000;
y_in<=32'b11100000000000000000000000000000;
end
endmodule
図 11 と図 12 を比較すると、シミュレーションが正しいことがわかります。
五、回転シミュレーション
1. トップレベルのコード
`timescale 1ns / 1ps
//
// Company: cq university
// Engineer: clg
// Create Date: 2023/01/10 14:40:46
// Design Name:
// Module Name: cordic_rotate_test
// Project Name:
// Target Devices:
// Tool Versions: 2017.4
// Description:
// Dependencies:
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
module cordic_rotate_test(
input clk, //输入时钟信号
input start, //输入开始计算信号
input [31:0] x_in, //输入坐标x
input [31:0] y_in, //输入坐标y
input [31:0] pha_in, //输入相角
output wire over, //输出计算完成标志
output wire [31:0] x_out, //输出坐标x
output wire [31:0] y_out //输出坐标y
);
cordic_rotate_ip u_cordic_rotate_ip (
.aclk(clk), // input wire aclk
.s_axis_phase_tvalid(start), // input wire s_axis_phase_tvalid
.s_axis_phase_tdata(pha_in), // input wire [31 : 0] s_axis_phase_tdata
.s_axis_cartesian_tvalid(start), // input wire s_axis_cartesian_tvalid
.s_axis_cartesian_tdata({y_in,x_in}), // input wire [63 : 0] s_axis_cartesian_tdata
.m_axis_dout_tvalid(over), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata({y_out,x_out}) // output wire [63 : 0] m_axis_dout_tdata
);
endmodule
2. シミュレーションコード
`timescale 1ns / 1ps
//
// Company: cq university
// Engineer: clg
// Create Date: 2023/01/10 14:41:21
// Design Name:
// Module Name: cordic_rotate_test_tb
// Project Name:
// Target Devices:
// Tool Versions: 2017.4
// Description:
// Dependencies:
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
module cordic_rotate_test_tb();
// cordic_rotate_test Parameters
parameter PERIOD = 2;
// cordic_rotate_test Inputs
reg clk = 0 ;
reg start = 0 ;
reg [31:0] x_in = 0 ;
reg [31:0] y_in = 0 ;
reg [31:0] pha_in = 0 ;
// cordic_rotate_test Outputs
wire over ;
wire [31:0] x_out ;
wire [31:0] y_out ;
initial
begin
forever #(PERIOD/2) clk=~clk;
end
cordic_rotate_test u_cordic_rotate_test (
.clk ( clk ),
.start ( start ),
.x_in ( x_in [31:0] ),
.y_in ( y_in [31:0] ),
.pha_in ( pha_in [31:0] ),
.over ( over ),
.x_out ( x_out [31:0] ),
.y_out ( y_out [31:0] )
);
initial
begin
#5 start<=1;
pha_in<=32'b00110010010000111111011010101000;
x_in<=32'b00110000000000000000000000000000;
y_in<=32'b00110000000000000000000000000000;
#2
pha_in<=32'b10011011011110000001001010101111;
x_in<=32'b11100000000000000000000000000000;
y_in<=32'b11100000000000000000000000000000;
end
endmodule
図 13 に示すように、(-0.5, -0.5) は -pi だけ回転して (0.5, 0.5) になります。
要約する
以上が本日のお話で、主にザイリンクスが提供する CORDIC IP コアの Translate モードと Rotate モードの使い方を紹介します。