nao-milkの経験ブログ

25年間の半導体エンジニア経験で知り得た内容を記載したブログです。

FRAMにアクセス (Niosコーディング編)

f:id:nao-milk:20210425180306p:plain

Quartusを実行し、リソースとタイミングもOKだったので、次はNiosのプログラムコーディングとシミュレーションについてになります。
NiosはC言語で記述し、シミュレーションはFPGA トップからの行います。

ここでは、シミュレーションを実行する前のNiosのプログラム作成とテストベンチ記述を記載しています。
トップ構成は、以下をご参照ください。
nao-milk.hatenablog.com

※Quartusを実行した時のリソース使用状況とタイミングに関しては、以下をご参照ください。
nao-milk.hatenablog.com

シミュレーション内容

目的

接続が正しく行われるかを確認するため、Niosを含めたシミュレーションを行います。

経路

接続が正しく行われているか各経路を確認します。
経路は以下の通りになります。

f:id:nao-milk:20210425152624p:plain
データの流れ

①マスタモード時、FRAMの内容をRAMに格納できること。
②RAMに格納されたデータをNIOSでリードできること。
③NIOSからRAMにデータを格納できること。
④RAMからFRAMにデータを格納できること。
⑤FRAMからリードしたデータをRAMに格納できること。
⑥NIOSからFRAMにデータを格納できること。
 また、FRAMからNIOSでリードできること。
⑦割り込みが発生し、NIOSに届くこと。
⑧割り込み処理が実行され、割り込みをクリアできること。

メモリマップ

CPU(Nios)から見えるOnChipMemoryはCPU_MEMとPARAMETERになります。
CPU_MEMはNIOSが使用するプログラムや変数などとなり、PARAMETERはFRAMのデータを格納するために使用します。
※FRAMはパラメータ(USERブロックのレジスタ設定値など。。。)を保存するための用途と想定しており、起動時にFRAMからLoadし、終了時や設定変更時にSaveするイメージとなります。

メモリPARAMETER

「Device ID」「Serial Number」「Special Sector」「Data Memory」「その他(Temporary)」の領域に区切り、マスタモードでLoadする時に分割して保存して使用します。
領域が固定されるようLinkerで開始アドレスと領域を指定し、C言語で変数とリンク付けしています。

Linker設定

Linkerの設定内容は、以下通りです。

f:id:nao-milk:20210425170218p:plain
Linker設定
メモリマップ

メモリPARAMETERのアドレスマップは以下の通りです。

f:id:nao-milk:20210425163622p:plain
PARAMETERメモリマップ
リンク方法

変数の関連付けは、main.cで設定します。

unsigned char   FramID[  16]    __attribute__   ((section (".fram_id")));   // Device ID
unsigned char   FramSN[  16]    __attribute__   ((section (".fram_sn")));   // Serial Number
unsigned char   FramSS[ 256]    __attribute__   ((section (".fram_ss")));   // Special Sector
unsigned char   FramDT[2048]    __attribute__   ((section (".fram_dt")));   // Data Memory
unsigned char   FramTM[1024]    __attribute__   ((section (".fram_tm")));   // Temporary
unsigned char   FramST          __attribute__   ((section (".fram_tm")));   // Status

「その他(Temporary)」は自由な変数として使用できるようにしています。
従って、FramTM[1024]FramSTコンパイラ任せとなります。

リンク確認

コンパイル後、変数に指定したセクションが関連付けられているか、マップファイルで確認します。
マップファイルの抜粋を以下に示します。

Memory Configuration

Name             Origin             Length             Attributes
reset            0x0000000000000000 0x0000000000000020
CPU_MEM          0x0000000000000020 0x0000000000003fe0
prm_ram_id       0x0000000000200000 0x0000000000000010
prm_ram_sn       0x0000000000200010 0x0000000000000010
prm_ram_ss       0x0000000000200020 0x0000000000000100
prm_ram_dt       0x0000000000200120 0x0000000000000800
prm_ram_tm       0x0000000000200920 0x00000000000006e0
*default*        0x0000000000000000 0xffffffffffffffff

===== 略 =====
Linker script and memory map
  .............
.fram_id        0x0000000000200000       0x10
                [!provide]                        PROVIDE (_alt_partition_fram_id_start, ABSOLUTE (.))
 *(.fram_id .fram_id.*)
 .fram_id       0x0000000000200000       0x10 obj/default/main.o
                0x0000000000200000                FramID
                0x0000000000200010                . = ALIGN (0x4)
                [!provide]                        PROVIDE (_alt_partition_fram_id_end, ABSOLUTE (.))

.fram_sn        0x0000000000200010       0x10
                [!provide]                        PROVIDE (_alt_partition_fram_sn_start, ABSOLUTE (.))
 *(.fram_sn .fram_sn.*)
 .fram_sn       0x0000000000200010       0x10 obj/default/main.o
                0x0000000000200010                FramSN
                0x0000000000200020                . = ALIGN (0x4)
                [!provide]                        PROVIDE (_alt_partition_fram_sn_end, ABSOLUTE (.))

.fram_ss        0x0000000000200020      0x100
                [!provide]                        PROVIDE (_alt_partition_fram_ss_start, ABSOLUTE (.))
 *(.fram_ss .fram_ss.*)
 .fram_ss       0x0000000000200020      0x100 obj/default/main.o
                0x0000000000200020                FramSS
                0x0000000000200120                . = ALIGN (0x4)
                [!provide]                        PROVIDE (_alt_partition_fram_ss_end, ABSOLUTE (.))

.fram_dt        0x0000000000200120      0x800
                [!provide]                        PROVIDE (_alt_partition_fram_dt_start, ABSOLUTE (.))
 *(.fram_dt .fram_dt.*)
 .fram_dt       0x0000000000200120      0x800 obj/default/main.o
                0x0000000000200120                FramDT
                0x0000000000200920                . = ALIGN (0x4)
                [!provide]                        PROVIDE (_alt_partition_fram_dt_end, ABSOLUTE (.))

.fram_tm        0x0000000000200920      0x404
                [!provide]                        PROVIDE (_alt_partition_fram_tm_start, ABSOLUTE (.))
 *(.fram_tm .fram_tm.*)
 .fram_tm       0x0000000000200920      0x401 obj/default/main.o
                0x0000000000200920                FramST
                0x0000000000200921                FramTM
                0x0000000000200d24                . = ALIGN (0x4)
 *fill*         0x0000000000200d21        0x3 
                [!provide]                        PROVIDE (_alt_partition_fram_tm_end, ABSOLUTE (.))
  .............

データ比較

