論理回路デザイン
ArchiTek home page
コーディング1

コード(トップモジュールRTL)

/* **************************** MODULE PREAMBLE ********************************

        Copyright (c) 2011, ArchiTek
        This document constitutes confidential and proprietary information
        of ArchiTek. All rights reserved.
*/

// ***************************** MODULE HEADER *********************************

module fft (
        iVld, iStall,
        oVld, oStall,

        mRdStrb, mRdAck, mRdData,
        mWrStrb, mWrAck, mWrData,

        reset, clk

        );

// ************************* PARAMETER DECLARATIONS ****************************

        // 最大のポイント数の指数はカウンタ等のビット範囲を定める
        parameter               MRR     = 10;           // Max Radix Radix

        // 処理するポイント数は予め指定、可変にする場合はiVldと同期させる
        parameter               RADIX   = 4'd10;

// *************************** I/O DECLARATIONS ********************************

        // Pipe Input
        input                   iVld;
        output                  iStall;

        // Pipe Output
        output                  oVld;
        input                   oStall;

        // データは16ビットの半精度浮動小数点が8つ並ぶ(4x2ペア)
        // Memory Interface (Read Data)
        output                  mRdStrb;
        input                   mRdAck;
        input   [127:0]         mRdData;

        // Memory Interface (Write Data)
        output                  mWrStrb;
        input                   mWrAck;
        output  [127:0]         mWrData;

        // Utility
        input                   reset;
        input                   clk;

// ************************** LOCAL DECLARATIONS *******************************

        // ここから各ユニットの入出力信号を定義する
        // Load Data
        wire                    oLoadDataVld;
        wire                    oLoadDataStall;
        wire    [1:0]           oLoadDataFlip;
        wire                    ldRam0WE, ldRam1WE, ldRam2WE, ldRam3WE;
        wire    [7:0]           ldRam0WA, ldRam1WA, ldRam2WA, ldRam3WA;
        wire    [31:0]          ldRam0WD, ldRam1WD, ldRam2WD, ldRam3WD;

        // Butterfly Calc FIFO
        wire                    iBFIFOVld;
        wire                    iBFIFOStall;
        wire                    oBFIFOVld;
        wire                    oBFIFOStall;

        // Butterfly Calc
        wire                    iBfCalcVld;
        wire                    iBfCalcStall;
        wire                    oBfCalcVld;
        wire                    oBfCalcStall;
        wire    [1:0]           bcRamRF;
        reg     [1:0]           bcRamRFB;
        wire                    bcRamRP;
        wire                    bcRam0RE, bcRam1RE, bcRam2RE, bcRam3RE;
        wire    [7:0]           bcRam0RA, bcRam1RA, bcRam2RA, bcRam3RA;
        wire    [31:0]          bcRam0RD, bcRam1RD, bcRam2RD, bcRam3RD;
        wire                    bcRamWP;
        wire    [1:0]           bcRamWF;
        wire                    bcRam0WE, bcRam1WE, bcRam2WE, bcRam3WE;
        wire    [7:0]           bcRam0WA, bcRam1WA, bcRam2WA, bcRam3WA;
        wire    [31:0]          bcRam0WD, bcRam1WD, bcRam2WD, bcRam3WD;

        // Coefficients of Fourier
        wire    [MRR-3:0]       wIndex;
        wire    [2:0]           wPhase;
        wire    [15:0]          wRe0, wIm0, wRe1, wIm1, wRe2, wIm2, wRe3, wIm3;

        // Store Data FIFO
        wire                    iSdFIFOVld;
        wire                    iSdFIFOStall;
        wire                    oSdFIFOVld;
        wire                    oSdFIFOStall;

        // Store Data
        wire                    iStoreDataVld;
        wire                    iStoreDataStall;
        wire    [1:0]           oStoreDataFlip;
        reg     [1:0]           oStoreDataFlipB;
        wire                    stRam0RE, stRam1RE, stRam2RE, stRam3RE;
        wire    [7:0]           stRam0RA, stRam1RA, stRam2RA, stRam3RA;
        wire    [31:0]          stRam0RD, stRam1RD, stRam2RD, stRam3RD;

        // 8つ(4Bank x2セット)あるSRAM信号の入出力信号を定義する
        // アドレスレンジは4Bankに分かれていることから2を引く
        // データには実数と虚数のペアが入る
        // SRAM Signals
        wire                    ram0WE0, ram0WE1, ram1WE0, ram1WE1,
                                ram2WE0, ram2WE1, ram3WE0, ram3WE1;
        wire    [MRR-2:0]       ram0WA0, ram0WA1, ram1WA0, ram1WA1,
                                ram2WA0, ram2WA1, ram3WA0, ram3WA1;
        wire    [31:0]          ram0WD0, ram0WD1, ram1WD0, ram1WD1,
                                ram2WD0, ram2WD1, ram3WD0, ram3WD1;
        wire                    ram0RE0, ram0RE1, ram1RE0, ram1RE1,
                                ram2RE0, ram2RE1, ram3RE0, ram3RE1;
        wire    [MRR-2:0]       ram0RA0, ram0RA1, ram1RA0, ram1RA1,
                                ram2RA0, ram2RA1, ram3RA0, ram3RA1;
        wire    [31:0]          ram0RD0, ram0RD1, ram1RD0, ram1RD1,
                                ram2RD0, ram2RD1, ram3RD0, ram3RD1;

