Overtone NSL Support

NSLサポートページ



15ワード x 8ビット幅 同期式 FIFO


機能

15word x 8bit FIFO module

信号機能

DB_i[8] = 書き込みデータ入力
DB_o[8] = 読み出しデータ出力

WEN_i = 書き込みイネーブル入力
REN_i = 読み出しイネーブル入力

動作解説

本FIFO回路は内蔵されたメモリアレイワード数-1の数だけデータを取り込むことができます
よって,本機能は15ワードのFIFO機能です.

WEN_iをHレベルにすると,DB_i入力端子の値を内部FIFOメモリに取り込みます.
REN_iをHレベルにすると,内部FIFOメモリの値をDB_o出力端子に出力します.

動作開始直後の状態は下記のとおりです.
・WEN_iがLの状態では読出し可能なデータが存在しないため,EMPTYフラグがHレベルになっています.
・REN_iがLの状態でWEN_iをHレベルにすると,最大15ワード分の値を取り込み,FULLフラグをHレベルにします.
・FIFOがEMPTYの状態で書込みと読出しを同時に行った場合には動作保証を行いません.

記述特徴

メモリを推論させるためにはmemを使います。

mem メモリ名 [n][m] = { 初期値,初期値, … } ;

上記の例だと、nワードでmビットのメモリ名という名前のメモリが作られます。
{}で初期値を与えることができます。初期値がメモリの数より少ない場合、足りない分は0で初期化されます。

NSL記述例

/* ************************************************************ */
declare RAM_FIFO {
    input       DB_i[8] ;       // Write Data (in)
    output      DB_o[8] ;       // Read Data (out)

    input       WEN_i ;         // Write enable (in)
    input       REN_i ;         // Read enable (in)

    output      FULL ;          // FIFO full flag.
    output      EMPTY ;         // FIFO empty flag.
}

/* ************************************************************ */
// Declare module
module RAM_FIFO {

/* ************************************************************ */
// Internal operation signals
    mem     mem_array [16][8] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } ;
                                // Declare memory array with INIT.
    reg     reg_DB_o[8] ;

    reg     wr_ptr[4] = 0 ;     // Write pointer ( current )
    reg     rd_ptr[4] = 0 ;     // Read  pointer ( current )
    wire    next_wr_ptr[4] ;
    wire    next_rd_ptr[4] ;

    wire    internal_FULL ;
    wire    internal_EMPTY ;

    func_self   Check_FULL_flag() ;
    func_self   Check_EMPTY_flag() ;

/* ************************************************************ */
// Equation
{
// ************************ //
// FIFO write side.
    if ( WEN_i & ~internal_FULL ) {
        mem_array[wr_ptr] := DB_i ; // Store a current write data to memory array.
        wr_ptr := next_wr_ptr ;     // Update NEW write pointer
    }

    next_wr_ptr = wr_ptr + 4'b1 ;

    Check_FULL_flag() ;

// ************************ //
// FIFO read side.
    if ( REN_i & ~internal_EMPTY ) {
        reg_DB_o := mem_array[rd_ptr] ;
                            // Read-out memory array to internal output regs.
        rd_ptr := next_rd_ptr ;     // Update NEW write pointer
    }

    DB_o = reg_DB_o ;

    next_rd_ptr = rd_ptr + 4'b1 ;

    Check_EMPTY_flag() ;    

    FULL    = internal_FULL ;
    EMPTY   = internal_EMPTY ;

}

func Check_FULL_flag {
    any {
        next_wr_ptr == rd_ptr   : internal_FULL = 1'b1 ;    // Set FULL flag.
        else                    : internal_FULL = 1'b0 ;
    }
}

func Check_EMPTY_flag {
    any {
        rd_ptr == wr_ptr        : internal_EMPTY = 1'b1 ;   // Set FULL flag.
        else                    : internal_EMPTY = 1'b0 ;
    }
}

/* ************************************************************ */
}

Verilog変換例

/*
 Produced by NSL Core, IP ARCH, Inc. Fri Jun 04 17:54:48 2010

 Licensed to :EVALUATION USER:
*/