データ転送(リード/ライト)が正常に行われたかNios内とテストベンチ内で確認します。

ソースコード

C言語(Nios)

メインプログラム(main.c)

上記経路確認と割り込み処理を記述しています。
また、波形で見た時にどの部分を実行中か分かるようにport_aを使ってステップ番号を出力しています。

#define _MAIN_C_
#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    "system.h"
#include    "io.h"
#include    "sys/alt_irq.h"
#include    "altera_avalon_pio_regs.h"
#include    "nml_framif.h"

//#define DBG_PRINT(...)  printf(__VA_ARGS__)
#define DBG_PRINT(...)

// **
// **   Interrupt program
// ***************************************************************************************
int     fram_irq_step   = 0;
static  void    fram_ir(void *context,unsigned int id){
    unsigned int    status  = 0;

    status  = NML_FRAMIF_GETREG_IRS();  // Interrupt status
    NML_FRAMIF_SETREG_IRS(status);      // Interrupt clear
    fram_irq_step++;
}

// **
// **   Main program
// ***************************************************************************************
// 
// [ Dedicated memory] 
//  Split PARAMETER memory with Linker
unsigned char   FramID[  16]    __attribute__   ((section (".fram_id")));   // Device ID
unsigned char   FramSN[  16]    __attribute__   ((section (".fram_sn")));   // Serial Number
unsigned char   FramSS[ 256]    __attribute__   ((section (".fram_ss")));   // Special Sector
unsigned char   FramDT[2048]    __attribute__   ((section (".fram_dt")));   // Data Memory
unsigned char   FramTM[1024]    __attribute__   ((section (".fram_tm")));   // Temporary
unsigned char   FramST          __attribute__   ((section (".fram_tm")));   // Status

int main(void){
    unsigned int    addr    = 0;
    unsigned char   exp     = 0;
    unsigned int    err     = 0;

    // ==
    // ==   Test 
    // =========================================================================
    // ++
    // ++   Status
    // +++++++++++++++++++++++++++++++++++++++++++
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x01);  // Step No
    NML_FRAMIF_RDSR(&FramST);
    if( FramST != 0x40 )        err++;
    DBG_PRINT(" >>> Step%d : error[%d]\n",IORD_ALTERA_AVALON_PIO_DATA(PORT_A_BASE),err);

    // ++
    // ++   Waiting for master load
    // +++++++++++++++++++++++++++++++++++++++++++
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x02);  // Step No
    if( (FramID[0]==0x11) |
        (FramID[1]==0x22) |
        (FramID[2]==0x33) |
        (FramID[3]==0x44) |
        (FramID[4]==0x55) |
        (FramID[5]==0x66) |
        (FramID[6]==0x77) |
        (FramID[7]==0x88) |
        (FramID[8]==0x99) );
    else                        err++;
    DBG_PRINT(" >>> Step%d : error[%d]\n",IORD_ALTERA_AVALON_PIO_DATA(PORT_A_BASE),err);

    // ++
    // ++   Serial number confirmation
    // +++++++++++++++++++++++++++++++++++++++++++
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x03);  // Step No
    if( (FramSN[0]==0x01) |
        (FramSN[1]==0x23) |
        (FramSN[2]==0x45) |
        (FramSN[3]==0x67) |
        (FramSN[4]==0x89) |
        (FramSN[5]==0xAB) |
        (FramSN[6]==0xCD) |
        (FramSN[7]==0xEF) );
    else                        err++;
    DBG_PRINT(" >>> Step%d : error[%d]\n",IORD_ALTERA_AVALON_PIO_DATA(PORT_A_BASE),err);

    // ++
    // ++   Initial setting for FRAM I/F
    // +++++++++++++++++++++++++++++++++++++++++++
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x04);  // Step No
    NML_FRAMIF_SETUP(0,0,0);

    // ++
    // ++   Data rewriting
    // +++++++++++++++++++++++++++++++++++++++++++
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x05);  // Step No
    for(addr=0;addr<8;addr++)   FramSN[addr] = (unsigned char)(0xFF-FramSN[addr]);
    for(addr=0;addr<64;addr++)  FramSS[addr] = (unsigned char)(0x00-FramSS[addr]);
    for(addr=0;addr<128;addr++) FramDT[addr] = (unsigned char)(FramDT[addr]+0xFF);

    // ++
    // ++   Save
    // +++++++++++++++++++++++++++++++++++++++++++
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x06);  // Step No
    NML_FRAMIF_SETWP(NML_FRAMIF_WP_OFF);            // ** Protect

    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x07);  // Step No
    NML_FRAMIF_WRSN(FramSN);                        // Write Serial Number

    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x08);  // Step No
    NML_FRAMIF_SSWR( 0x000000, 64,FramSS);          // Special Sector Write
    
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x09);  // Step No
    NML_FRAMIF_WRITE(0x000000,128,FramDT);          // Write Data to Memory
    
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x0A);  // Step No
    NML_FRAMIF_SETWP(NML_FRAMIF_WP_ON);             // ** Protect

    // ++
    // ++   Load
    // +++++++++++++++++++++++++++++++++++++++++++
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x0B);  // Step No
    NML_FRAMIF_RDID(FramTM);                        // Read Device ID
    for(addr=0;addr<9;addr++){
        exp = FramID[addr]+1;
        if( exp != FramTM[addr] )   err++;
    }

    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x0C);  // Step No
    NML_FRAMIF_RDSN(FramTM);                        // Read Serial No
    for(addr=0;addr<8;addr++){
        exp = FramSN[addr] + 1;
        if( exp != FramTM[addr] )   err++;
    }

    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x0D);  // Step No
    NML_FRAMIF_SSRD( 0x000000, 64,FramTM);          // Special Sector Read
    for(addr=0;addr< 64;addr++){
        exp = FramSS[addr] + 1;
        if( exp != FramTM[addr] )   err++;
    }

    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x0E);  // Step No
    NML_FRAMIF_READ( 0x000000,128,FramTM);          // Read Data from Memory
    for(addr=0;addr<128;addr++){
        exp = FramDT[addr] + 1;
        if( exp != FramTM[addr] )   err++;
    }

    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x0F);  // Step No
    DBG_PRINT(" >>>>> FRAM Read/Write Test End : Error [%d]\n\n",err);
    NML_FRAMIF_SETWP(NML_FRAMIF_WP_OFF);            // ** Protect
    // =========================================================================

    // ==
    // ==   Interrupt Test 
    // =========================================================================
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x10);  // Step No
    NML_FRAMIF_SETREG_IRS(1);                       // Clear
    NML_FRAMIF_SETREG_IRM(0);                       // Unmask
    alt_irq_register(0,0,fram_ir);                  // Interrupt processing registration

    while(1){
        IOWR_ALTERA_AVALON_PIO_DATA(PORT_B_BASE,fram_irq_step);

        if( fram_irq_step == 0 ){
            IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x11);
            NML_FRAMIF_SETWP(NML_FRAMIF_WP_OFF);    // ** Protect
            NML_FRAMIF_WREN();                      // Enable Write
            NML_FRAMIF_SETREG_BAD(0x000000);        // Buffer Address
            NML_FRAMIF_SETREG_BDT(0x02);            // Buffer Data [Command]
            NML_FRAMIF_SETREG_BDT(0x00);            // Buffer Data [Address]
            NML_FRAMIF_SETREG_BDT(0x80);            // Buffer Data [Address]
            NML_FRAMIF_SETREG_BDT(0x00);            // Buffer Data [Address]
            for(addr=0;addr<16;addr++){             // Buffer Data [Write Data]
                NML_FRAMIF_SETREG_BDT(addr+5);
            }
            NML_FRAMIF_SETREG_ACS(1+3+16-1);        // Access
            NML_FRAMIF_SETREG_OTC(1+3+16-1);        // Output
            fram_irq_step++;
            NML_FRAMIF_SETREG_IRM(0);               // Unmask
            NML_FRAMIF_SETREG_ENB(1);               // START
        };
        if( fram_irq_step == 2 ){
            IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x12);
            NML_FRAMIF_SETWP(NML_FRAMIF_WP_ON);     // ** Protect

            NML_FRAMIF_SETREG_BAD(0x000000);        // Buffer Address
            NML_FRAMIF_SETREG_BDT(0x03);            // Buffer Data [Command]
            NML_FRAMIF_SETREG_ACS(1+3+16-1);        // Access
            NML_FRAMIF_SETREG_OTC(1+3   -1);        // Output
            fram_irq_step++;
            NML_FRAMIF_SETREG_IRM(0);               // Unmask
            NML_FRAMIF_SETREG_ENB(1);               // START
        }
        if( fram_irq_step == 4 ){
            IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0x13);
            NML_FRAMIF_SETREG_BAD(0x000004);        // Buffer Address
            for(addr=0;addr<16;addr++){             // Buffer Data [Write Data]
                exp = addr+5+3;
                if( (unsigned char)(NML_FRAMIF_GETREG_BDT()) != exp )   err++;
            }
            break;
        }
    }

    // ++++++ Final Message +++++
    IOWR_ALTERA_AVALON_PIO_DATA(PORT_A_BASE,0xFF);
    printf(" >>>>> FRAM Read/Write Test End : Error [%d]\n",err);
    NML_FRAMIF_SETWP(NML_FRAMIF_WP_OFF);
    return  0;
}
FRAM I/F用プログラム(framif.c)
#ifndef _NML_FRAMIF_C_
#define _NML_FRAMIF_C_

