//
|
//
|
// Module SwitchSyncFIFO
|
// Module SwitchSyncFIFO
|
//
|
//
|
// the differences between this FIFO and the general one are listed below
|
// the differences between this FIFO and the general one are listed below
|
// 1. because there is no any write and read acknowledgements, the user should take advantage of the status flags to generate the write and read requests.
|
// 1. because there is no any write and read acknowledgements, the user should take advantage of the status flags to generate the write and read requests.
|
// 2. after the full flag has been asserted, the word can not be written into the FIFO even if the reacd request is being asserted at the same cycle.
|
// 2. after the full flag has been asserted, the word can not be written into the FIFO even if the reacd request is being asserted at the same cycle.
|
//
|
//
|
// Created:
|
// Created:
|
// by - Xinchun Liu
|
// by - Xinchun Liu
|
// at - 2006-09-25
|
// at - 2006-09-25
|
// History:
|
// History:
|
// 2007-1-31 9:50 change iReset to nReset Revised By Wang Dawei wangdawei@ncic.ac.cn
|
// 2007-1-31 9:50 change iReset to nReset Revised By Wang Dawei wangdawei@ncic.ac.cn
|
//
|
//
|
`resetall
|
`resetall
|
`timescale 1ns/10ps
|
`timescale 1ns/10ps
|
|
|
module SwitchSyncFIFO (
|
module SwitchSyncFIFO (
|
nReset,
|
nReset,
|
iClk,
|
iClk,
|
iWEn,
|
iWEn,
|
ivDataIn,
|
ivDataIn,
|
iREn,
|
iREn,
|
ovDataOut,
|
ovDataOut,
|
qEmpty,
|
qEmpty,
|
qFull,
|
qFull,
|
qvCount
|
qvCount
|
);
|
);
|
|
|
// Default address and data width
|
// Default address and data width
|
parameter pDepthWidth = 5 ;
|
parameter pDepthWidth = 5 ;
|
parameter pWordWidth = 16 ;
|
parameter pWordWidth = 16 ;
|
|
|
input nReset ;
|
input nReset ;
|
input iClk ;
|
input iClk ;
|
input iWEn ;
|
input iWEn ;
|
input [pWordWidth-1:0] ivDataIn ;
|
input [pWordWidth-1:0] ivDataIn ;
|
input iREn ;
|
input iREn ;
|
output [pWordWidth-1:0] ovDataOut ;
|
output [pWordWidth-1:0] ovDataOut ;
|
output qEmpty ;
|
output qEmpty ;
|
output qFull ;
|
output qFull ;
|
output [pDepthWidth:0] qvCount ;
|
output [pDepthWidth:0] qvCount ;
|
|
|
wire nReset ;
|
wire nReset ;
|
wire iClk ;
|
wire iClk ;
|
wire iWEn ;
|
wire iWEn ;
|
wire [pWordWidth-1:0] ivDataIn ;
|
wire [pWordWidth-1:0] ivDataIn ;
|
wire iREn ;
|
wire iREn ;
|
wire [pWordWidth-1:0] ovDataOut_i ;
|
wire [pWordWidth-1:0] ovDataOut_i ;
|
wire qEmpty ;
|
wire qEmpty ;
|
wire qFull ;
|
wire qFull ;
|
wire [pDepthWidth:0] qvCount ;
|
wire [pDepthWidth:0] qvCount ;
|
|
|
wire MemWEn;
|
wire MemWEn;
|
wire MemREn;
|
wire MemREn;
|
wire [pDepthWidth-1:0] vWriteAddr ;
|
wire [pDepthWidth-1:0] vWriteAddr ;
|
wire [pDepthWidth-1:0] vReadAddr ;
|
wire [pDepthWidth-1:0] vReadAddr ;
|
|
|
DualPortRAM #( pDepthWidth, pWordWidth ) Fifo_Storage // Generic synchronous two-port RAM interface
|
DualPortRAM #( pDepthWidth, pWordWidth ) Fifo_Storage // Generic synchronous two-port RAM interface
|
(
|
(
|
.clock ( iClk ) ,
|
.clock ( iClk ) ,
|
.MemWEn ( MemWEn ) ,
|
.MemWEn ( MemWEn ) ,
|
.qvWAddr ( vWriteAddr ) ,
|
.qvWAddr ( vWriteAddr ) ,
|
.vDataIn ( ivDataIn ) ,
|
.vDataIn ( ivDataIn ) ,
|
.qvRAddr ( vReadAddr ) ,
|
.qvRAddr ( vReadAddr ) ,
|
.vDataOut ( ovDataOut_i )
|
.vDataOut ( ovDataOut_i )
|
);
|
);
|
|
|
|
|
reg [pWordWidth-1:0] ovDataOut ;
|
reg [pWordWidth-1:0] ovDataOut ;
|
|
|
always @ ( posedge iClk )
|
always @ ( posedge iClk )
|
if ( MemREn )
|
if ( MemREn )
|
ovDataOut <= ovDataOut_i ;
|
ovDataOut <= ovDataOut_i ;
|
else
|
else
|
ovDataOut <= 0;
|
ovDataOut <= 0;
|
|
|
FifoControl #( pDepthWidth ) Fifo_Ctrl
|
FifoControl #( pDepthWidth ) Fifo_Ctrl
|
(
|
(
|
.Reset ( nReset ) ,
|
.Reset ( nReset ) ,
|
.clock ( iClk ) ,
|
.clock ( iClk ) ,
|
.iWEn ( iWEn ) ,
|
.iWEn ( iWEn ) ,
|
.MemWEn ( MemWEn ) ,
|
.MemWEn ( MemWEn ) ,
|
.MemREn (MemREn),
|
.MemREn (MemREn),
|
.qvWAddr ( vWriteAddr ) ,
|
.qvWAddr ( vWriteAddr ) ,
|
.iREn ( iREn ) ,
|
.iREn ( iREn ) ,
|
.qvRAddr ( vReadAddr ) ,
|
.qvRAddr ( vReadAddr ) ,
|
.qEmpty ( qEmpty ) ,
|
.qEmpty ( qEmpty ) ,
|
.qFull ( qFull ) ,
|
.qFull ( qFull ) ,
|
.qvCount ( qvCount )
|
.qvCount ( qvCount )
|
) ;
|
) ;
|
|
|
endmodule
|
endmodule
|
|
|
module FifoControl(
|
module FifoControl(
|
Reset ,
|
Reset ,
|
clock ,
|
clock ,
|
iWEn ,
|
iWEn ,
|
MemWEn ,
|
MemWEn ,
|
MemREn,
|
MemREn,
|
qvWAddr ,
|
qvWAddr ,
|
iREn ,
|
iREn ,
|
qvRAddr ,
|
qvRAddr ,
|
qEmpty ,
|
qEmpty ,
|
qFull ,
|
qFull ,
|
qvCount
|
qvCount
|
) ;
|
) ;
|
|
|
parameter pDepthWidth = 5;
|
parameter pDepthWidth = 5;
|
|
|
input Reset ;
|
input Reset ;
|
input clock ;
|
input clock ;
|
input iWEn ;
|
input iWEn ;
|
output MemWEn ;
|
output MemWEn ;
|
output MemREn ;
|
output MemREn ;
|
output [pDepthWidth-1:0] qvWAddr ;
|
output [pDepthWidth-1:0] qvWAddr ;
|
input iREn ;
|
input iREn ;
|
output [pDepthWidth-1:0] qvRAddr ;
|
output [pDepthWidth-1:0] qvRAddr ;
|
output qEmpty ;
|
output qEmpty ;
|
output qFull ;
|
output qFull ;
|
output [pDepthWidth:0] qvCount ;
|
output [pDepthWidth:0] qvCount ;
|
|
|
wire Reset ;
|
wire Reset ;
|
wire clock ;
|
wire clock ;
|
wire iWEn ;
|
wire iWEn ;
|
wire MemWEn ;
|
wire MemWEn ;
|
reg [pDepthWidth-1:0] qvWAddr ;
|
reg [pDepthWidth-1:0] qvWAddr ;
|
wire iREn ;
|
wire iREn ;
|
reg [pDepthWidth-1:0] qvRAddr ;
|
reg [pDepthWidth-1:0] qvRAddr ;
|
reg qEmpty ;
|
reg qEmpty ;
|
reg qFull ;
|
reg qFull ;
|
reg [pDepthWidth:0] qvCount ;
|
reg [pDepthWidth:0] qvCount ;
|
|
|
wire MemREn ;
|
wire MemREn ;
|
|
|
// write allow wire - writes are allowed when fifo is not full
|
// write allow wire - writes are allowed when fifo is not full
|
// read allow wire - reads are allowed when fifo is not empty
|
// read allow wire - reads are allowed when fifo is not empty
|
assign MemWEn = iWEn && ( ~qFull ) ;
|
assign MemWEn = iWEn && ( ~qFull ) ;
|
assign MemREn = iREn && ( ~qEmpty ) ;
|
assign MemREn = iREn && ( ~qEmpty ) ;
|
|
|
// write address module
|
// write address module
|
always @ ( posedge clock or negedge Reset) begin
|
always @ ( posedge clock or negedge Reset) begin
|
if( ~Reset ) begin
|
if( ~Reset ) begin
|
qvWAddr <= 0 ;
|
qvWAddr <= 0 ;
|
end
|
end
|
else begin
|
else begin
|
if( MemWEn ) qvWAddr <= qvWAddr + 1'b1 ;
|
if( MemWEn ) qvWAddr <= qvWAddr + 1'b1 ;
|
end
|
end
|
end
|
end
|
|
|
// read address module
|
// read address module
|
always @ ( posedge clock or negedge Reset) begin
|
always @ ( posedge clock or negedge Reset) begin
|
if( ~Reset ) begin
|
if( ~Reset ) begin
|
qvRAddr <= 0 ;
|
qvRAddr <= 0 ;
|
end
|
end
|
else begin
|
else begin
|
if( MemREn ) qvRAddr <= qvRAddr + 1'b1 ;
|
if( MemREn ) qvRAddr <= qvRAddr + 1'b1 ;
|
end
|
end
|
end
|
end
|
|
|
// flags module
|
// flags module
|
always @ ( posedge clock or negedge Reset) begin
|
always @ ( posedge clock or negedge Reset) begin
|
if( ~Reset ) begin
|
if( ~Reset ) begin
|
qFull <= 0 ;
|
qFull <= 0 ;
|
qEmpty <= 1 ;
|
qEmpty <= 1 ;
|
qvCount <= 0 ;
|
qvCount <= 0 ;
|
end
|
end
|
else begin
|
else begin
|
if( MemWEn ) begin
|
if( MemWEn ) begin
|
if( qEmpty ) qEmpty <= 0 ;
|
if( qEmpty ) qEmpty <= 0 ;
|
if ( ~MemREn ) begin
|
if ( ~MemREn ) begin
|
qvCount <= qvCount + 1'b1 ;
|
qvCount <= qvCount + 1'b1 ;
|
if( qvCount[pDepthWidth-1:0] == { pDepthWidth{1'b1} } )
|
if( qvCount[pDepthWidth-1:0] == { pDepthWidth{1'b1} } )
|
qFull <= 1 ;
|
qFull <= 1 ;
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
if( MemREn ) begin
|
if( MemREn ) begin
|
qvCount <= qvCount - 1'b1 ;
|
qvCount <= qvCount - 1'b1 ;
|
if( qvCount == 1'b1 ) qEmpty <= 1;
|
if( qvCount == 1'b1 ) qEmpty <= 1;
|
if( qFull ) qFull <= 0;
|
if( qFull ) qFull <= 0;
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|
//=============================================================================================================
|
//=============================================================================================================
|
|
|
module DualPortRAM
|
module DualPortRAM
|
(
|
(
|
clock ,
|
clock ,
|
MemWEn ,
|
MemWEn ,
|
qvWAddr ,
|
qvWAddr ,
|
vDataIn ,
|
vDataIn ,
|
qvRAddr ,
|
qvRAddr ,
|
vDataOut
|
vDataOut
|
);
|
);
|
|
|
// Default address and data width
|
// Default address and data width
|
parameter pDepthWidth = 5 ;
|
parameter pDepthWidth = 5 ;
|
parameter pWordWidth = 16 ;
|
parameter pWordWidth = 16 ;
|
|
|
// Generic synchronous two-port RAM interface
|
// Generic synchronous two-port RAM interface
|
input clock ; // clock
|
input clock ; // clock
|
input MemWEn ; // write enable input
|
input MemWEn ; // write enable input
|
input [pDepthWidth-1:0] qvWAddr ; // write address bus
|
input [pDepthWidth-1:0] qvWAddr ; // write address bus
|
input [pWordWidth-1:0] vDataIn ; // input data bus
|
input [pWordWidth-1:0] vDataIn ; // input data bus
|
input [pDepthWidth-1:0] qvRAddr ; // read address bus
|
input [pDepthWidth-1:0] qvRAddr ; // read address bus
|
output [pWordWidth-1:0] vDataOut ; // output data bus
|
output [pWordWidth-1:0] vDataOut ; // output data bus
|
|
|
|
|
// Generic two-port synchronous RAM model
|
// Generic two-port synchronous RAM model
|
|
|
// Generic RAM's registers and wires
|
// Generic RAM's registers and wires
|
reg [pWordWidth-1:0] mem[(1<<pDepthWidth)-1:0] /*synthesis syn_ramstyle="no_rw_check"*/;
|
reg [pWordWidth-1:0] mem[(1<<pDepthWidth)-1:0] /*synthesis syn_ramstyle="no_rw_check"*/;
|
|
|
always @ ( posedge clock )
|
always @ ( posedge clock )
|
if ( MemWEn )
|
if ( MemWEn )
|
mem[qvWAddr] <= vDataIn ;
|
mem[qvWAddr] <= vDataIn ;
|
|
|
assign vDataOut = mem[qvRAddr] ;
|
assign vDataOut = mem[qvRAddr] ;
|
|
|
endmodule
|
endmodule
|
|
|
|
|
///**********************************************************************
|
///**********************************************************************
|
// FIFO
|
// FIFO
|
|
|