// ****************************** MODULE BODY **********************************

// -----------------------------------------------------------------------------
// Load Data
// RADIXが可変なら、iVldに同期させる
// iStallはLoadDataの処理がほぼ終わるまでアサートするため、突き放したい場合は前段にFIFOを入れる
fftLoadData #(MRR) loadData_0 (
        .iVld                   (iVld),
        .iStall                 (iStall),
        .iRadix                 (RADIX),
        .oVld                   (oLoadDataVld),
        .oStall                 (oLoadDataStall),
        .oFlip                  (oLoadDataFlip),        // SRAMダブルバッファ制御に使用
        .mStrb                  (mRdStrb),
        .mAck                   (mRdAck),
        .mData                  (mRdData),
        .ram0WE                 (ldRam0WE),             // SRAMへのWrite信号グループ
        .ram0WA                 (ldRam0WA),
        .ram0WD                 (ldRam0WD),
        .ram1WE                 (ldRam1WE),
        .ram1WA                 (ldRam1WA),
        .ram1WD                 (ldRam1WD),
        .ram2WE                 (ldRam2WE),
        .ram2WA                 (ldRam2WA),
        .ram2WD                 (ldRam2WD),
        .ram3WE                 (ldRam3WE),
        .ram3WA                 (ldRam3WA),
        .ram3WD                 (ldRam3WD),
        .reset                  (reset),
        .clk                    (clk)
        );

assign oLoadDataStall   = iBFIFOStall;

// -----------------------------------------------------------------------------
// Butterfly Calc FIFO
// LoadDataとBcCalcを繋ぐFIFO、データがないのでSignalingだけ
sig_2 sig_0 (
        .iVld                   (iBFIFOVld),
        .iStall                 (iBFIFOStall),
        .oVld                   (oBFIFOVld),
        .oStall                 (oBFIFOStall),
        .reset                  (reset),
        .clk                    (clk)
        );

assign iBFIFOVld        = oLoadDataVld;
assign oBFIFOStall      = iBfCalcStall;

// -----------------------------------------------------------------------------
// Butterfly Calculation
// RADIXが可変なら、iVldに同期させる
// 逆変換が必要な場合もiVldに同期したフラグが必要
fftBfCalc #(MRR) bfCalc_0 (
        .iVld                   (iBfCalcVld),
        .iStall                 (iBfCalcStall),
        .iRadix                 (RADIX),
        .oVld                   (oBfCalcVld),
        .oStall                 (oBfCalcStall),
        .wIndex                 (wIndex),               // 係数テーブルへのインターフェイス
        .wPhase                 (wPhase),
        .wRe0                   (wRe0),
        .wIm0                   (wIm0),
        .wRe1                   (wRe1),
        .wIm1                   (wIm1),
        .wRe2                   (wRe2),
        .wIm2                   (wIm2),
        .wRe3                   (wRe3),
        .wIm3                   (wIm3),
        .ramRF                  (bcRamRF),              // SRAMダブルバッファ制御に使用(Read)
        .ramRP                  (bcRamRP),              // SRAM領域制御に使用(Read)
        .ram0RE                 (bcRam0RE),             // SRAMへのRead信号グループ
        .ram0RA                 (bcRam0RA),
        .ram0RD                 (bcRam0RD),
        .ram1RE                 (bcRam1RE),
        .ram1RA                 (bcRam1RA),
        .ram1RD                 (bcRam1RD),
        .ram2RE                 (bcRam2RE),
        .ram2RA                 (bcRam2RA),
        .ram2RD                 (bcRam2RD),
        .ram3RE                 (bcRam3RE),
        .ram3RA                 (bcRam3RA),
        .ram3RD                 (bcRam3RD),
        .ramWF                  (bcRamWF),              // SRAMダブルバッファ制御に使用(Write)
        .ramWP                  (bcRamWP),              // SRAM領域制御に使用(Write)
        .ram0WE                 (bcRam0WE),             // SRAMへのWrite信号グループ
        .ram0WA                 (bcRam0WA),
        .ram0WD                 (bcRam0WD),
        .ram1WE                 (bcRam1WE),
        .ram1WA                 (bcRam1WA),
        .ram1WD                 (bcRam1WD),
        .ram2WE                 (bcRam2WE),
        .ram2WA                 (bcRam2WA),
        .ram2WD                 (bcRam2WD),
        .ram3WE                 (bcRam3WE),
        .ram3WA                 (bcRam3WA),
        .ram3WD                 (bcRam3WD),
        .reset                  (reset),
        .clk                    (clk)
        );