module RAM_FIFO ( p_reset , m_clock , DB_i , DB_o , WEN_i , REN_i , FULL , EMPTY );
  input p_reset, m_clock;
  input [7:0] DB_i;
  output [7:0] DB_o;
  input WEN_i;
  input REN_i;
  output FULL;
  output EMPTY;
  reg [7:0] mem_array [0:15];
  reg [7:0] reg_DB_o;
  reg [3:0] wr_ptr;
  reg [3:0] rd_ptr;
  wire [3:0] next_wr_ptr;
  wire [3:0] next_rd_ptr;
  wire internal_FULL;
  wire internal_EMPTY;
  wire Check_FULL_flag;
  wire Check_EMPTY_flag;
  wire _net_0;
  wire _net_1;
  wire _net_2;
  wire _net_3;

   assign  next_wr_ptr = (wr_ptr)+(4'b0001);
   assign  next_rd_ptr = (rd_ptr)+(4'b0001);

//synthesis translate_off
always @(posedge m_clock or posedge p_reset)
  begin
if ((Check_FULL_flag&(~_net_2))&Check_FULL_flag&_net_2)
 begin $display("Warning: assign collision(RAM_FIFO:internal_FULL) at %d",$time);
if (Check_FULL_flag&(~_net_2)) $display("assert (Check_FULL_flag&(~_net_2)) at 71\n");
if (Check_FULL_flag&_net_2) $display("assert (Check_FULL_flag&_net_2) at 70\n");

  end
  end
//synthesis translate_on
   assign  internal_FULL =
//synthesis translate_off
((Check_FULL_flag&(~_net_2))&Check_FULL_flag&_net_2)? 1'bx :((Check_FULL_flag&(~_net_2))|(Check_FULL_flag&_net_2))?
//synthesis translate_on
((Check_FULL_flag&(~_net_2))?1'b0:1'b0)|
    ((Check_FULL_flag&_net_2)?1'b1:1'b0)
//synthesis translate_off
:1'bx
//synthesis translate_on
;

//synthesis translate_off
always @(posedge m_clock or posedge p_reset)
  begin
if ((Check_EMPTY_flag&(~_net_3))&Check_EMPTY_flag&_net_3)
 begin $display("Warning: assign collision(RAM_FIFO:internal_EMPTY) at %d",$time);
if (Check_EMPTY_flag&(~_net_3)) $display("assert (Check_EMPTY_flag&(~_net_3)) at 78\n");
if (Check_EMPTY_flag&_net_3) $display("assert (Check_EMPTY_flag&_net_3) at 77\n");

  end
  end
//synthesis translate_on
   assign  internal_EMPTY =
//synthesis translate_off
((Check_EMPTY_flag&(~_net_3))&Check_EMPTY_flag&_net_3)? 1'bx :((Check_EMPTY_flag&(~_net_3))|(Check_EMPTY_flag&_net_3))?
//synthesis translate_on
((Check_EMPTY_flag&(~_net_3))?1'b0:1'b0)|
    ((Check_EMPTY_flag&_net_3)?1'b1:1'b0)
//synthesis translate_off
:1'bx
//synthesis translate_on
;
   assign  Check_FULL_flag = 1'b1;
   assign  Check_EMPTY_flag = 1'b1;
   assign  _net_0 = WEN_i&(~internal_FULL);
   assign  _net_1 = REN_i&(~internal_EMPTY);
   assign  _net_2 = (next_wr_ptr)==(rd_ptr);
   assign  _net_3 = (rd_ptr)==(wr_ptr);
   assign  DB_o = reg_DB_o;
   assign  FULL = internal_FULL;
   assign  EMPTY = internal_EMPTY;
initial begin
    mem_array[0] <= 8'b00000000;
    mem_array[1] <= 8'b00000000;
    mem_array[2] <= 8'b00000000;
    mem_array[3] <= 8'b00000000;
    mem_array[4] <= 8'b00000000;
    mem_array[5] <= 8'b00000000;
    mem_array[6] <= 8'b00000000;
    mem_array[7] <= 8'b00000000;
    mem_array[8] <= 8'b00000000;
    mem_array[9] <= 8'b00000000;
    mem_array[10] <= 8'b00000000;
    mem_array[11] <= 8'b00000000;
    mem_array[12] <= 8'b00000000;
    mem_array[13] <= 8'b00000000;
    mem_array[14] <= 8'b00000000;
    mem_array[15] <= 8'b00000000;
end
always @(posedge m_clock)
  begin
   if (_net_0 )
     mem_array[wr_ptr] <= DB_i;
end
always @(posedge m_clock)
  begin
if (_net_1)
      reg_DB_o <= mem_array[rd_ptr];
end
always @(posedge m_clock or posedge p_reset)
  begin
if (p_reset)
     wr_ptr <= 4'b0000;
else if (_net_0)
      wr_ptr <= next_wr_ptr;
end
always @(posedge m_clock or posedge p_reset)
  begin
if (p_reset)
     rd_ptr <= 4'b0000;
else if (_net_1)
      rd_ptr <= next_rd_ptr;
end
endmodule
/*
 Produced by NSL Core, IP ARCH, Inc. Fri Jun 04 17:54:49 2010

 Licensed to
*/
PAGE TOP