論理回路デザイン
|
|
/* **************************** MODULE PREAMBLE ********************************
Copyright (c) 2012, ArchiTek
This document constitutes confidential and proprietary information
of ArchiTek. All rights reserved.
*/
// ***************************** MODULE HEADER *********************************
module fftBfCalc (
iVld, iStall, iRadix,
oVld, oStall,
wIndex, wPhase,
wRe0, wIm0, wRe1, wIm1, wRe2, wIm2, wRe3, wIm3,
ramRF, ramRP,
ram0RE, ram1RE, ram2RE, ram3RE,
ram0RA, ram1RA, ram2RA, ram3RA,
ram0RD, ram1RD, ram2RD, ram3RD,
ramWF, ramWP,
ram0WE, ram1WE, ram2WE, ram3WE,
ram0WA, ram1WA, ram2WA, ram3WA,
ram0WD, ram1WD, ram2WD, ram3WD,
reset, clk
);
// ************************* PARAMETER DECLARATIONS ****************************
// 最大のポイント数の指数はカウンタ等のビット範囲を定める
parameter MRR = 10; // Max Radix Radix
// 半精度で頻繁に利用する固定値
parameter NEG = 16'h8000;
parameter ZERO = 16'h0000;
// *************************** I/O DECLARATIONS ********************************
// Pipe Input
// iRadixはiVldに同期していれば、タスクごとに値の変更が可能
input iVld;
output iStall;
input [3:0] iRadix;
// Pipe Output
// oVldは処理の終了を伝達するために存在
output oVld;
input oStall;
// Coefficient
// 係数テーブルのインターフェイス、4つの係数を同時アクセス
output [MRR-3:0] wIndex;
output [2:0] wPhase;
input [15:0] wRe0, wIm0, wRe1, wIm1, wRe2, wIm2, wRe3, wIm3;
// SRAM Read
// ramRFはSRAM Read時のSRAMセットの選択(LoadDataでのoVldに属していたoFlipと対)
output [1:0] ramRF;
// ramRPはSRAM Read時の領域の選択
output ramRP;
output ram0RE, ram1RE, ram2RE, ram3RE;
output [MRR-3:0] ram0RA, ram1RA, ram2RA, ram3RA;
input [31:0] ram0RD, ram1RD, ram2RD, ram3RD;
// SRAM Write
// ramWFはSRAM Write時のSRAMセットの選択(StoreDataでのoVldに属していたoFlipと対)
output [1:0] ramWF;
// ramWPはSRAM Write時の領域の選択
output ramWP;
output ram0WE, ram1WE, ram2WE, ram3WE;
output [MRR-3:0] ram0WA, ram1WA, ram2WA, ram3WA;
output [31:0] ram0WD, ram1WD, ram2WD, ram3WD;
// Utility
input reset;
input clk;
// **************************** LOCAL DECLARATIONS *****************************
// Control
reg [1:0] iStat;
reg [1:0] iStatD;
reg iEn;
reg iStall;
reg [3:0] gapCnt;
wire gapEnd;
wire stall_s;
// Counter
// ポイント数のカウンタとPhaseのカウンタを用意、前者が下位で後者が上位の2Dカウンタ
// Radix-4は4つ同時に処理するので、ポイント数のカウンタもN/4個数えればよい
reg [MRR-3:0] qntCnt, iQntNum;
reg [2:0] rdxCnt, iRdxNum;
// iTrigはポイント数のカウンタの区切り、iFinはPhaseのカウンタの区切り(終了)
wire iTrig;
wire iFin;
// Pipeline Variable
// パイプラインは0〜10の11段、SuffixはパイプラインStageを示す
reg vld_0, vld_1, vld_2, vld_3, vld_4,
vld_5, vld_6, vld_7, vld_8, vld_9, vld_10;
wire stall_0, stall_1, stall_2, stall_3, stall_4,
stall_5, stall_6, stall_7, stall_8, stall_9, stall_10;
reg fin_0, fin_1, fin_2, fin_3, fin_4,
fin_5, fin_6, fin_7, fin_8, fin_9, fin_10;
reg [MRR-3:0] index_0, index_1, index_2, index_3, index_4,
index_5, index_6, index_7, index_8, index_9, index_10;
reg [2:0] phase_0, phase_1, phase_2, phase_3, phase_4,
phase_5, phase_6, phase_7, phase_8, phase_9, phase_10;
reg [3:0] radix_0, radix_1, radix_2, radix_3, radix_4,
radix_5, radix_6, radix_7, radix_8, radix_9, radix_10;
reg [MRR-1:0] addr0_0, addr1_0, addr2_0, addr3_0;
reg [1:0] addr0_1, addr1_1, addr2_1, addr3_1;
reg [MRR-1:0] addr0_10, addr1_10, addr2_10, addr3_10;
reg [15:0] dRe0_2, dIm0_2, dRe1_2, dIm1_2;
reg [15:0] dRe2_2, dIm2_2, dRe3_2, dIm3_2;
reg [15:0] wRe0_2, wIm0_2, wRe1_2, wIm1_2;
reg [15:0] wRe2_2, wIm2_2, wRe3_2, wIm3_2;
wire [15:0] rr0_4, ri0_4, ir0_4, ii0_4, rr1_4, ri1_4, ir1_4, ii1_4;
wire [15:0] rr2_4, ri2_4, ir2_4, ii2_4, rr3_4, ri3_4, ir3_4, ii3_4;
wire [15:0] re0_6, im0_6, re1_6, im1_6, re2_6, im2_6, re3_6, im3_6;
wire [15:0] pRe02_8, pIm02_8, pRe13_8, pIm13_8;
wire [15:0] mRe02_8, mIm02_8, mRe13_8, mIm13_8;
wire [15:0] xRe0_10, xIm0_10, xRe1_10, xIm1_10;
wire [15:0] xRe2_10, xIm2_10, xRe3_10, xIm3_10;
wire [15:0] dRe0, dIm0, dRe1, dIm1, dRe2, dIm2, dRe3, dIm3;
// SRAM Flip
reg wFlip, rFlip;
// ******************************** MODULE BODY ********************************
// -----------------------------------------------------------------------------
// Control
// 停止・実行・保留のStateマシン、Gapがなければカウンタだけで状態が分かるので不必要
parameter IDLE = 2'h0,
PROC = 2'h1,
GAP = 2'h2;
// iEnは保留(Gap)中'0'にして余分なSRAMアクセス等を禁止するために用意
always @(
iStat or
iVld or
iTrig or
iFin or
gapEnd or
stall_s
) begin
iStatD = iStat;
iEn = 1'b1;
iStall = stall_s;
if (!stall_s)
case (iStat)
IDLE: if (iVld) begin // すぐさま実行状態へ
iStatD = PROC;
iEn = 1'b1;
iStall = 1'b1;
end
PROC: casex ({iTrig, iFin})
2'b0x: begin // 実行中
iStatD = PROC;
iEn = 1'b1;
iStall = 1'b1;
end
2'b10: begin // Phase切り替え時は保留状態へ
// iRadixによってはGapへの遷移は不必要
// iStatD = PROC;
iStatD = GAP;
iEn = 1'b1;
iStall = 1'b1;
end
2'b11: begin // 終了時は停止状態へ
iStatD = IDLE;
iEn = 1'b1;
iStall = 1'b0;
end
endcase
GAP: if (gapEnd) begin // Gapを数え終われば実行状態へ
iStatD = PROC;
iEn = 1'b0;
iStall = 1'b1;
end
else begin // Gapカウント中
iStatD = GAP;
iEn = 1'b0;
iStall = 1'b1;
end
endcase
end
always @(posedge clk)
if (reset)
iStat <= #1 IDLE;
else
iStat <= #1 iStatD;
// -----------------------------------------------------------------------------
// Gap
// Gapをカウント、パイプライン長程度を数えることが必要(11なので4bitカウンタ)
always @(posedge clk)
if (reset)
gapCnt <= #1 4'h0;
else
gapCnt <= #1 gapCnt + {3'h0, iVld & !iEn};
// 正確にはパイプライン長-Xを設定する(XはSRAMアクセスのスケジュールで判断)
// 16, 64ポイントFFTに限定されるので、その処理に重要性がなければ簡単な手法を採用(ここでは16)
assign gapEnd = &gapCnt;
// -----------------------------------------------------------------------------
// Counter
// 2Dカウンタになっており、理論通りN/4 log4Nを数える
always @(posedge clk)
if (reset) begin
qntCnt <= #1 {MRR-2{1'b0}};
rdxCnt <= #1 3'h0;
end
else if (!stall_s) begin
qntCnt <= #1 iTrig
? {MRR-2{1'b0}}
: qntCnt + {{MRR-3{1'b0}}, iVld & iEn};
rdxCnt <= #1 iFin
? 3'h0
: rdxCnt + {2'h0, iVld & iTrig};
end
// iCntのデフォルト設定はポイント数2^10、MRRを増やす場合は隙間(10,12,14,,,)を積み増して行く
// case()文でiRadix依存しない記述方法があればそれを採用すべき
always @(
iRadix
)
case (iRadix)
4'h4: begin
iQntNum = 8'h03;
iRdxNum = 3'h1;
end
4'h6: begin
iQntNum = 8'h0f;
iRdxNum = 3'h2;
end
4'h8: begin
iQntNum = 8'h3f;
iRdxNum = 3'h3;
end
default: begin
// MRR
iQntNum = 8'hff;
iRdxNum = 3'h4;
end
endcase
assign iTrig = iVld & (qntCnt == iQntNum);
assign iFin = iTrig & (rdxCnt == iRdxNum);
// -----------------------------------------------------------------------------
// Pipeline (Valid Control)
// 11段パイプライン、SRAMアドレスを生成するためカウンタ値等を送る
always @(posedge clk)
if (reset)
{vld_0, fin_0, index_0, phase_0, radix_0}
<= #1 {MRR+7{1'b0}};
else if (!stall_s)
{vld_0, fin_0, index_0, phase_0, radix_0}
<= #1 {iVld & iEn, iFin, qntCnt, rdxCnt, iRadix};
always @(posedge clk)
if (reset)
{vld_1, fin_1, index_1, phase_1, radix_1}
<= #1 {MRR+7{1'b0}};
else if (!stall_0)
{vld_1, fin_1, index_1, phase_1, radix_1}
<= #1 {vld_0, fin_0, index_0, phase_0, radix_0};
always @(posedge clk)
if (reset)
{vld_2, fin_2, index_2, phase_2, radix_2}
<= #1 {MRR+7{1'b0}};
else if (!stall_1)
{vld_2, fin_2, index_2, phase_2, radix_2}
<= #1 {vld_1, fin_1, index_1, phase_1, radix_1};
always @(posedge clk)
if (reset)
{vld_3, fin_3, index_3, phase_3, radix_3}
<= #1 {MRR+7{1'b0}};
else if (!stall_2)
{vld_3, fin_3, index_3, phase_3, radix_3}
<= #1 {vld_2, fin_2, index_2, phase_2, radix_2};
always @(posedge clk)
if (reset)
{vld_4, fin_4, index_4, phase_4, radix_4}
<= #1 {MRR+7{1'b0}};
else if (!stall_3)
{vld_4, fin_4, index_4, phase_4, radix_4}
<= #1 {vld_3, fin_3, index_3, phase_3, radix_3};
always @(posedge clk)
if (reset)
{vld_5, fin_5, index_5, phase_5, radix_5}
<= #1 {MRR+7{1'b0}};
else if (!stall_4)
{vld_5, fin_5, index_5, phase_5, radix_5}
<= #1 {vld_4, fin_4, index_4, phase_4, radix_4};
always @(posedge clk)
if (reset)
{vld_6, fin_6, index_6, phase_6, radix_6}
<= #1 {MRR+7{1'b0}};
else if (!stall_5)
{vld_6, fin_6, index_6, phase_6, radix_6}
<= #1 {vld_5, fin_5, index_5, phase_5, radix_5};
always @(posedge clk)
if (reset)
{vld_7, fin_7, index_7, phase_7, radix_7}
<= #1 {MRR+7{1'b0}};
else if (!stall_6)
{vld_7, fin_7, index_7, phase_7, radix_7}
<= #1 {vld_6, fin_6, index_6, phase_6, radix_6};
always @(posedge clk)
if (reset)
{vld_8, fin_8, index_8, phase_8, radix_8}
<= #1 {MRR+7{1'b0}};
else if (!stall_7)
{vld_8, fin_8, index_8, phase_8, radix_8}
<= #1 {vld_7, fin_7, index_7, phase_7, radix_7};
always @(posedge clk)
if (reset)
{vld_9, fin_9, index_9, phase_9, radix_9}
<= #1 {MRR+7{1'b0}};
else if (!stall_8)
{vld_9, fin_9, index_9, phase_9, radix_9}
<= #1 {vld_8, fin_8, index_8, phase_8, radix_8};
always @(posedge clk)
if (reset)
{vld_10, fin_10, index_10, phase_10, radix_10}
<= #1 {MRR+7{1'b0}};
else if (!stall_9)
{vld_10, fin_10, index_10, phase_10, radix_10}
<= #1 {vld_9, fin_9, index_9, phase_9, radix_9};
// -----------------------------------------------------------------------------
// Pipeline (Stall Control)
// バッファ型のパイプライン記述
// 全体の処理数を考えるとパイプライン長はたいしたことがないので、基本型を用いてもよい(以下vldを削除)
assign stall_s = vld_0 & stall_0;
assign stall_0 = vld_1 & stall_1;
assign stall_1 = vld_2 & stall_2;
assign stall_2 = vld_3 & stall_3;
assign stall_3 = vld_4 & stall_4;
assign stall_4 = vld_5 & stall_5;
assign stall_5 = vld_6 & stall_6;
assign stall_6 = vld_7 & stall_7;
assign stall_7 = vld_8 & stall_8;
assign stall_8 = vld_9 & stall_9;
assign stall_9 = vld_10 & stall_10;
assign stall_10 = oStall & fin_10;
// -----------------------------------------------------------------------------
// SRAM Read Address & Data Latch
// データアドレスに対する操作を4ポートに対して実施、SRMAアドレスとしてSRAM Readへ
always @(posedge clk)
if (!stall_s) begin
addr0_0 <= #1 addrInFunc({qntCnt, 2'h0}, rdxCnt, iRadix);
addr1_0 <= #1 addrInFunc({qntCnt, 2'h1}, rdxCnt, iRadix);
addr2_0 <= #1 addrInFunc({qntCnt, 2'h2}, rdxCnt, iRadix);
addr3_0 <= #1 addrInFunc({qntCnt, 2'h3}, rdxCnt, iRadix);
end
// SRAMから出てくるReadデータは1サイクル遅れるので、データの分配情報もラッチして遅延させる
always @(posedge clk)
if (!stall_0) begin
addr0_1 <= #1 addr0_0[1:0];
addr1_1 <= #1 addr1_0[1:0];
addr2_1 <= #1 addr2_0[1:0];
addr3_1 <= #1 addr3_0[1:0];
end
// 4つのSRAMアドレスLSB2ビットは必ず排他的になり、これによりSRAM Bankに配分する
// ここでBank1とBank2はひねられていることに注意(Radix-4の理論)
assign {dIm0, dRe0} = ram0RD & {32{addr0_1 == 2'h0}}
| ram1RD & {32{addr0_1 == 2'h1}}
| ram2RD & {32{addr0_1 == 2'h2}}
| ram3RD & {32{addr0_1 == 2'h3}};
assign {dIm1, dRe1} = ram0RD & {32{addr2_1 == 2'h0}} // addr2_1!
| ram1RD & {32{addr2_1 == 2'h1}}
| ram2RD & {32{addr2_1 == 2'h2}}
| ram3RD & {32{addr2_1 == 2'h3}};
assign {dIm2, dRe2} = ram0RD & {32{addr1_1 == 2'h0}} // addr_11!
| ram1RD & {32{addr1_1 == 2'h1}}
| ram2RD & {32{addr1_1 == 2'h2}}
| ram3RD & {32{addr1_1 == 2'h3}};
assign {dIm3, dRe3} = ram0RD & {32{addr3_1 == 2'h0}}
| ram1RD & {32{addr3_1 == 2'h1}}
| ram2RD & {32{addr3_1 == 2'h2}}
| ram3RD & {32{addr3_1 == 2'h3}};
// SRAMのReadデータを一旦ラッチ
always @(posedge clk)
if (vld_1 & !stall_1) begin
dRe0_2 <= #1 dRe0;
dRe1_2 <= #1 dRe1;
dRe2_2 <= #1 dRe2;
dRe3_2 <= #1 dRe3;
dIm0_2 <= #1 dIm0;
dIm1_2 <= #1 dIm1;
dIm2_2 <= #1 dIm2;
dIm3_2 <= #1 dIm3;
wRe0_2 <= #1 wRe0;
wRe1_2 <= #1 wRe1;
wRe2_2 <= #1 wRe2;
wRe3_2 <= #1 wRe3;
wIm0_2 <= #1 wIm0;
wIm1_2 <= #1 wIm1;
wIm2_2 <= #1 wIm2;
wIm3_2 <= #1 wIm3;
end
// ここから演算器が並ぶ、実際の記述はポート接続を使用すること!(掲載の見やすさの都合上変更している)
// -----------------------------------------------------------------------------
// Stage 3,4 - Data x Coef
// 複素数乗算のための乗算器16個、最初の4つは係数が固定(1.0, 0.0)なので省略可能
fmul mul_rr0 (vld_2,, dRe0_2, wRe0_2,, stall_4, rr0_4, reset, clk);
fmul mul_ri0 (vld_2,, dRe0_2, wIm0_2,, stall_4, ri0_4, reset, clk);
fmul mul_ir0 (vld_2,, dIm0_2, wRe0_2,, stall_4, ir0_4, reset, clk);
fmul mul_ii0 (vld_2,, dIm0_2, wIm0_2,, stall_4, ii0_4, reset, clk);
fmul mul_rr1 (vld_2,, dRe1_2, wRe1_2,, stall_4, rr1_4, reset, clk);
fmul mul_ri1 (vld_2,, dRe1_2, wIm1_2,, stall_4, ri1_4, reset, clk);
fmul mul_ir1 (vld_2,, dIm1_2, wRe1_2,, stall_4, ir1_4, reset, clk);
fmul mul_ii1 (vld_2,, dIm1_2, wIm1_2,, stall_4, ii1_4, reset, clk);
fmul mul_rr2 (vld_2,, dRe2_2, wRe2_2,, stall_4, rr2_4, reset, clk);
fmul mul_ri2 (vld_2,, dRe2_2, wIm2_2,, stall_4, ri2_4, reset, clk);
fmul mul_ir2 (vld_2,, dIm2_2, wRe2_2,, stall_4, ir2_4, reset, clk);
fmul mul_ii2 (vld_2,, dIm2_2, wIm2_2,, stall_4, ii2_4, reset, clk);
fmul mul_rr3 (vld_2,, dRe3_2, wRe3_2,, stall_4, rr3_4, reset, clk);
fmul mul_ri3 (vld_2,, dRe3_2, wIm3_2,, stall_4, ri3_4, reset, clk);
fmul mul_ir3 (vld_2,, dIm3_2, wRe3_2,, stall_4, ir3_4, reset, clk);
fmul mul_ii3 (vld_2,, dIm3_2, wIm3_2,, stall_4, ii3_4, reset, clk);
// -----------------------------------------------------------------------------
// Stage 5,6 - Re-Re/Im+Im
// 複素数乗算のための加算器8個、最初の2つは係数が固定(1.0, 0.0)なので省略可能
// NEGの排他的論理和はオペランドの減算を意味する
fadd add_r0 (vld_4,, rr0_4, ii0_4 ^ NEG,, stall_6, re0_6, reset, clk);
fadd add_i0 (vld_4,, ri0_4, ir0_4,, stall_6, im0_6, reset, clk);
fadd add_r1 (vld_4,, rr1_4, ii1_4 ^ NEG,, stall_6, re1_6, reset, clk);
fadd add_i1 (vld_4,, ri1_4, ir1_4,, stall_6, im1_6, reset, clk);
fadd add_r2 (vld_4,, rr2_4, ii2_4 ^ NEG,, stall_6, re2_6, reset, clk);
fadd add_i2 (vld_4,, ri2_4, ir2_4,, stall_6, im2_6, reset, clk);
fadd add_r3 (vld_4,, rr3_4, ii3_4 ^ NEG,, stall_6, re3_6, reset, clk);
fadd add_i3 (vld_4,, ri3_4, ir3_4,, stall_6, im3_6, reset, clk);
// -----------------------------------------------------------------------------
// Stage 7,8 - Det0
// 行列演算の前処理のための加算器8個
fadd add_pr02 (vld_6,, re0_6, re2_6,, stall_8, pRe02_8, reset, clk);
fadd add_pi02 (vld_6,, im0_6, im2_6,, stall_8, pIm02_8, reset, clk);
fadd add_mr02 (vld_6,, re0_6, re2_6 ^ NEG,, stall_8, mRe02_8, reset, clk);
fadd add_mi02 (vld_6,, im0_6, im2_6 ^ NEG,, stall_8, mIm02_8, reset, clk);
fadd add_pr13 (vld_6,, re1_6, re3_6,, stall_8, pRe13_8, reset, clk);
fadd add_pi13 (vld_6,, im1_6, im3_6,, stall_8, pIm13_8, reset, clk);
fadd add_mr13 (vld_6,, re1_6, re3_6 ^ NEG,, stall_8, mRe13_8, reset, clk);
fadd add_mi13 (vld_6,, im1_6, im3_6 ^ NEG,, stall_8, mIm13_8, reset, clk);
// -----------------------------------------------------------------------------
// Stage 9,10 - Det1
// X0 = P02 + P13
// Re(X0) = Re(P02) + Re(P13)
// Im(X0) = Im(P02) + Im(P13)
// X1 = M02 - jM13
// Re(X1) = Re(M02) + Im(M13)
// Im(X1) = Im(M02) - Re(M13)
// X2 = P02 - P13
// Re(X2) = Re(P02) - Re(P13)
// Im(X2) = Im(P02) - Im(P13)
// X3 = M02 + jM13
// Re(X3) = Re(M02) - Im(M13)
// Im(X3) = Im(M02) + Re(M13)
// 行列演算の後処理のための加算器8個
fadd add_xr0 (vld_8,, pRe02_8, pRe13_8,, stall_10, xRe0_10, reset, clk);
fadd add_xi0 (vld_8,, pIm02_8, pIm13_8,, stall_10, xIm0_10, reset, clk);
fadd add_xr1 (vld_8,, mRe02_8, mIm13_8,, stall_10, xRe1_10, reset, clk);
fadd add_xi1 (vld_8,, mIm02_8, mRe13_8 ^ NEG,, stall_10, xIm1_10, reset, clk);
fadd add_xr2 (vld_8,, pRe02_8, pRe13_8 ^ NEG,, stall_10, xRe2_10, reset, clk);
fadd add_xi2 (vld_8,, pIm02_8, pIm13_8 ^ NEG,, stall_10, xIm2_10, reset, clk);
fadd add_xr3 (vld_8,, mRe02_8, mIm13_8 ^ NEG,, stall_10, xRe3_10, reset, clk);
fadd add_xi3 (vld_8,, mIm02_8, mRe13_8,, stall_10, xIm3_10, reset, clk);
// -----------------------------------------------------------------------------
// SRAM Write Address Latch
// データアドレスに対する操作を4ポートに対して前もって実施、SRMAアドレスとしてSRAM Writeへ
always @(posedge clk)
if (!stall_9) begin
addr0_10 <= #1 addrOutFunc({index_9, 2'h0}, phase_9, radix_9);
addr1_10 <= #1 addrOutFunc({index_9, 2'h1}, phase_9, radix_9);
addr2_10 <= #1 addrOutFunc({index_9, 2'h2}, phase_9, radix_9);
addr3_10 <= #1 addrOutFunc({index_9, 2'h3}, phase_9, radix_9);
end
// -----------------------------------------------------------------------------
// Output
assign oVld = vld_10 & fin_10;
// -----------------------------------------------------------------------------
// SRAM Flip
// FFTの実行の度にFlipすることで、使用するSRAMセットをReadとWriteに分けて選択する
// また、SRAMを使用する状態(vld=1)を組み合わせて出力(トップモジュールはこの信号でデータをブレンド)
always @(posedge clk)
if (reset)
rFlip <= #1 1'b0;
else if (vld_0 & fin_0 & !stall_0)
rFlip <= #1 ~rFlip;
always @(posedge clk)
if (reset)
wFlip <= #1 1'b0;
else if (vld_10 & fin_10 & !stall_10)
wFlip <= #1 ~wFlip;
assign ramRF = {1'b0, vld_0 & !stall_0} << rFlip;
assign ramWF = {1'b0, vld_10 & !stall_10} << wFlip;
// -----------------------------------------------------------------------------
// Coefficient
// 係数テーブルへのアクセスはSRAMアクセスに1サイクル遅れて実施(SRAMのレイテンシが異なるため)
assign wIndex = index_1;
assign wPhase = phase_1;
// -----------------------------------------------------------------------------
// SRAM Read
// SRAM Read用の信号を生成
// ramRPは領域を示すがこの記述だとiRadix=64,1024にしか対応できずNG(ここの脚注[4]を参照)
assign ramRP = phase_0[0];
// SRAMにStallを効かす、また未使用時はRE(Read Enable)をActiveにしないことで低消費電力化を考慮する
assign ram0RE = vld_0 & !stall_0;
assign ram1RE = vld_0 & !stall_0;
assign ram2RE = vld_0 & !stall_0;
assign ram3RE = vld_0 & !stall_0;
assign ram0RA = {
addr0_0[MRR-1:2] & {MRR-2{addr0_0[1:0] == 2'h0}} |
addr1_0[MRR-1:2] & {MRR-2{addr1_0[1:0] == 2'h0}} |
addr2_0[MRR-1:2] & {MRR-2{addr2_0[1:0] == 2'h0}} |
addr3_0[MRR-1:2] & {MRR-2{addr3_0[1:0] == 2'h0}}
};
assign ram1RA = {
addr0_0[MRR-1:2] & {MRR-2{addr0_0[1:0] == 2'h1}} |
addr1_0[MRR-1:2] & {MRR-2{addr1_0[1:0] == 2'h1}} |
addr2_0[MRR-1:2] & {MRR-2{addr2_0[1:0] == 2'h1}} |
addr3_0[MRR-1:2] & {MRR-2{addr3_0[1:0] == 2'h1}}
};
assign ram2RA = {
addr0_0[MRR-1:2] & {MRR-2{addr0_0[1:0] == 2'h2}} |
addr1_0[MRR-1:2] & {MRR-2{addr1_0[1:0] == 2'h2}} |
addr2_0[MRR-1:2] & {MRR-2{addr2_0[1:0] == 2'h2}} |
addr3_0[MRR-1:2] & {MRR-2{addr3_0[1:0] == 2'h2}}
};
assign ram3RA = {
addr0_0[MRR-1:2] & {MRR-2{addr0_0[1:0] == 2'h3}} |
addr1_0[MRR-1:2] & {MRR-2{addr1_0[1:0] == 2'h3}} |
addr2_0[MRR-1:2] & {MRR-2{addr2_0[1:0] == 2'h3}} |
addr3_0[MRR-1:2] & {MRR-2{addr3_0[1:0] == 2'h3}}
};
// -----------------------------------------------------------------------------
// SRAM Write
// SRAM Write用の信号を生成
// ramWPは領域を示すがこの記述だとiRadix=64,1024にしか対応できずNG(ここの脚注[4]を参照)
assign ramWP = ~phase_10[0];
// SRAMにStallを効かす、また未使用時はWE(Write Enable)をActiveにしないことで低消費電力化を考慮する
assign ram0WE = vld_10 & !stall_10;
assign ram1WE = vld_10 & !stall_10;
assign ram2WE = vld_10 & !stall_10;
assign ram3WE = vld_10 & !stall_10;
assign ram0WA = {
addr0_10[MRR-1:2] & {MRR-2{addr0_10[1:0] == 2'h0}} |
addr1_10[MRR-1:2] & {MRR-2{addr1_10[1:0] == 2'h0}} |
addr2_10[MRR-1:2] & {MRR-2{addr2_10[1:0] == 2'h0}} |
addr3_10[MRR-1:2] & {MRR-2{addr3_10[1:0] == 2'h0}}
};
assign ram1WA = {
addr0_10[MRR-1:2] & {MRR-2{addr0_10[1:0] == 2'h1}} |
addr1_10[MRR-1:2] & {MRR-2{addr1_10[1:0] == 2'h1}} |
addr2_10[MRR-1:2] & {MRR-2{addr2_10[1:0] == 2'h1}} |
addr3_10[MRR-1:2] & {MRR-2{addr3_10[1:0] == 2'h1}}
};
assign ram2WA = {
addr0_10[MRR-1:2] & {MRR-2{addr0_10[1:0] == 2'h2}} |
addr1_10[MRR-1:2] & {MRR-2{addr1_10[1:0] == 2'h2}} |
addr2_10[MRR-1:2] & {MRR-2{addr2_10[1:0] == 2'h2}} |
addr3_10[MRR-1:2] & {MRR-2{addr3_10[1:0] == 2'h2}}
};
assign ram3WA = {
addr0_10[MRR-1:2] & {MRR-2{addr0_10[1:0] == 2'h3}} |
addr1_10[MRR-1:2] & {MRR-2{addr1_10[1:0] == 2'h3}} |
addr2_10[MRR-1:2] & {MRR-2{addr2_10[1:0] == 2'h3}} |
addr3_10[MRR-1:2] & {MRR-2{addr3_10[1:0] == 2'h3}}
};
assign ram0WD = {
{xIm0_10, xRe0_10} & {32{addr0_10[1:0] == 2'h0}} |
{xIm1_10, xRe1_10} & {32{addr1_10[1:0] == 2'h0}} |
{xIm2_10, xRe2_10} & {32{addr2_10[1:0] == 2'h0}} |
{xIm3_10, xRe3_10} & {32{addr3_10[1:0] == 2'h0}}
};
assign ram1WD = {
{xIm0_10, xRe0_10} & {32{addr0_10[1:0] == 2'h1}} |
{xIm1_10, xRe1_10} & {32{addr1_10[1:0] == 2'h1}} |
{xIm2_10, xRe2_10} & {32{addr2_10[1:0] == 2'h1}} |
{xIm3_10, xRe3_10} & {32{addr3_10[1:0] == 2'h1}}
};
assign ram2WD = {
{xIm0_10, xRe0_10} & {32{addr0_10[1:0] == 2'h2}} |
{xIm1_10, xRe1_10} & {32{addr1_10[1:0] == 2'h2}} |
{xIm2_10, xRe2_10} & {32{addr2_10[1:0] == 2'h2}} |
{xIm3_10, xRe3_10} & {32{addr3_10[1:0] == 2'h2}}
};
assign ram3WD = {
{xIm0_10, xRe0_10} & {32{addr0_10[1:0] == 2'h3}} |
{xIm1_10, xRe1_10} & {32{addr1_10[1:0] == 2'h3}} |
{xIm2_10, xRe2_10} & {32{addr2_10[1:0] == 2'h3}} |
{xIm3_10, xRe3_10} & {32{addr3_10[1:0] == 2'h3}}
};
// **************************** FUNCTIONS and TASKS ****************************
// 入力SRAMアドレスの生成:
// 先ずPhaseに従ってカウンタの回転を行いRadix-4の入力に相応しいアドレスを生成
// 次に前Phaseで行ったアドレスの攪乱を元に戻すための攪乱を行う
function [MRR-1:0] addrInFunc;
input [MRR-1:0] idx;
input [2:0] phase;
input [3:0] radix;
reg [MRR-1:0] result;
reg [MRR-1:0] twid;
begin
// Rotate
casex (phase)
3'h1: result = {idx[9:4], idx[1:0], idx[3:2]};
3'h2: result = {idx[9:6], idx[1:0], idx[5:2]};
3'h3: result = {idx[9:8], idx[1:0], idx[7:2]};
3'h4: result = { idx[1:0], idx[9:2]};
default: result = idx;
endcase
// Twiddle & Twidle Factor
casex (phase)
3'h1: twid = {{MRR-2{1'b0}}, idx[1:0] };
3'h2: twid = {{MRR-2{1'b0}}, idx[1:0] ^ idx[5:4]};
3'h3: twid = {{MRR-2{1'b0}}, idx[1:0] ^ idx[7:6]};
3'h4: twid = {{MRR-2{1'b0}}, idx[1:0] ^ idx[9:8]};
default:
// LoadDataでアドレスの攪乱(2度することで元に戻る)
case (radix)
4'h4: twid = {{MRR-2{1'b0}}, idx[3:2]};
4'h6: twid = {{MRR-2{1'b0}}, idx[5:4]};
4'h8: twid = {{MRR-2{1'b0}}, idx[7:6]};
default:
twid = {{MRR-2{1'b0}}, idx[MRR-1:MRR-2]};
endcase
endcase
// Result
addrInFunc = result ^ twid;
end
endfunction
// 出力SRAMアドレスの生成:
// 先ずPhaseに従ってカウンタの回転を行いRadix-4の出力に相応しいアドレスを生成
// 次に最終Phase(border)でない限り前Phaseで行ったアドレスの攪乱を元に戻すための攪乱を行う
function [MRR-1:0] addrOutFunc;
input [MRR-1:0] idx;
input [2:0] phase;
input [3:0] radix;
reg border;
reg [MRR-1:0] result;
reg [MRR-1:0] twid;
begin
case (radix)
4'h4: border = (phase == 3'h1);
4'h6: border = (phase == 3'h2);
4'h8: border = (phase == 3'h3);
default: border = (phase == 3'h4);
endcase
// Rotate
case (phase)
3'h1: result = {idx[9:4], idx[1:0], idx[3:2]};
3'h2: result = {idx[9:6], idx[1:0], idx[5:2]};
3'h3: result = {idx[9:8], idx[1:0], idx[7:2]};
3'h4: result = { idx[1:0], idx[9:2]};
default: result = idx;
endcase
// Twiddle & Twidle Factor
casex ({border, phase})
{1'b0, 3'h0}: twid = {{MRR-2{1'b0}}, result[3:2]};
{1'b0, 3'h1}: twid = {{MRR-2{1'b0}}, result[3:2] ^ result[5:4]};
{1'b0, 3'h2}: twid = {{MRR-2{1'b0}}, result[5:4] ^ result[7:6]};
{1'b0, 3'h3}: twid = {{MRR-2{1'b0}}, result[7:6] ^ result[9:8]};
default:
// storeDataでアドレスの攪乱(2度することで元に戻る)
case (radix)
4'h4: twid = {{MRR-2{1'b0}}, result[3:2]};
4'h6: twid = {{MRR-2{1'b0}}, result[5:4]};
4'h8: twid = {{MRR-2{1'b0}}, result[7:6]};
default:
twid = {{MRR-2{1'b0}}, result[MRR-1:MRR-2]};
endcase
endcase
// Result
addrInFunc = result ^ twid;
end
endfunction
endmodule // bfCalc
// *****************************************************************************
/* **************************** MODULE PREAMBLE ********************************
Copyright (c) 2012, ArchiTek
This document constitutes confidential and proprietary information
of ArchiTek. All rights reserved.
*/
// ***************************** MODULE HEADER *********************************
module fftCoef (
wIndex,
wPhase,
wRe0, wIm0, wRe1, wIm1, wRe2, wIm2, wRe3, wIm3
);
// ************************* PARAMETER DECLARATIONS ****************************
parameter MRR = 10; // Max Radix Radix
parameter ZERO = 16'h0000;
parameter ONEP = 16'h3c00;
parameter ONEM = 16'hbc00;
// *************************** I/O DECLARATIONS ********************************
// ROM(組み合わせ回路)なのでクロックはない
input [MRR-3:0] wIndex;
input [2:0] wPhase;
output [15:0] wRe0, wIm0, wRe1, wIm1, wRe2, wIm2, wRe3, wIm3;
// **************************** LOCAL DECLARATIONS *****************************
// Rotation Primitive
reg [MRR-3:0] index;
reg [3:0] div;
wire [MRR-1:0] rot;
// Index
wire [MRR-1:0] index0, index1, index2, index3;
wire [MRR-3:0] fIndex0, fIndex1, fIndex2, fIndex3;
wire [MRR-3:0] iIndex0, iIndex1, iIndex2, iIndex3;
// Indicator
wire z0, z1, z2, z3; // Zero
wire [15:0] rs0, rs1, rs2, rs3; // Re Sign
wire [15:0] is0, is1, is2, is3; // Im Sign
// Temporary
reg [15:0] wRe0, wIm0, wRe1, wIm1, wRe2, wIm2, wRe3, wIm3;
// ******************************** MODULE BODY ********************************
// -----------------------------------------------------------------------------
// Prepare
// Phaseによってテーブルをアクセスする角度粒度が異なるので調整する
always @(
wIndex or
wPhase
)
case (wPhase)
3'h0: begin
index = 8'd0;
div = 4'h8;
end
3'h1: begin
index = {6'd0, wIndex[1:0]};
div = 4'h6;
end
3'h2: begin
index = {4'd0, wIndex[3:0]};
div = 4'h4;
end
3'h3: begin
index = {2'd0, wIndex[5:0]};
div = 4'h2;
end
default: begin
index = wIndex;
div = 4'h0;
end
endcase
assign rot = {2'h0, index} << div;
// Radix-4の第一係数は常に角度0、その他は上記で求めた角度の倍数
assign index0 = {MRR{1'b0}};
assign index1 = rot;
assign index2 = rot << 1;
assign index3 = rot + (rot << 1);
// 正の方向と負の方向の角度を求めておく(π/4ずらす)、それぞれでsin(), cos()を求める
assign fIndex0 = index0[MRR-3:0];
assign fIndex1 = index1[MRR-3:0];
assign fIndex2 = index2[MRR-3:0];
assign fIndex3 = index3[MRR-3:0];
assign iIndex0 = ~fIndex0 + 1'b1;
assign iIndex1 = ~fIndex1 + 1'b1;
assign iIndex2 = ~fIndex2 + 1'b1;
assign iIndex3 = ~fIndex3 + 1'b1;
// 角度0を検知
assign z0 = ~|index0[MRR-3:0];
assign z1 = ~|index1[MRR-3:0];
assign z2 = ~|index2[MRR-3:0];
assign z3 = ~|index3[MRR-3:0];
// π/4を超えるものは符号の反転とsin(), cos()の入れ替えになるので、そのフラグを生成
assign rs0 = {^index0[MRR-1:MRR-2], 15'd0};
assign rs1 = {^index1[MRR-1:MRR-2], 15'd0};
assign rs2 = {^index2[MRR-1:MRR-2], 15'd0};
assign rs3 = {^index3[MRR-1:MRR-2], 15'd0};
assign is0 = {~index0[MRR-1], 15'd0};
assign is1 = {~index1[MRR-1], 15'd0};
assign is2 = {~index2[MRR-1], 15'd0};
assign is3 = {~index3[MRR-1], 15'd0};
// -----------------------------------------------------------------------------
// Rotation #0
// Radix-4の第一ポートの計算(常に1.0と0.0だが、汎用性を持たせるため記述)
always @(
index0 or
fIndex0 or
iIndex0 or
rs0 or
z0
)
casex ({z0, index0[MRR-1:MRR-2]})
3'b100: wRe0 = ONEP; // 1.0
3'b110: wRe0 = ONEM; // -1.0
3'b1x1: wRe0 = ZERO; // 0.0
3'b0x0: wRe0 = coefFunc(iIndex0) ^ rs0; // cos()
3'b0x1: wRe0 = coefFunc(fIndex0) ^ rs0; // sin()
endcase
always @(
index0 or
fIndex0 or
iIndex0 or
is0 or
z0
)
casex ({z0, index0[MRR-1:MRR-2]})
3'b1x0: wIm0 = ZERO; // 0.0
3'b101: wIm0 = ONEM; // -1.0
3'b111: wIm0 = ONEP; // 1.0
3'b0x0: wIm0 = coefFunc(fIndex0) ^ is0; // sin()
3'b0x1: wIm0 = coefFunc(iIndex0) ^ is0; // cos()
endcase
// -----------------------------------------------------------------------------
// Rotation #1
// Radix-4の第二ポートの計算
always @(
index1 or
fIndex1 or
iIndex1 or
rs1 or
z1
)
casex ({z1, index1[MRR-1:MRR-2]})
3'b100: wRe1 = ONEP; // 1.0
3'b110: wRe1 = ONEM; // -1.0
3'b1x1: wRe1 = ZERO; // 0.0
3'b0x0: wRe1 = coefFunc(iIndex1) ^ rs1; // cos()
3'b0x1: wRe1 = coefFunc(fIndex1) ^ rs1; // sin()
endcase
always @(
index1 or
fIndex1 or
iIndex1 or
is1 or
z1
)
casex ({z1, index1[MRR-1:MRR-2]})
3'b1x0: wIm1 = ZERO; // 0.0
3'b101: wIm1 = ONEM; // -1.0
3'b111: wIm1 = ONEP; // 1.0
3'b0x0: wIm1 = coefFunc(fIndex1) ^ is1; // sin()
3'b0x1: wIm1 = coefFunc(iIndex1) ^ is1; // cos()
endcase
// -----------------------------------------------------------------------------
// Rotation #2
// Radix-4の第三ポートの計算
always @(
index2 or
fIndex2 or
iIndex2 or
rs2 or
z2
)
casex ({z2, index2[MRR-1:MRR-2]})
3'b100: wRe2 = ONEP; // 1.0
3'b110: wRe2 = ONEM; // -1.0
3'b1x1: wRe2 = ZERO; // 0.0
3'b0x0: wRe2 = coefFunc(iIndex2) ^ rs2; // cos()
3'b0x1: wRe2 = coefFunc(fIndex2) ^ rs2; // sin()
endcase
always @(
index2 or
fIndex2 or
iIndex2 or
is2 or
z2
)
casex ({z2, index2[MRR-1:MRR-2]})
3'b1x0: wIm2 = ZERO; // 0.0
3'b101: wIm2 = ONEM; // -1.0
3'b111: wIm2 = ONEP; // 1.0
3'b0x0: wIm2 = coefFunc(fIndex2) ^ is2; // sin()
3'b0x1: wIm2 = coefFunc(iIndex2) ^ is2; // cos()
endcase
// -----------------------------------------------------------------------------
// Rotation #3
// Radix-4の第四ポートの計算
always @(
index3 or
fIndex3 or
iIndex3 or
rs3 or
z3
)
casex ({z3, index3[MRR-1:MRR-2]})
3'b100: wRe3 = ONEP; // 1.0
3'b110: wRe3 = ONEM; // -1.0
3'b1x1: wRe3 = ZERO; // 0.0
3'b0x0: wRe3 = coefFunc(iIndex3) ^ rs3; // cos()
3'b0x1: wRe3 = coefFunc(fIndex3) ^ rs3; // sin()
endcase
always @(
index3 or
fIndex3 or
iIndex3 or
is3 or
z3
)
casex ({z3, index3[MRR-1:MRR-2]})
3'b1x0: wIm3 = ZERO; // 0.0
3'b101: wIm3 = ONEM; // -1.0
3'b111: wIm3 = ONEP; // 1.0
3'b0x0: wIm3 = coefFunc(fIndex3) ^ is3; // sin()
3'b0x1: wIm3 = coefFunc(iIndex3) ^ is3; // cos()
endcase
// **************************** FUNCTIONS and TASKS ****************************
// ここがテーブルの本体、IEEE754 Binary16フォーマット
// 最大ポイント数が増える場合はここを増やす
function [15:0] coefFunc;
input [MRR-3:0] index;
reg [15:0] tmp;
begin
case (index)
8'h00: tmp = ZERO;
8'h01: tmp = 16'h1e48;
8'h02: tmp = 16'h2248;
8'h03: tmp = 16'h24b6;
8'h04: tmp = 16'h2648;
8'h05: tmp = 16'h27da;
8'h06: tmp = 16'h28b6;
8'h07: tmp = 16'h297f;
8'h08: tmp = 16'h2a48;
8'h09: tmp = 16'h2b11;
8'h0a: tmp = 16'h2bd9;
8'h0b: tmp = 16'h2c51;
8'h0c: tmp = 16'h2cb5;
8'h0d: tmp = 16'h2d1a;
8'h0e: tmp = 16'h2d7e;
8'h0f: tmp = 16'h2de2;
8'h10: tmp = 16'h2e46;
8'h11: tmp = 16'h2eaa;
8'h12: tmp = 16'h2f0e;
8'h13: tmp = 16'h2f72;
8'h14: tmp = 16'h2fd6;
8'h15: tmp = 16'h301d;
8'h16: tmp = 16'h304e;
8'h17: tmp = 16'h3080;
8'h18: tmp = 16'h30b2;
8'h19: tmp = 16'h30e4;
8'h1a: tmp = 16'h3115;
8'h1b: tmp = 16'h3147;
8'h1c: tmp = 16'h3179;
8'h1d: tmp = 16'h31aa;
8'h1e: tmp = 16'h31db;
8'h1f: tmp = 16'h320d;
8'h20: tmp = 16'h323e;
8'h21: tmp = 16'h326f;
8'h22: tmp = 16'h32a1;
8'h23: tmp = 16'h32d2;
8'h24: tmp = 16'h3303;
8'h25: tmp = 16'h3334;
8'h26: tmp = 16'h3365;
8'h27: tmp = 16'h3396;
8'h28: tmp = 16'h33c6;
8'h29: tmp = 16'h33f7;
8'h2a: tmp = 16'h3414;
8'h2b: tmp = 16'h342c;
8'h2c: tmp = 16'h3444;
8'h2d: tmp = 16'h345d;
8'h2e: tmp = 16'h3475;
8'h2f: tmp = 16'h348d;
8'h30: tmp = 16'h34a5;
8'h31: tmp = 16'h34bd;
8'h32: tmp = 16'h34d5;
8'h33: tmp = 16'h34ed;
8'h34: tmp = 16'h3505;
8'h35: tmp = 16'h351d;
8'h36: tmp = 16'h3534;
8'h37: tmp = 16'h354c;
8'h38: tmp = 16'h3564;
8'h39: tmp = 16'h357c;
8'h3a: tmp = 16'h3593;
8'h3b: tmp = 16'h35ab;
8'h3c: tmp = 16'h35c2;
8'h3d: tmp = 16'h35da;
8'h3e: tmp = 16'h35f1;
8'h3f: tmp = 16'h3608;
8'h40: tmp = 16'h361f;
8'h41: tmp = 16'h3637;
8'h42: tmp = 16'h364e;
8'h43: tmp = 16'h3665;
8'h44: tmp = 16'h367c;
8'h45: tmp = 16'h3693;
8'h46: tmp = 16'h36aa;
8'h47: tmp = 16'h36c1;
8'h48: tmp = 16'h36d7;
8'h49: tmp = 16'h36ee;
8'h4a: tmp = 16'h3705;
8'h4b: tmp = 16'h371b;
8'h4c: tmp = 16'h3732;
8'h4d: tmp = 16'h3748;
8'h4e: tmp = 16'h375e;
8'h4f: tmp = 16'h3775;
8'h50: tmp = 16'h378b;
8'h51: tmp = 16'h37a1;
8'h52: tmp = 16'h37b7;
8'h53: tmp = 16'h37cd;
8'h54: tmp = 16'h37e3;
8'h55: tmp = 16'h37f9;
8'h56: tmp = 16'h3807;
8'h57: tmp = 16'h3812;
8'h58: tmp = 16'h381d;
8'h59: tmp = 16'h3828;
8'h5a: tmp = 16'h3832;
8'h5b: tmp = 16'h383d;
8'h5c: tmp = 16'h3848;
8'h5d: tmp = 16'h3852;
8'h5e: tmp = 16'h385d;
8'h5f: tmp = 16'h3867;
8'h60: tmp = 16'h3872;
8'h61: tmp = 16'h387c;
8'h62: tmp = 16'h3887;
8'h63: tmp = 16'h3891;
8'h64: tmp = 16'h389b;
8'h65: tmp = 16'h38a6;
8'h66: tmp = 16'h38b0;
8'h67: tmp = 16'h38ba;
8'h68: tmp = 16'h38c4;
8'h69: tmp = 16'h38ce;
8'h6a: tmp = 16'h38d8;
8'h6b: tmp = 16'h38e2;
8'h6c: tmp = 16'h38ec;
8'h6d: tmp = 16'h38f6;
8'h6e: tmp = 16'h3900;
8'h6f: tmp = 16'h3909;
8'h70: tmp = 16'h3913;
8'h71: tmp = 16'h391d;
8'h72: tmp = 16'h3927;
8'h73: tmp = 16'h3930;
8'h74: tmp = 16'h393a;
8'h75: tmp = 16'h3943;
8'h76: tmp = 16'h394d;
8'h77: tmp = 16'h3956;
8'h78: tmp = 16'h395f;
8'h79: tmp = 16'h3969;
8'h7a: tmp = 16'h3972;
8'h7b: tmp = 16'h397b;
8'h7c: tmp = 16'h3984;
8'h7d: tmp = 16'h398d;
8'h7e: tmp = 16'h3996;
8'h7f: tmp = 16'h399f;
8'h80: tmp = 16'h39a8;
8'h81: tmp = 16'h39b1;
8'h82: tmp = 16'h39ba;
8'h83: tmp = 16'h39c3;
8'h84: tmp = 16'h39cb;
8'h85: tmp = 16'h39d4;
8'h86: tmp = 16'h39dc;
8'h87: tmp = 16'h39e5;
8'h88: tmp = 16'h39ed;
8'h89: tmp = 16'h39f6;
8'h8a: tmp = 16'h39fe;
8'h8b: tmp = 16'h3a07;
8'h8c: tmp = 16'h3a0f;
8'h8d: tmp = 16'h3a17;
8'h8e: tmp = 16'h3a1f;
8'h8f: tmp = 16'h3a27;
8'h90: tmp = 16'h3a2f;
8'h91: tmp = 16'h3a37;
8'h92: tmp = 16'h3a3f;
8'h93: tmp = 16'h3a47;
8'h94: tmp = 16'h3a4f;
8'h95: tmp = 16'h3a56;
8'h96: tmp = 16'h3a5e;
8'h97: tmp = 16'h3a65;
8'h98: tmp = 16'h3a6d;
8'h99: tmp = 16'h3a74;
8'h9a: tmp = 16'h3a7c;
8'h9b: tmp = 16'h3a83;
8'h9c: tmp = 16'h3a8a;
8'h9d: tmp = 16'h3a92;
8'h9e: tmp = 16'h3a99;
8'h9f: tmp = 16'h3aa0;
8'ha0: tmp = 16'h3aa7;
8'ha1: tmp = 16'h3aae;
8'ha2: tmp = 16'h3ab5;
8'ha3: tmp = 16'h3abc;
8'ha4: tmp = 16'h3ac2;
8'ha5: tmp = 16'h3ac9;
8'ha6: tmp = 16'h3ad0;
8'ha7: tmp = 16'h3ad6;
8'ha8: tmp = 16'h3add;
8'ha9: tmp = 16'h3ae3;
8'haa: tmp = 16'h3ae9;
8'hab: tmp = 16'h3af0;
8'hac: tmp = 16'h3af6;
8'had: tmp = 16'h3afc;
8'hae: tmp = 16'h3b02;
8'haf: tmp = 16'h3b08;
8'hb0: tmp = 16'h3b0e;
8'hb1: tmp = 16'h3b14;
8'hb2: tmp = 16'h3b1a;
8'hb3: tmp = 16'h3b20;
8'hb4: tmp = 16'h3b25;
8'hb5: tmp = 16'h3b2b;
8'hb6: tmp = 16'h3b30;
8'hb7: tmp = 16'h3b36;
8'hb8: tmp = 16'h3b3b;
8'hb9: tmp = 16'h3b41;
8'hba: tmp = 16'h3b46;
8'hbb: tmp = 16'h3b4b;
8'hbc: tmp = 16'h3b50;
8'hbd: tmp = 16'h3b55;
8'hbe: tmp = 16'h3b5a;
8'hbf: tmp = 16'h3b5f;
8'hc0: tmp = 16'h3b64;
8'hc1: tmp = 16'h3b69;
8'hc2: tmp = 16'h3b6e;
8'hc3: tmp = 16'h3b72;
8'hc4: tmp = 16'h3b77;
8'hc5: tmp = 16'h3b7b;
8'hc6: tmp = 16'h3b80;
8'hc7: tmp = 16'h3b84;
8'hc8: tmp = 16'h3b88;
8'hc9: tmp = 16'h3b8c;
8'hca: tmp = 16'h3b91;
8'hcb: tmp = 16'h3b95;
8'hcc: tmp = 16'h3b99;
8'hcd: tmp = 16'h3b9d;
8'hce: tmp = 16'h3ba0;
8'hcf: tmp = 16'h3ba4;
8'hd0: tmp = 16'h3ba8;
8'hd1: tmp = 16'h3bab;
8'hd2: tmp = 16'h3baf;
8'hd3: tmp = 16'h3bb2;
8'hd4: tmp = 16'h3bb6;
8'hd5: tmp = 16'h3bb9;
8'hd6: tmp = 16'h3bbc;
8'hd7: tmp = 16'h3bc0;
8'hd8: tmp = 16'h3bc3;
8'hd9: tmp = 16'h3bc6;
8'hda: tmp = 16'h3bc9;
8'hdb: tmp = 16'h3bcb;
8'hdc: tmp = 16'h3bce;
8'hdd: tmp = 16'h3bd1;
8'hde: tmp = 16'h3bd4;
8'hdf: tmp = 16'h3bd6;
8'he0: tmp = 16'h3bd9;
8'he1: tmp = 16'h3bdb;
8'he2: tmp = 16'h3bdd;
8'he3: tmp = 16'h3be0;
8'he4: tmp = 16'h3be2;
8'he5: tmp = 16'h3be4;
8'he6: tmp = 16'h3be6;
8'he7: tmp = 16'h3be8;
8'he8: tmp = 16'h3bea;
8'he9: tmp = 16'h3bec;
8'hea: tmp = 16'h3bed;
8'heb: tmp = 16'h3bef;
8'hec: tmp = 16'h3bf1;
8'hed: tmp = 16'h3bf2;
8'hee: tmp = 16'h3bf4;
8'hef: tmp = 16'h3bf5;
8'hf0: tmp = 16'h3bf6;
8'hf1: tmp = 16'h3bf7;
8'hf2: tmp = 16'h3bf8;
8'hf3: tmp = 16'h3bf9;
8'hf4: tmp = 16'h3bfa;
8'hf5: tmp = 16'h3bfb;
8'hf6: tmp = 16'h3bfc;
8'hf7: tmp = 16'h3bfd;
8'hf8: tmp = 16'h3bfe;
8'hf9: tmp = 16'h3bfe;
8'hfa: tmp = 16'h3bff;
8'hfb: tmp = 16'h3bff;
8'hfc: tmp = 16'h3bff;
8'hfd: tmp = ONEP;
8'hfe: tmp = ONEP;
8'hff: tmp = ONEP;
endcase
coefFunc = tmp;
end
endfunction
endmodule // coef
// *****************************************************************************
回路デザイン > 設計例 [FFT] > コーディング3 次のページ(テスト) このページのTOP ▲