assign iBfCalcVld       = oBFIFOVld;
assign oBfCalcStall     = iSdFIFOStall;

// -----------------------------------------------------------------------------
// Coefficients of Fourier
// 係数テーブルモジュール、レイテンシ0のROMとして振る舞う
fftCoef #(MRR) coef_0 (
        .wIndex                 (wIndex),
        .wPhase                 (wPhase),
        .wRe0                   (wRe0),
        .wIm0                   (wIm0),
        .wRe1                   (wRe1),
        .wIm1                   (wIm1),
        .wRe2                   (wRe2),
        .wIm2                   (wIm2),
        .wRe3                   (wRe3),
        .wIm3                   (wIm3)
        );

// -----------------------------------------------------------------------------
// Store Data FIFO
// BcCalcとStoreDataを繋ぐFIFO、データがないのでSignalingだけ
sig_2 sig_1 (
        .iVld                   (iSdFIFOVld),
        .iStall                 (iSdFIFOStall),
        .oVld                   (oSdFIFOVld),
        .oStall                 (oSdFIFOStall),
        .reset                  (reset),
        .clk                    (clk)
        );

assign iSdFIFOVld       = oBfCalcVld;
assign oSdFIFOStall     = iStoreDataStall;

// -----------------------------------------------------------------------------
// Store Data
// RADIXが可変なら、iVldに同期させる
// oVldは最後のデータを出し切った時点でアサート
// アサート期間以外でoStallをアサートしてもパイプラインは止まらない
fftStoreData #(MRR) storeData_0 (
        .iVld                   (iStoreDataVld),
        .iStall                 (iStoreDataStall),
        .iRadix                 (RADIX),
        .oVld                   (oVld),
        .oStall                 (oStall),
        .oFlip                  (oStoreDataFlip),       // SRAMダブルバッファ制御に使用
        .mStrb                  (mWrStrb),
        .mAck                   (mWrAck),
        .mData                  (mWrData),
        .ram0RE                 (stRam0RE),             // SRAMへのRead信号グループ
        .ram0RA                 (stRam0RA),
        .ram0RD                 (stRam0RD),
        .ram1RE                 (stRam1RE),
        .ram1RA                 (stRam1RA),
        .ram1RD                 (stRam1RD),
        .ram2RE                 (stRam2RE),
        .ram2RA                 (stRam2RA),
        .ram2RD                 (stRam2RD),
        .ram3RE                 (stRam3RE),
        .ram3RA                 (stRam3RA),
        .ram3RD                 (stRam3RD),
        .reset                  (reset),
        .clk                    (clk)
        );

assign iStoreDataVld    = oSdFIFOVld;

// -----------------------------------------------------------------------------
// SRAM Signals
// LoadData, BcCalcのSRAM Write信号をマージ
// oLoadDataFlipとbcRamWFは0か排他的な関係になっているため信号は重ならない
// また、それぞれのMSBとLSBも排他的になっており、同じユニットが2セット同時アクセスすることはない
assign {
        ram0WE0, ram0WA0, ram0WD0,
        ram1WE0, ram1WA0, ram1WD0,
        ram2WE0, ram2WA0, ram2WD0,
        ram3WE0, ram3WA0, ram3WD0
        }               = {4*(MRR+32){oLoadDataFlip[0]}} & {
                                ldRam0WE, 1'b0, ldRam0WA, ldRam0WD,
                                ldRam1WE, 1'b0, ldRam1WA, ldRam1WD,
                                ldRam2WE, 1'b0, ldRam2WA, ldRam2WD,
                                ldRam3WE, 1'b0, ldRam3WA, ldRam3WD
                                }
                        | {4*(MRR+32){bcRamWF[0]}} & {
                                bcRam0WE, bcRamWP, bcRam0WA, bcRam0WD,
                                bcRam1WE, bcRamWP, bcRam1WA, bcRam1WD,
                                bcRam2WE, bcRamWP, bcRam2WA, bcRam2WD,
                                bcRam3WE, bcRamWP, bcRam3WA, bcRam3WD
                                };