#include    <stdio.h>
#include    <stdlib.h>
#include    "system.h"
#include    "io.h"
#include    "altera_avalon_pio_regs.h"
#include    "nml_framif.h"

// --
// -- Initial setting
// -----------------------------------------------------------------------------
void    NML_FRAMIF_SETUP(
    unsigned int    Div     ,   // Serial clock division    [0 to 15]
    unsigned int    Pol     ,   // Serial clock polarity    [0:Low 1:High]
    unsigned int    Tak         // Import timing            [0 to 3]
){
    NML_FRAMIF_SETREG_CNT(Tak,Pol,Div);
    NML_FRAMIF_SETREG_IRM(1);
    NML_FRAMIF_SETREG_IRS(1);
}
void    NML_FRAMIF_BUFINIT(void){
    unsigned int    bad = 0;
    NML_FRAMIF_SETREG_BAD(bad);
    for(bad=0;bad<NML_FRAMIF_BUFSIZE;bad++){
        NML_FRAMIF_SETREG_BDT(0x00);
    }
}

// --
// -- FRAM Access
// -----------------------------------------------------------------------------
// *******************************************************************
// **
// **   Private Function
// **

// @@
// @@ Transfer processing (Common)
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
char    nml_framif_access(
    unsigned char   Polling ,   // End detection method [1:Register polling]
    unsigned char   Command ,   // Command
             int    Address ,   // Address         (-1 or less and no address setting)
    unsigned int    PutSize ,   // Storage size
    unsigned int    GetSize ,   // Acquisition size
    unsigned char   *Data       // Data
){

    unsigned char   puttype = 0;
    unsigned int    acs     = 0;
    unsigned int    otc     = 0;
    unsigned int    tmp     = 0;

    // ++ Confirmation of operation
    // ++   Back if running
    // +++++++++++++++++++++++++++++++++++++++++++
    if( NML_FRAMIF_GETREG_ENB() != 0 )  return  NML_FRAMIF_STA_ERR;

    // ++ Parsing arguments
    // ++   (PutSize==0) & (GetSize==0) : Write system (command only)
    // ++   (PutSize!=0) & (GetSize==0) : Write system
    // ++   (PutSize==0) & (GetSize!=0) : Read system
    // ++   Others                      : Write system (command only)
    // +++++++++++++++++++++++++++++++++++++++++++
    if(      (PutSize==0) & (GetSize==0) ){ puttype = 1; acs = 1;           otc = 1;            }
    else if( (PutSize!=0) & (GetSize==0) ){ puttype = 1; acs = 1+PutSize;   otc = 1+PutSize;    }
    else if( (PutSize==0) & (GetSize!=0) ){ puttype = 0; acs = 1+GetSize;   otc = 1;            }
    else                                  { puttype = 1; acs = 1;           otc = 1;            }

    // ++ Interrupt clear and mask
    // +++++++++++++++++++++++++++++++++++++++++++
    NML_FRAMIF_SETREG_IRM(1);   // Mask
    NML_FRAMIF_SETREG_IRS(1);   // Clear

    // ++ Setting
    // +++++++++++++++++++++++++++++++++++++++++++
    NML_FRAMIF_SETREG_BAD(0);
    NML_FRAMIF_SETREG_BDT(Command);
    if( Address >= 0 ){
        acs = acs + 3;
        otc = otc + 3;
        NML_FRAMIF_SETREG_BDT(Address>>16);
        NML_FRAMIF_SETREG_BDT(Address>> 8);
        NML_FRAMIF_SETREG_BDT(Address>> 0);
    }
    NML_FRAMIF_SETREG_ACS((acs-1));
    NML_FRAMIF_SETREG_OTC((otc-1));

    // ++ Data storage
    // +++++++++++++++++++++++++++++++++++++++++++
    if( puttype == 1 ){
        for(tmp=0;tmp<PutSize;tmp++)    NML_FRAMIF_SETREG_BDT(Data[tmp]);
    }

    // ++ Transfer start
    // +++++++++++++++++++++++++++++++++++++++++++
    NML_FRAMIF_SETREG_ENB(1);

    // ++ Transfer complete
    // +++++++++++++++++++++++++++++++++++++++++++
    if( Polling == 1 ){
        while( NML_FRAMIF_GETREG_ENB() != 0 );

        NML_FRAMIF_SETREG_IRS(1);
        if( puttype == 0 ){
            if( Address < 0 )   NML_FRAMIF_SETREG_BAD(1);
            else                NML_FRAMIF_SETREG_BAD(4);
            for(tmp=0;tmp<GetSize;tmp++)    Data[tmp] = NML_FRAMIF_GETREG_BDT();
        }
        return  NML_FRAMIF_STA_FIN;
    }

    return  NML_FRAMIF_STA_SET;
}
// @@
// @@ Write processing (Common)
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
char    nml_framif_acc_wr(
    unsigned char   Type    ,   // Write type
    unsigned int    Address ,   // Start address
    unsigned int    Length  ,   // Storage size   (Range:1 to NML_FRAMIF_BUFSIZE-4)
    unsigned char   *Data       // Data
){
    char    status  = 0;

    // ++   Write Enable ON
    // +++++++++++++++++++++++++++++++++++++++++++
    if( Type == 0 )         return  nml_framif_access(1,0x06,-1,0,0,NULL);
    if( (status=nml_framif_access(1,0x06,-1,0,0,NULL)) != NML_FRAMIF_STA_FIN ) return  status;

    // ++   Write operation
    // +++++++++++++++++++++++++++++++++++++++++++
    if(      Type == 1 )    return  nml_framif_access(1,0x01,            -1,     1,0,Data);
    else if( Type == 2 )    return  nml_framif_access(1,0xC2,            -1,     8,0,Data);
    else if( Type == 3 )    return  nml_framif_access(1,0x02,(int)(Address),Length,0,Data);
    else if( Type == 4 )    return  nml_framif_access(1,0x42,(int)(Address),Length,0,Data);
    else                    return  nml_framif_access(1,0x04,            -1,     0,0,NULL);
}
// **
// *******************************************************************

