機能
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
*/