assign {
        ram0WE1, ram0WA1, ram0WD1,
        ram1WE1, ram1WA1, ram1WD1,
        ram2WE1, ram2WA1, ram2WD1,
        ram3WE1, ram3WA1, ram3WD1
        }               = {4*(MRR+32){oLoadDataFlip[1]}} & {
                                ldRam0WE, 1'b0, ldRam0WA, ldRam0WD,
                                ldRam1WE, 1'b0, ldRam1WA, ldRam1WD,
                                ldRam2WE, 1'b0, ldRam2WA, ldRam2WD,
                                ldRam3WE, 1'b0, ldRam3WA, ldRam3WD
                                }
                        | {4*(MRR+32){bcRamWF[1]}} & {
                                bcRam0WE, bcRamWP, bcRam0WA, bcRam0WD,
                                bcRam1WE, bcRamWP, bcRam1WA, bcRam1WD,
                                bcRam2WE, bcRamWP, bcRam2WA, bcRam2WD,
                                bcRam3WE, bcRamWP, bcRam3WA, bcRam3WD
                                };

// BcCalc, StoreDataのSRAM Read信号をマージ
// 仕組みは上記Writeと同じ
assign {
        ram0RE0, ram0RA0,
        ram1RE0, ram1RA0,
        ram2RE0, ram2RA0,
        ram3RE0, ram3RA0
        }               = {4*MRR{oStoreDataFlip[0]}} & {
                                stRam0RE, 1'b1, stRam0RA,
                                stRam1RE, 1'b1, stRam1RA,
                                stRam2RE, 1'b1, stRam2RA,
                                stRam3RE, 1'b1, stRam3RA
                                }
                        | {4*MRR{bcRamRF[0]}} & {
                                bcRam0RE, bcRamRP, bcRam0RA,
                                bcRam1RE, bcRamRP, bcRam1RA,
                                bcRam2RE, bcRamRP, bcRam2RA,
                                bcRam3RE, bcRamRP, bcRam3RA
                                };

assign {
        ram0RE1, ram0RA1,
        ram1RE1, ram1RA1,
        ram2RE1, ram2RA1,
        ram3RE1, ram3RA1
        }               = {4*MRR{oStoreDataFlip[1]}} & {
                                stRam0RE, 1'b1, stRam0RA,
                                stRam1RE, 1'b1, stRam1RA,
                                stRam2RE, 1'b1, stRam2RA,
                                stRam3RE, 1'b1, stRam3RA
                                }
                        | {4*MRR{bcRamRF[1]}} & {
                                bcRam0RE, bcRamRP, bcRam0RA,
                                bcRam1RE, bcRamRP, bcRam1RA,
                                bcRam2RE, bcRamRP, bcRam2RA,
                                bcRam3RE, bcRamRP, bcRam3RA
                                };

// Readデータを分配
assign {stRam0RD, stRam1RD, stRam2RD, stRam3RD}
                        = {128{oStoreDataFlipB[0]}} & {ram0RD0, ram1RD0, ram2RD0, ram3RD0}
                        | {128{oStoreDataFlipB[1]}} & {ram0RD1, ram1RD1, ram2RD1, ram3RD1};

assign {bcRam0RD, bcRam1RD, bcRam2RD, bcRam3RD}
                        = {128{bcRamRFB[0]}} & {ram0RD0, ram1RD0, ram2RD0, ram3RD0}
                        | {128{bcRamRFB[1]}} & {ram0RD1, ram1RD1, ram2RD1, ram3RD1};

// Readデータはアクセスに対し遅延するため、データ配分に関わるbcRamRFとoStoreDataFlipのラッチが必要
always @(posedge clk)
        if (reset)
                bcRamRFB        <= #1 2'h0;
        else if (|bcRamRF)      // パイプラインStallを加味(bcRamRFにStallが織り込まれている)
                bcRamRFB        <= #1 bcRamRF;

always @(posedge clk)
        if (reset)
                oStoreDataFlipB <= #1 2'h0;
        else if (|oStoreDataFlip)
                oStoreDataFlipB <= #1 oStoreDataFlip;

// -----------------------------------------------------------------------------
// SRAM #0
dualSRAM #(32, MRR-1) ram_00 (
        .WE                     (ram0WE0),
        .WA                     (ram0WA0),
        .WD                     (ram0WD0),
        .RE                     (ram0RE0),
        .RA                     (ram0RA0),
        .RD                     (ram0RD0),
        .CK                     (clk)
        );