// ++
// ++   Write system    (Supports CY15B102QN commands)
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
char    NML_FRAMIF_WREN(void)                   {   return  nml_framif_acc_wr(0,0,0,NULL);  }
char    NML_FRAMIF_WRSR(unsigned char *Data)    {   return  nml_framif_acc_wr(1,0,0,Data);  }
char    NML_FRAMIF_WRSN(unsigned char *Data)    {   return  nml_framif_acc_wr(2,0,0,Data);  }
char    NML_FRAMIF_WRDI(void)                   {   return  nml_framif_acc_wr(5,0,0,NULL);  }
char    NML_FRAMIF_WRITE(
    unsigned int    Address ,   // Start address
    unsigned int    Length  ,   // Storage size   (Range:1~NML_FRAMIF_BUFSIZE-4)
    unsigned char   *Data       // Data
){
    return  nml_framif_acc_wr(3,Address,Length,Data);
}
char    NML_FRAMIF_SSWR(
    unsigned int    Address ,   // Start address
    unsigned int    Length  ,   // Storage size   (Range:1 to NML_FRAMIF_BUFSIZE-4)
    unsigned char   *Data       // Data
){
    return  nml_framif_acc_wr(4,Address,Length,Data);
}

// ++
// ++   Read system    (Supports CY15B102QN commands)
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
char    NML_FRAMIF_RDSR(unsigned char *Data)    {   return  nml_framif_access(1,0x05,-1,0,1,Data);  }
char    NML_FRAMIF_RDID(unsigned char *Data)    {   return  nml_framif_access(1,0x9F,-1,0,9,Data);  }
char    NML_FRAMIF_RDSN(unsigned char *Data)    {   return  nml_framif_access(1,0xC3,-1,0,8,Data);  }
char    NML_FRAMIF_READ(
    unsigned int    Address ,   // Start address
    unsigned int    Length  ,   // Storage size   (Range:1 to NML_FRAMIF_BUFSIZE-4)
    unsigned char   *Data       // Data
){
    return  nml_framif_access(1,0x03,(int)(Address),0,Length,Data);
}
char    NML_FRAMIF_SSRD(
    unsigned int    Address ,   // Start address
    unsigned int    Length  ,   // Storage size   (Range:1 to NML_FRAMIF_BUFSIZE-4)
    unsigned char   *Data       // Data
){
    return  nml_framif_access(1,0x4B,(int)(Address),0,Length,Data);
}

// --
// -- Write protect control
// -----------------------------------------------------------------------------
void    NML_FRAMIF_SETWP(
    unsigned char   Flag
){
    IOWR_ALTERA_AVALON_PIO_DATA(FRAM_WP_BASE, (unsigned int)(Flag));
}
unsigned char   NML_FRAMIF_GETWP(void){
    return  (unsigned char)(IORD_ALTERA_AVALON_PIO_DATA(FRAM_WP_BASE));
}

#endif  /* _NML_FRAMIF_C_   */
FRAM I/Fのヘッダファイル(framif.h)
#ifndef _NML_FRAMIF_H_
#define _NML_FRAMIF_H_

#include    "system.h"
#include    "io.h"

// --
// -- Define
// -----------------------------------------------------------------------------
#define NML_FRAMIF_BUFSIZE  (4096)  // Buffer size in FRAM I / F
#define NML_FRAMIF_STA_ERR  (-1)    // FRAM I/F is in operation
#define NML_FRAMIF_STA_FIN  ( 1)    // Processing to FRAM I/F is completed
#define NML_FRAMIF_STA_SET  ( 2)    // Finished setting process to FRAM I/F

#define NML_FRAMIF_WP_ON    (0)     // Write protect ON
#define NML_FRAMIF_WP_OFF   (1)     // Write protect OFF

// --
// -- Register for FRAM I/F
// -----------------------------------------------------------------------------
#define NML_FRAMIF_SETREG_ENB(enb)          (IOWR(FRAM_BASE,0x00, ((enb)&0x00000001)))
#define NML_FRAMIF_SETREG_CNT(tak,pol,div)  (IOWR(FRAM_BASE,0x01,(((tak)&0x00000001)<<5)|   \
                                                                 (((pol)&0x00000001)<<4)|   \
                                                                 (((div)&0x0000000F)<<0)))