dualSRAM #(32, MRR-1) ram_01 (
        .WE                     (ram0WE1),
        .WA                     (ram0WA1),
        .WD                     (ram0WD1),
        .RE                     (ram0RE1),
        .RA                     (ram0RA1),
        .RD                     (ram0RD1),
        .CK                     (clk)
        );

// -----------------------------------------------------------------------------
// SRAM #1
dualSRAM #(32, MRR-1) ram_10 (
        .WE                     (ram1WE0),
        .WA                     (ram1WA0),
        .WD                     (ram1WD0),
        .RE                     (ram1RE0),
        .RA                     (ram1RA0),
        .RD                     (ram1RD0),
        .CK                     (clk)
        );

dualSRAM #(32, MRR-1) ram_11 (
        .WE                     (ram1WE1),
        .WA                     (ram1WA1),
        .WD                     (ram1WD1),
        .RE                     (ram1RE1),
        .RA                     (ram1RA1),
        .RD                     (ram1RD1),
        .CK                     (clk)
        );

// -----------------------------------------------------------------------------
// SRAM #2
dualSRAM #(32, MRR-1) ram_20 (
        .WE                     (ram2WE0),
        .WA                     (ram2WA0),
        .WD                     (ram2WD0),
        .RE                     (ram2RE0),
        .RA                     (ram2RA0),
        .RD                     (ram2RD0),
        .CK                     (clk)
        );

dualSRAM #(32, MRR-1) ram_21 (
        .WE                     (ram2WE1),
        .WA                     (ram2WA1),
        .WD                     (ram2WD1),
        .RE                     (ram2RE1),
        .RA                     (ram2RA1),
        .RD                     (ram2RD1),
        .CK                     (clk)
        );

// -----------------------------------------------------------------------------
// SRAM #3
dualSRAM #(32, MRR-1) ram_30 (
        .WE                     (ram3WE0),
        .WA                     (ram3WA0),
        .WD                     (ram3WD0),
        .RE                     (ram3RE0),
        .RA                     (ram3RA0),
        .RD                     (ram3RD0),
        .CK                     (clk)
        );

dualSRAM #(32, MRR-1) ram_31 (
        .WE                     (ram3WE1),
        .WA                     (ram3WA1),
        .WD                     (ram3WD1),
        .RE                     (ram3RE1),
        .RA                     (ram3RA1),
        .RD                     (ram3RD1),
        .CK                     (clk)
        );

// ************************** FUNCTIONS and TASKS ******************************

endmodule

// *****************************************************************************
        

コード(Signaling FIFO RTL)

/* **************************** MODULE PREAMBLE ********************************

        Copyright (c) 2011, ArchiTek
        This document constitutes confidential and proprietary information
        of ArchiTek. All rights reserved.
        // FIFO記述からデータを抜いたもの
*/

// ***************************** MODULE HEADER *********************************

module sig_2 (
        iVld,
        iStall,

        oVld,
        oStall,

        reset,
        clk

        );

// *************************** I/O DECLARATIONS ********************************

        input                   iVld;
        output                  iStall;

        output                  oVld;
        input                   oStall;

        input                   reset;
        input                   clk;

// ************************** LOCAL DECLARATIONS *******************************

        reg                     sVld;
        reg                     sVldD;

        reg                     oVld;
        reg                     oVldD;

// ******************************** MODULE BODY ********************************

// -----------------------------------------------------------------------------
// FIFO In
always @(posedge clk)
        if (reset)
                sVld            <= #1 1'b0;
        else
                sVld            <= #1 sVldD;

always @(
        iVld or
        sVld or
        oVld or
        oStall
        )
        casex ({iVld, sVld, !oVld | !oStall})
                3'bx11: sVldD           = 1'b0;
                3'b1x0: sVldD           = 1'b1;
                default:
                        sVldD           = sVld;
        endcase

assign iStall           = sVld;

// -----------------------------------------------------------------------------
// FIFO Out
always @(posedge clk)
        if (reset)
                oVld            <= #1 1'b0;
        else
                oVld            <= #1 oVldD;

always @(
        iVld or
        sVld or
        oVld or
        oStall
        )
        if (!oVld | !oStall)
                oVldD           = iVld | sVld;
        else
                oVldD           = oVld;

// **************************** FUNCTIONS and TASKS ****************************

endmodule

// *****************************************************************************
        

回路デザイン > 設計例 [FFT] > コーディング1    次のページ(コーディング2)   このページのTOP ▲

[1]
ArchiTekの仕様書frFFTを参考にしてみて下さい。

ただ、削った機能だとしても市販のIPに負けず劣らずの実力はあると思います。