#define NML_FRAMIF_SETREG_ACS(acs)          (IOWR(FRAM_BASE,0x02, ((acs)&0x001FFFFF)))
#define NML_FRAMIF_SETREG_OTC(otc)          (IOWR(FRAM_BASE,0x03, ((otc)&0x001FFFFF)))
#define NML_FRAMIF_SETREG_IRS(irs)          (IOWR(FRAM_BASE,0x04, ((irs)&0x00000001)))
#define NML_FRAMIF_SETREG_IRM(irm)          (IOWR(FRAM_BASE,0x05, ((irm)&0x00000001)))
#define NML_FRAMIF_SETREG_BAD(bad)          (IOWR(FRAM_BASE,0x06, ((bad)&0x001FFFFF)))
#define NML_FRAMIF_SETREG_BDT(bdt)          (IOWR(FRAM_BASE,0x07, ((bdt)&0x000000FF)))
#define NML_FRAMIF_GETREG_ENB(void)         (IORD(FRAM_BASE,0x00))
#define NML_FRAMIF_GETREG_CNT(void)         (IORD(FRAM_BASE,0x01))
#define NML_FRAMIF_GETREG_ACS(void)         (IORD(FRAM_BASE,0x02))
#define NML_FRAMIF_GETREG_OTC(void)         (IORD(FRAM_BASE,0x03))
#define NML_FRAMIF_GETREG_IRS(void)         (IORD(FRAM_BASE,0x04))
#define NML_FRAMIF_GETREG_IRM(void)         (IORD(FRAM_BASE,0x05))
#define NML_FRAMIF_GETREG_BAD(void)         (IORD(FRAM_BASE,0x06))
#define NML_FRAMIF_GETREG_BDT(void)         (IORD(FRAM_BASE,0x07))
#define NML_FRAMIF_GETREG_CNT_TAK(void)     ((IORD(FRAM_BASE,0x01)>>5)&0x03)
#define NML_FRAMIF_GETREG_CNT_POL(void)     ((IORD(FRAM_BASE,0x01)>>4)&0x01)
#define NML_FRAMIF_GETREG_CNT_DIV(void)     ((IORD(FRAM_BASE,0x01)>>0)&0x0F)

// --
// -- Function for FRAM I/F
// -----------------------------------------------------------------------------
#ifdef  _NML_FRAMIF_C_
        void            NML_FRAMIF_SETUP(                           // ** Initial setting
                            unsigned int    Div     ,                   // Serial clock division    [0 to 15]
                            unsigned int    Pol     ,                   // Serial clock polarity    [0:Low 1:High]
                            unsigned int    Tak                         // Import timing            [0 to 3]
        );
        void            NML_FRAMIF_BUFINIT(void);                   // ** Buffer initialization
        // ***** Write protect control
        void            NML_FRAMIF_SETWP(unsigned char);            // ** Write protect settings
        unsigned char   NML_FRAMIF_GETWP(void);                     // ** Get write protect status
        // ***** Write system(Supports CY15B102QN commands)
        char            NML_FRAMIF_WREN(void)                   ;   // ** Enable Write
        char            NML_FRAMIF_WRDI(void)                   ;   // ** Disable Write
        char            NML_FRAMIF_WRSR(unsigned char *Data)    ;   // ** Write Status Register
        char            NML_FRAMIF_WRSN(unsigned char *Data)    ;   // ** Write Serial Number
        char            NML_FRAMIF_WRITE(                           // ** Write Data to Memory
                            unsigned int    Address ,                   // Start address
                            unsigned int    Length  ,                   // Storage size   (Range:1~NML_FRAMIF_BUFSIZE-4)
                            unsigned char   *Data                       // Data
                        );
        char            NML_FRAMIF_SSWR(                            // ** Special Sector Write
                            unsigned int    Address ,                   // Start address
                            unsigned int    Length  ,                   // Storage size   (Range:1~NML_FRAMIF_BUFSIZE-4)
                            unsigned char   *Data                       // Data
                        );
        // ***** Read system(Supports CY15B102QN commands)
        char            NML_FRAMIF_RDSR(unsigned char *Data)    ;   // ** Read Status Register
        char            NML_FRAMIF_RDID(unsigned char *Data)    ;   // ** Read Device ID
        char            NML_FRAMIF_RDSN(unsigned char *Data)    ;   // ** Read Serial No
        char            NML_FRAMIF_READ(                            // ** Read Data from Memory
                            unsigned int    Address ,                   // Start address
                            unsigned int    Length  ,                   // Storage size   (Range:1~NML_FRAMIF_BUFSIZE-4)
                            unsigned char   *Data                       // Data
                        );
        char            NML_FRAMIF_SSRD(                            // ** Special Sector Read
                            unsigned int    Address ,                   // Start address
                            unsigned int    Length  ,                   // Storage size   (Range:1~NML_FRAMIF_BUFSIZE-4)
                            unsigned char   *Data                       // Data
        );
#else   // ---------------------------------------------------------------------
extern  void            NML_FRAMIF_SETUP(                           // ** Initial setting
                            unsigned int    Div     ,                   // Serial clock division    [0 to 15]
                            unsigned int    Pol     ,                   // Serial clock polarity    [0:Low 1:High]
                            unsigned int    Tak                         // Import timing            [0 to 3]
        );
extern  void            NML_FRAMIF_BUFINIT(void);                   // ** Buffer initialization
        // ***** Write protect control
extern  void            NML_FRAMIF_SETWP(unsigned char);            // ** Write protect settings
extern  unsigned char   NML_FRAMIF_GETWP(void);                     // ** Get write protect status
        // ***** Write system(Supports CY15B102QN commands)
extern  char            NML_FRAMIF_WREN(void)                   ;   // ** Enable Write
extern  char            NML_FRAMIF_WRDI(void)                   ;   // ** Disable Write
extern  char            NML_FRAMIF_WRSR(unsigned char *Data)    ;   // ** Write Status Register
extern  char            NML_FRAMIF_WRSN(unsigned char *Data)    ;   // ** Write Serial Number
extern  char            NML_FRAMIF_WRITE(                           // ** Write Data to Memory
                            unsigned int    Address ,                   // Start address
                            unsigned int    Length  ,                   // Storage size   (Range:1~NML_FRAMIF_BUFSIZE-4)
                            unsigned char   *Data                       // Data
                        );
extern  char            NML_FRAMIF_SSWR(                            // ** Special Sector Write
                            unsigned int    Address ,                   // Start address
                            unsigned int    Length  ,                   // Storage size   (Range:1~NML_FRAMIF_BUFSIZE-4)
                            unsigned char   *Data                       // Data
                        );
        // ***** Read system(Supports CY15B102QN commands)
extern  char            NML_FRAMIF_RDSR(unsigned char *Data)    ;   // ** Read Status Register
extern  char            NML_FRAMIF_RDID(unsigned char *Data)    ;   // ** Read Device ID
extern  char            NML_FRAMIF_RDSN(unsigned char *Data)    ;   // ** Read Serial No
extern  char            NML_FRAMIF_READ(                            // ** Read Data from Memory
                            unsigned int    Address ,                   // Start address
                            unsigned int    Length  ,                   // Storage size   (Range:1~NML_FRAMIF_BUFSIZE-4)
                            unsigned char   *Data                       // Data
                        );
extern  char            NML_FRAMIF_SSRD(                            // ** Special Sector Read
                            unsigned int    Address ,                   // Start address
                            unsigned int    Length  ,                   // Storage size   (Range:1~NML_FRAMIF_BUFSIZE-4)
                            unsigned char   *Data                       // Data
        );

#endif

#endif  /* _NML_FRAMIF_H_   */

verilog言語(テストベンチ)

テストベンチでは、リセット解除後にFRAM I/Fブロックをマスタモードで動作させるための記述(forceで入力信号PRM_???を変更して動作させています)と、FRAM内のメモリ配列を確認したり書き換えたりしています。

`timescale  1ns/1ps

module  TB_TOP;
integer     PERIOD      = 0;
reg         RESET_N     = 0;
reg         CLOCK       = 0;
reg         SW_SLAVE    = 1;
reg         SW_GO       = 0;
wire        FRAM_CS_N   ;       // @@ [SYS_CLK↑同期] FRAM SPI チップセレクト
wire        FRAM_SCLK   ;       // @@ [SYS_CLK↑同期] FRAM SPI シリアルクロック
wire        FRAM_MOSI   ;       // @@ [SYS_CLK↑同期] FRAM SPI シリアル出力
wire        FRAM_MISO   ;       // @@ [SYS_CLK↑同期] FRAM SPI シリアル入力

// ++ タイミング設定
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Clock波形
real        tcCLOCK = 40.000;
real        tpCLOCK =  5.000;
real        tnCLOCK = 25.000;

// FRAM モデル間遅延
defparam    UnDlyFRAM_CS_N.NsStep= 0 ,UnDlyFRAM_CS_N.PsStep=  0;
defparam    UnDlyFRAM_SCLK.NsStep= 0 ,UnDlyFRAM_SCLK.PsStep=  0;
defparam    UnDlyFRAM_MOSI.NsStep= 0 ,UnDlyFRAM_MOSI.PsStep=  0;
defparam    UnDlyFRAM_MISO.NsStep= 0 ,UnDlyFRAM_MISO.PsStep=  0;

// --
// -- Clock生成
// -------------------------------------------------------------------
    initial begin
        forever begin
            fork
                #(tpCLOCK)    CLOCK     = 1;
                #(tnCLOCK)    CLOCK     = 0;
                #(tcCLOCK)    PERIOD    = PERIOD+1;
            join
        end
    end

// --
// -- Reset
// -------------------------------------------------------------------
    reg  [ 7:0] tmpID[0:     8];
    reg  [ 7:0] tmpSN[0:     7];
    reg  [ 7:0] tmpSS[0:   255];
    reg  [ 7:0] tmpDT[0:262143];
    integer     error   = 0;
    reg  [ 7:0] exp;
    initial begin : GenReset
        integer     a;

        #0                      RESET_N = 0;
        repeat(10)  @(PERIOD);  RESET_N = 1;
        FRAM.Device_ID[0] = 'h11;
        FRAM.Device_ID[1] = 'h22;
        FRAM.Device_ID[2] = 'h33;
        FRAM.Device_ID[3] = 'h44;
        FRAM.Device_ID[4] = 'h55;
        FRAM.Device_ID[5] = 'h66;
        FRAM.Device_ID[6] = 'h77;
        FRAM.Device_ID[7] = 'h88;
        FRAM.Device_ID[8] = 'h99;
        FRAM.Serial_No[0] = 'h01;
        FRAM.Serial_No[1] = 'h23;
        FRAM.Serial_No[2] = 'h45;
        FRAM.Serial_No[3] = 'h67;
        FRAM.Serial_No[4] = 'h89;
        FRAM.Serial_No[5] = 'hAB;
        FRAM.Serial_No[6] = 'hCD;
        FRAM.Serial_No[7] = 'hEF;
        for(a=0;a<256;a=a+1)    FRAM.Smem[a] = $random;
        for(a=0;a<262144;a=a+1) FRAM.mem[a] = $random;
        /***** Copy *****/
        for(a=0;a<9;a=a+1)      tmpID[a] = FRAM.Device_ID[a];
        for(a=0;a<8;a=a+1)      tmpSN[a] = FRAM.Serial_No[a];
        for(a=0;a<256;a=a+1)    tmpSS[a] = FRAM.Smem[a];
        for(a=0;a<262144;a=a+1) tmpDT[a] = FRAM.mem[a];

        wait( TOP.FRAM_WP_N === 1 ) $display(" >>> FRAM Protect OFF");
        wait( TOP.FRAM_WP_N === 0 ) $display(" >>> FRAM Protect ON");

        for(a=0;a<9;a=a+1) begin
            if( FRAM.Device_ID[a] !== tmpID[a] )    error = error + 1;
        end
        $display(" >>> Device ID      : Error = %d",error);

        for(a=0;a<8;a=a+1) begin
            exp = 'hFF - tmpSN[a];
            if( exp !== FRAM.Serial_No[a] ) error = error + 1;
        end
        $display(" >>> Serial No      : Error = %d",error);

        for(a=0;a<64;a=a+1) begin
            exp = 'h00 - tmpSS[a];
            if( exp !== FRAM.Smem[a] ) error = error + 1;
        end
        $display(" >>> Special Sector : Error = %d",error);

        for(a=0;a<128;a=a+1) begin
            exp = 'hFF + tmpDT[a];
            if( exp !== FRAM.mem[a] ) error = error + 1;
        end
        $display(" >>> Memory Sector  : Error = %d",error);

        for(a=0;a<9;a=a+1)      FRAM.Device_ID[a]   = FRAM.Device_ID[a] + 1;
        for(a=0;a<8;a=a+1)      FRAM.Serial_No[a]   = FRAM.Serial_No[a] + 1;
        for(a=0;a<256;a=a+1)    FRAM.Smem[a]        = FRAM.Smem[a]      + 1;
        for(a=0;a<128;a=a+1)    FRAM.mem[a]         = FRAM.mem[a]       + 1;

        wait( TOP.FRAM_WP_N === 1 ) $display(" >>> FRAM Protect OFF");
        wait( TOP.FRAM_WP_N === 0 ) $display(" >>> FRAM Protect ON");
        for(a='h8000;a<'h8010;a=a+1) FRAM.mem[a] = FRAM.mem[a]+3;

        wait( TOP.FRAM_WP_N === 1 );
        $display(" >>>>> FRAM Save Data Error : %d",error);
    end

// --
// -- Mater Mode 起動 Force操作
// -------------------------------------------------------------------
    parameter   LOAD_STA_ID = 'h20_0000;
    parameter   LOAD_STA_SN = 'h20_0010;
    parameter   LOAD_STA_SS = 'h20_0020;
    parameter   LOAD_STA_DT = 'h20_0120;
    parameter   LOAD_STA_TM = 'h20_0920;
    initial begin : MasterBoot
        #0;
        wait( TOP.cpu_rst_n === 1'b1 ); $display(" >>> %m : Reset Off");
        repeat(10)  @(posedge TOP.cpu_clk);
        force   TOP.UnFRAMIF.MST_SLV    = 0;    // Master Mode
        force   TOP.UnFRAMIF.PRM_MSK    = 1;    // Mask
        force   TOP.UnFRAMIF.PRM_CLR    = 1;    // Clear
        force   TOP.UnFRAMIF.PRM_DIV    = 0;
        force   TOP.UnFRAMIF.PRM_POL    = 0;
        force   TOP.UnFRAMIF.PRM_TAK    = 0;

        // ++ シリアルNo 取得
        $display(" >>> %m : Read Serial No");   #1;
        force   TOP.UnFRAMIF.PRM_CMD    = 'hC3;
        force   TOP.UnFRAMIF.PRM_ADD    = 0;
        force   TOP.UnFRAMIF.PRM_ACS    = 1+8 -1;
        force   TOP.UnFRAMIF.PRM_OTC    = 1   -1;
        force   TOP.UnFRAMIF.PRM_STA    = LOAD_STA_SN;
        repeat(10)  @(posedge TOP.cpu_clk);     #1;
        $display(" >>> %m :   CMD = %h",TOP.UnFRAMIF.PRM_CMD);
        $display(" >>> %m :   ADD = %h",TOP.UnFRAMIF.PRM_ADD);
        $display(" >>> %m :   ACS = %d",TOP.UnFRAMIF.PRM_ACS);
        $display(" >>> %m :   OTC = %d",TOP.UnFRAMIF.PRM_OTC);
        $display(" >>> %m :   STA = %h",TOP.UnFRAMIF.PRM_STA);
        $display(" >>> %m :   START");
        force   TOP.UnFRAMIF.PRM_ENB    = 1;
        repeat( 5)  @(posedge TOP.cpu_clk);     #1;
        wait( TOP.UnFRAMIF.MON_ENB === 1'b1 );  #1;
        wait( TOP.UnFRAMIF.MON_ENB === 1'b0 );  #1;
        $display(" >>> %m :   FINISH");
        repeat(20)  @(posedge TOP.cpu_clk);     #1;
        force   TOP.UnFRAMIF.PRM_ENB    = 0;
        repeat(10)  @(posedge TOP.cpu_clk);     #1;

        // ++ 特殊セクタ 取得
        $display(" >>> %m : Special Sector Read");   #1;
        force   TOP.UnFRAMIF.PRM_CMD    = 'h4B;
        force   TOP.UnFRAMIF.PRM_ADD    = 0;
        force   TOP.UnFRAMIF.PRM_ACS    =  64+4 -1;
        force   TOP.UnFRAMIF.PRM_OTC    =     4 -1;
        force   TOP.UnFRAMIF.PRM_STA    = LOAD_STA_SS;
        repeat(10)  @(posedge TOP.cpu_clk);     #1;
        $display(" >>> %m :   CMD = %h",TOP.UnFRAMIF.PRM_CMD);
        $display(" >>> %m :   ADD = %h",TOP.UnFRAMIF.PRM_ADD);
        $display(" >>> %m :   ACS = %d",TOP.UnFRAMIF.PRM_ACS);
        $display(" >>> %m :   OTC = %d",TOP.UnFRAMIF.PRM_OTC);
        $display(" >>> %m :   STA = %h",TOP.UnFRAMIF.PRM_STA);
        $display(" >>> %m :   START");
        force   TOP.UnFRAMIF.PRM_ENB    = 1;
        repeat( 5)  @(posedge TOP.cpu_clk);     #1;
        wait( TOP.UnFRAMIF.MON_ENB === 1'b1 );  #1;
        wait( TOP.UnFRAMIF.MON_ENB === 1'b0 );  #1;
        $display(" >>> %m :   FINISH");
        repeat(20)  @(posedge TOP.cpu_clk);     #1;
        force   TOP.UnFRAMIF.PRM_ENB    = 0;
        repeat(10)  @(posedge TOP.cpu_clk);     #1;

        // ++ メモリデータ 取得
        $display(" >>> %m : Read Data from Memory");    #1;
        force   TOP.UnFRAMIF.PRM_CMD    = 'h03;
        force   TOP.UnFRAMIF.PRM_ADD    = 0;
        force   TOP.UnFRAMIF.PRM_ACS    = 128+4 -1;
        force   TOP.UnFRAMIF.PRM_OTC    =     4 -1;
        force   TOP.UnFRAMIF.PRM_STA    = LOAD_STA_DT;
        repeat(10)  @(posedge TOP.cpu_clk);     #1;
        $display(" >>> %m :   CMD = %h",TOP.UnFRAMIF.PRM_CMD);
        $display(" >>> %m :   ADD = %h",TOP.UnFRAMIF.PRM_ADD);
        $display(" >>> %m :   ACS = %d",TOP.UnFRAMIF.PRM_ACS);
        $display(" >>> %m :   OTC = %d",TOP.UnFRAMIF.PRM_OTC);
        $display(" >>> %m :   STA = %h",TOP.UnFRAMIF.PRM_STA);
        $display(" >>> %m :   START");
        force   TOP.UnFRAMIF.PRM_ENB    = 1;
        repeat( 5)  @(posedge TOP.cpu_clk);     #1;
        wait( TOP.UnFRAMIF.MON_ENB === 1'b1 );  #1;
        wait( TOP.UnFRAMIF.MON_ENB === 1'b0 );  #1;
        $display(" >>> %m :   FINISH");
        repeat(20)  @(posedge TOP.cpu_clk);     #1;
        force   TOP.UnFRAMIF.PRM_ENB    = 0;
        repeat(10)  @(posedge TOP.cpu_clk);     #1;

        // ++ デバイスID 取得
        $display(" >>> %m : Read Device ID");    #1;
        force   TOP.UnFRAMIF.PRM_CMD    = 'h9F;
        force   TOP.UnFRAMIF.PRM_ADD    = 0;
        force   TOP.UnFRAMIF.PRM_ACS    =   9+1 -1;
        force   TOP.UnFRAMIF.PRM_OTC    =     1 -1;
        force   TOP.UnFRAMIF.PRM_STA    = LOAD_STA_ID;
        repeat(10)  @(posedge TOP.cpu_clk);     #1;
        $display(" >>> %m :   CMD = %h",TOP.UnFRAMIF.PRM_CMD);
        $display(" >>> %m :   ADD = %h",TOP.UnFRAMIF.PRM_ADD);
        $display(" >>> %m :   ACS = %d",TOP.UnFRAMIF.PRM_ACS);
        $display(" >>> %m :   OTC = %d",TOP.UnFRAMIF.PRM_OTC);
        $display(" >>> %m :   STA = %h",TOP.UnFRAMIF.PRM_STA);
        $display(" >>> %m :   START");
        force   TOP.UnFRAMIF.PRM_ENB    = 1;
        repeat( 5)  @(posedge TOP.cpu_clk);     #1;
        wait( TOP.UnFRAMIF.MON_ENB === 1'b1 );  #1;
        wait( TOP.UnFRAMIF.MON_ENB === 1'b0 );  #1;
        $display(" >>> %m :   FINISH");
        repeat(20)  @(posedge TOP.cpu_clk);     #1;
        force   TOP.UnFRAMIF.PRM_ENB    = 0;
        repeat(10)  @(posedge TOP.cpu_clk);     #1;

        // =======================================
        $display(" >>> %m : Master Mode End");    #1;
        release TOP.UnFRAMIF.MST_SLV;
        release TOP.UnFRAMIF.PRM_ENB;
        release TOP.UnFRAMIF.PRM_DIV;
        release TOP.UnFRAMIF.PRM_POL;
        release TOP.UnFRAMIF.PRM_TAK;
        release TOP.UnFRAMIF.PRM_ACS;
        release TOP.UnFRAMIF.PRM_OTC;
        release TOP.UnFRAMIF.PRM_MSK;
        release TOP.UnFRAMIF.PRM_CLR;
        release TOP.UnFRAMIF.PRM_STA;
        release TOP.UnFRAMIF.PRM_CMD;
        release TOP.UnFRAMIF.PRM_ADD;
    end

// --
// --   ターゲットのインスタンス
// -------------------------------------------------------------------
    wire        dlyFRAM_CS_N;   DlyBuf  UnDlyFRAM_CS_N(.A(FRAM_CS_N),.Y(dlyFRAM_CS_N) );
    wire        dlyFRAM_SCLK;   DlyBuf  UnDlyFRAM_SCLK(.A(FRAM_SCLK),.Y(dlyFRAM_SCLK) );
    wire        dlyFRAM_MOSI;   DlyBuf  UnDlyFRAM_MOSI(.A(FRAM_MOSI),.Y(dlyFRAM_MOSI) );
    wire        dlyFRAM_MISO;   DlyBuf  UnDlyFRAM_MISO(.A(FRAM_MISO),.Y(dlyFRAM_MISO) );

    TOP TOP(
        .RESET_N    (RESET_N        ), // input   wire        RESET_N     ,   // @@ リセット
        .CLOCK      (CLOCK          ), // input   wire        CLOCK       ,   // @@ クロック
        .FRAM_WP_N  (               ), // output  wire        FRAM_WP_N   ,   // @@ FRAM ライトプロテクト[0:プロテクト]
        .FRAM_CS_N  (   FRAM_CS_N   ), // output  wire        FRAM_CS_N   ,   // @@ FRAM SPI チップセレクト
        .FRAM_SCLK  (   FRAM_SCLK   ), // output  wire        FRAM_SCLK   ,   // @@ FRAM SPI シリアルクロック
        .FRAM_MOSI  (   FRAM_MOSI   ), // output  wire        FRAM_MOSI   ,   // @@ FRAM SPI シリアル出力
        .FRAM_MISO  (dlyFRAM_MISO   ), // input   wire        FRAM_MISO   ,   // @@ FRAM SPI シリアル入力
        .SW_SLAVE   (SW_SLAVE       ), // input   wire        SW_SLAVE    ,   // @@ Master/Slave切替 [0:Master]
        .SW_GO      (SW_GO          ), // input   wire        SW_GO       ,   // @@ 処理イネーブル
        .LED_LOCK   (               )  // output  wire        LED_LOCK        // @@ LED Lock
    );

    reg         FRAM_VDD = 0;
    initial begin   #1; FRAM_VDD=1; end
    FRAM_SPI FRAM(
        .CSB    (dlyFRAM_CS_N   ),
        .SCK    (dlyFRAM_SCLK   ),
        .SI     (dlyFRAM_MOSI   ),
        .SO     (   FRAM_MISO   ),
        .WPB    (1'b1           ),
        .VDD    (   FRAM_VDD    )
    );
endmodule

module DlyBuf
#(
    parameter   NsStep = 1,
    parameter   PsStep = 1
)
(
    input   wire    A ,
    output  wire    Y
);

    wire    [NsStep:0] SigNs;
    wire    [PsStep:0] SigPs;

    assign  SigNs[0] = A;
    generate
        genvar  ins;

        if( NsStep != 0 ) begin
            for(ins=1;ins<=NsStep;ins=ins+1) begin
                DlyBufCoreNs UnDlyNs(.A(SigNs[ins-1]),.Y(SigNs[ins]) );
            end
        end
    endgenerate

    assign  SigPs[0] = SigNs[NsStep];
    generate
        genvar  ips;

        if( PsStep != 0 ) begin
            for(ips=1;ips<=PsStep;ips=ips+1) begin
                DlyBufCorePs UnDlyPs(.A(SigPs[ips-1]),.Y(SigPs[ips]) );
            end
        end
    endgenerate

    assign  Y = SigPs[PsStep];

endmodule

module DlyBufCoreNs(input wire A, output wire Y);   assign #(1.000) Y = A;  endmodule
module DlyBufCorePs(input wire A, output wire Y);   assign #(0.001) Y = A;  endmodule

最後に

上記で説明した内容は設計したブロック間が正しいか確認するためのNiosプログラムとなります。
経路を確認した後、実際の用途に合わせて、ソフトウェアを作り込むことになります。