1495 lines
38 KiB
Verilog
Executable File
1495 lines
38 KiB
Verilog
Executable File
//
|
|
// Generated by Bluespec Compiler, version 2009.11.beta2 (build 18693, 2009-11-24)
|
|
//
|
|
// On Tue Jun 8 18:41:53 EDT 2010
|
|
//
|
|
//
|
|
// Ports:
|
|
// Name I/O size props
|
|
// RDY_iport0_put O 1
|
|
// RDY_iport1_put O 1
|
|
// oport_get O 153
|
|
// RDY_oport_get O 1
|
|
// CLK I 1 clock
|
|
// RST_N I 1 reset
|
|
// iport0_put I 153
|
|
// iport1_put I 153
|
|
// EN_iport0_put I 1
|
|
// EN_iport1_put I 1
|
|
// EN_oport_get I 1
|
|
//
|
|
// No combinational paths from inputs to outputs
|
|
//
|
|
//
|
|
|
|
|
|
|
|
module mkPktMerge(CLK,
|
|
RST_N,
|
|
|
|
iport0_put,
|
|
EN_iport0_put,
|
|
RDY_iport0_put,
|
|
|
|
iport1_put,
|
|
EN_iport1_put,
|
|
RDY_iport1_put,
|
|
|
|
EN_oport_get,
|
|
oport_get,
|
|
RDY_oport_get);
|
|
input CLK;
|
|
input RST_N;
|
|
|
|
// action method iport0_put
|
|
input [152 : 0] iport0_put;
|
|
input EN_iport0_put;
|
|
output RDY_iport0_put;
|
|
|
|
// action method iport1_put
|
|
input [152 : 0] iport1_put;
|
|
input EN_iport1_put;
|
|
output RDY_iport1_put;
|
|
|
|
// actionvalue method oport_get
|
|
input EN_oport_get;
|
|
output [152 : 0] oport_get;
|
|
output RDY_oport_get;
|
|
|
|
// signals for module outputs
|
|
wire [152 : 0] oport_get;
|
|
wire RDY_iport0_put, RDY_iport1_put, RDY_oport_get;
|
|
|
|
// register fi0Active
|
|
reg fi0Active;
|
|
wire fi0Active__D_IN;
|
|
wire fi0Active__EN;
|
|
|
|
// register fi0HasPrio
|
|
reg fi0HasPrio;
|
|
reg fi0HasPrio__D_IN;
|
|
wire fi0HasPrio__EN;
|
|
|
|
// register fi1Active
|
|
reg fi1Active;
|
|
wire fi1Active__D_IN, fi1Active__EN;
|
|
|
|
// ports of submodule fi0
|
|
wire [152 : 0] fi0__D_IN, fi0__D_OUT;
|
|
wire fi0__CLR, fi0__DEQ, fi0__EMPTY_N, fi0__ENQ, fi0__FULL_N;
|
|
|
|
// ports of submodule fi1
|
|
wire [152 : 0] fi1__D_IN, fi1__D_OUT;
|
|
wire fi1__CLR, fi1__DEQ, fi1__EMPTY_N, fi1__ENQ, fi1__FULL_N;
|
|
|
|
// ports of submodule fo
|
|
reg [152 : 0] fo__D_IN;
|
|
wire [152 : 0] fo__D_OUT;
|
|
wire fo__CLR, fo__DEQ, fo__EMPTY_N, fo__ENQ, fo__FULL_N;
|
|
|
|
// rule scheduling signals
|
|
wire CAN_FIRE_RL_arbitrate,
|
|
CAN_FIRE_RL_fi0_advance,
|
|
CAN_FIRE_RL_fi1_advance,
|
|
CAN_FIRE_iport0_put,
|
|
CAN_FIRE_iport1_put,
|
|
CAN_FIRE_oport_get,
|
|
WILL_FIRE_RL_arbitrate,
|
|
WILL_FIRE_RL_fi0_advance,
|
|
WILL_FIRE_RL_fi1_advance,
|
|
WILL_FIRE_iport0_put,
|
|
WILL_FIRE_iport1_put,
|
|
WILL_FIRE_oport_get;
|
|
|
|
// inputs to muxes for submodule ports
|
|
wire [152 : 0] MUX_fo__enq_1__VAL_1;
|
|
wire MUX_fi0Active__write_1__SEL_1,
|
|
MUX_fi0Active__write_1__VAL_1,
|
|
MUX_fi1Active__write_1__SEL_1;
|
|
|
|
// remaining internal signals
|
|
reg [63 : 0] v__h679;
|
|
wire fo_RDY_enq_AND_IF_fi0HasPrio_THEN_fi0_RDY_firs_ETC___d10;
|
|
|
|
// action method iport0_put
|
|
assign RDY_iport0_put = fi0__FULL_N ;
|
|
assign CAN_FIRE_iport0_put = fi0__FULL_N ;
|
|
assign WILL_FIRE_iport0_put = EN_iport0_put ;
|
|
|
|
// action method iport1_put
|
|
assign RDY_iport1_put = fi1__FULL_N ;
|
|
assign CAN_FIRE_iport1_put = fi1__FULL_N ;
|
|
assign WILL_FIRE_iport1_put = EN_iport1_put ;
|
|
|
|
// actionvalue method oport_get
|
|
assign oport_get = fo__D_OUT ;
|
|
assign RDY_oport_get = fo__EMPTY_N ;
|
|
assign CAN_FIRE_oport_get = fo__EMPTY_N ;
|
|
assign WILL_FIRE_oport_get = EN_oport_get ;
|
|
|
|
// submodule fi0
|
|
arSRLFIFO_a fi0 (.CLK(CLK),
|
|
.RST_N(RST_N),
|
|
.D_IN(fi0__D_IN),
|
|
.ENQ(fi0__ENQ),
|
|
.DEQ(fi0__DEQ),
|
|
.CLR(fi0__CLR),
|
|
.D_OUT(fi0__D_OUT),
|
|
.EMPTY_N(fi0__EMPTY_N),
|
|
.FULL_N(fi0__FULL_N));
|
|
|
|
// submodule fi1
|
|
arSRLFIFO_b fi1
|
|
(.CLK(CLK),
|
|
.RST_N(RST_N),
|
|
.D_IN(fi1__D_IN),
|
|
.ENQ(fi1__ENQ),
|
|
.DEQ(fi1__DEQ),
|
|
.CLR(fi1__CLR),
|
|
.D_OUT(fi1__D_OUT),
|
|
.EMPTY_N(fi1__EMPTY_N),
|
|
.FULL_N(fi1__FULL_N));
|
|
|
|
// submodule fo
|
|
arSRLFIFO_c fo
|
|
(.CLK(CLK),
|
|
.RST_N(RST_N),
|
|
.D_IN(fo__D_IN),
|
|
.ENQ(fo__ENQ),
|
|
.DEQ(fo__DEQ),
|
|
.CLR(fo__CLR),
|
|
.D_OUT(fo__D_OUT),
|
|
.EMPTY_N(fo__EMPTY_N),
|
|
.FULL_N(fo__FULL_N));
|
|
|
|
// rule RL_arbitrate
|
|
assign CAN_FIRE_RL_arbitrate =
|
|
fo_RDY_enq_AND_IF_fi0HasPrio_THEN_fi0_RDY_firs_ETC___d10 &&
|
|
fi0__EMPTY_N &&
|
|
fi1__EMPTY_N &&
|
|
!fi0Active &&
|
|
!fi1Active ;
|
|
assign WILL_FIRE_RL_arbitrate = CAN_FIRE_RL_arbitrate ;
|
|
|
|
// rule RL_fi0_advance
|
|
assign CAN_FIRE_RL_fi0_advance = fi0__EMPTY_N && fo__FULL_N && !fi1Active ;
|
|
assign WILL_FIRE_RL_fi0_advance =
|
|
CAN_FIRE_RL_fi0_advance && !WILL_FIRE_RL_arbitrate ;
|
|
|
|
// rule RL_fi1_advance
|
|
assign CAN_FIRE_RL_fi1_advance = fi1__EMPTY_N && fo__FULL_N && !fi0Active ;
|
|
assign WILL_FIRE_RL_fi1_advance =
|
|
CAN_FIRE_RL_fi1_advance && !WILL_FIRE_RL_fi0_advance &&
|
|
!WILL_FIRE_RL_arbitrate ;
|
|
|
|
// inputs to muxes for submodule ports
|
|
assign MUX_fi0Active__write_1__SEL_1 = WILL_FIRE_RL_arbitrate && fi0HasPrio ;
|
|
assign MUX_fi1Active__write_1__SEL_1 =
|
|
WILL_FIRE_RL_arbitrate && !fi0HasPrio ;
|
|
assign MUX_fi0Active__write_1__VAL_1 =
|
|
fi0HasPrio ? !fi0__D_OUT[151] : !fi1__D_OUT[151] ;
|
|
assign MUX_fo__enq_1__VAL_1 = fi0HasPrio ? fi0__D_OUT : fi1__D_OUT ;
|
|
|
|
// register fi0Active
|
|
assign fi0Active__D_IN =
|
|
MUX_fi0Active__write_1__SEL_1 ?
|
|
MUX_fi0Active__write_1__VAL_1 :
|
|
!fi0__D_OUT[151] ;
|
|
assign fi0Active__EN =
|
|
WILL_FIRE_RL_arbitrate && fi0HasPrio ||
|
|
WILL_FIRE_RL_fi0_advance ;
|
|
|
|
// register fi0HasPrio
|
|
always@(WILL_FIRE_RL_arbitrate or
|
|
fi0HasPrio or WILL_FIRE_RL_fi0_advance or WILL_FIRE_RL_fi1_advance)
|
|
begin
|
|
// case (1'b1) // synopsys parallel_case
|
|
// WILL_FIRE_RL_arbitrate: fi0HasPrio__D_IN = !fi0HasPrio;
|
|
// WILL_FIRE_RL_fi0_advance: fi0HasPrio__D_IN = 1'd0;
|
|
// WILL_FIRE_RL_fi1_advance: fi0HasPrio__D_IN = 1'd1;
|
|
//case (1'b1) // synopsys parallel_case
|
|
// WILL_FIRE_RL_arbitrate: fi0HasPrio__D_IN = !fi0HasPrio;
|
|
fi0HasPrio__D_IN = !fi0HasPrio;
|
|
// WILL_FIRE_RL_fi0_advance: fi0HasPrio__D_IN = 1'd0;
|
|
// WILL_FIRE_RL_fi1_advance: fi0HasPrio__D_IN = 1'd1;
|
|
|
|
// endcase
|
|
//endcase
|
|
end
|
|
assign fi0HasPrio__EN =
|
|
WILL_FIRE_RL_arbitrate || WILL_FIRE_RL_fi0_advance ||
|
|
WILL_FIRE_RL_fi1_advance ;
|
|
|
|
// register fi1Active
|
|
assign fi1Active__D_IN =
|
|
MUX_fi1Active__write_1__SEL_1 ?
|
|
MUX_fi0Active__write_1__VAL_1 :
|
|
!fi1__D_OUT[151] ;
|
|
assign fi1Active__EN =
|
|
WILL_FIRE_RL_arbitrate && !fi0HasPrio ||
|
|
WILL_FIRE_RL_fi1_advance ;
|
|
|
|
// submodule fi0
|
|
assign fi0__D_IN = iport0_put ;
|
|
assign fi0__DEQ =
|
|
WILL_FIRE_RL_arbitrate && fi0HasPrio ||
|
|
WILL_FIRE_RL_fi0_advance ;
|
|
assign fi0__ENQ = EN_iport0_put ;
|
|
assign fi0__CLR = 1'b0 ;
|
|
|
|
// submodule fi1
|
|
assign fi1__D_IN = iport1_put ;
|
|
assign fi1__DEQ =
|
|
WILL_FIRE_RL_arbitrate && !fi0HasPrio ||
|
|
WILL_FIRE_RL_fi1_advance ;
|
|
assign fi1__ENQ = EN_iport1_put ;
|
|
assign fi1__CLR = 1'b0 ;
|
|
|
|
// submodule fo
|
|
always@(WILL_FIRE_RL_arbitrate or
|
|
MUX_fo__enq_1__VAL_1 or
|
|
WILL_FIRE_RL_fi0_advance or
|
|
fi0__D_OUT or WILL_FIRE_RL_fi1_advance or fi1__D_OUT)
|
|
begin
|
|
// case (1'b1) // synopsys parallel_case
|
|
//WILL_FIRE_RL_arbitrate: fo__D_IN = MUX_fo__enq_1__VAL_1;
|
|
fo__D_IN = MUX_fo__enq_1__VAL_1;
|
|
// WILL_FIRE_RL_fi0_advance: fo__D_IN = fi0__D_OUT;
|
|
// WILL_FIRE_RL_fi1_advance: fo__D_IN = fi1__D_OUT;
|
|
|
|
// endcase
|
|
end
|
|
assign fo__DEQ = EN_oport_get ;
|
|
assign fo__ENQ =
|
|
WILL_FIRE_RL_arbitrate || WILL_FIRE_RL_fi0_advance ||
|
|
WILL_FIRE_RL_fi1_advance ;
|
|
assign fo__CLR = 1'b0 ;
|
|
|
|
// remaining internal signals
|
|
assign fo_RDY_enq_AND_IF_fi0HasPrio_THEN_fi0_RDY_firs_ETC___d10 =
|
|
fo__FULL_N && (fi0HasPrio ? fi0__EMPTY_N : fi1__EMPTY_N) ;
|
|
|
|
// handling of inlined registers
|
|
|
|
always@(posedge CLK)
|
|
begin
|
|
if (!RST_N)
|
|
begin
|
|
fi0Active <= 1'd0;
|
|
fi0HasPrio <= 1'd1;
|
|
fi1Active <= 1'd0;
|
|
end
|
|
else
|
|
begin
|
|
if (fi0Active__EN) fi0Active <= fi0Active__D_IN;
|
|
if (fi0HasPrio__EN)
|
|
fi0HasPrio <= fi0HasPrio__D_IN;
|
|
if (fi1Active__EN) fi1Active <= fi1Active__D_IN;
|
|
end
|
|
end
|
|
|
|
|
|
// handling of system tasks
|
|
|
|
|
|
endmodule // mkPktMerge
|
|
|
|
|
|
|
|
|
|
module arSRLFIFO_a (CLK, RST_N, D_IN,ENQ,DEQ,CLR,D_OUT,EMPTY_N,FULL_N);
|
|
|
|
input CLK;
|
|
input RST_N;
|
|
input [152:0] D_IN;
|
|
input ENQ;
|
|
input DEQ;
|
|
input CLR;
|
|
output [152:0] D_OUT;
|
|
output EMPTY_N;
|
|
output FULL_N;
|
|
|
|
|
|
|
|
wire fulln;
|
|
wire emptyn;
|
|
|
|
wire always_one;
|
|
wire always_zero;
|
|
|
|
assign always_one = 1'b1;
|
|
assign always_zero = 1'b0;
|
|
|
|
generic_fifo_sc_a fifo_1
|
|
(.clk(CLK),
|
|
.rst(RST_N),
|
|
.clr (CLR),
|
|
.din (D_IN),
|
|
.we (ENQ),
|
|
.dout (D_OUT),
|
|
.re (DEQ),
|
|
.full_r (FULL_N),
|
|
.empty_r(EMPTY_N),
|
|
.full_n_r (fulln),
|
|
.empty_n_r (emptyn)
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//// ////
|
|
//// Universal FIFO Single Clock ////
|
|
//// ////
|
|
//// ////
|
|
//// Author: Rudolf Usselmann ////
|
|
//// rudi@asics.ws ////
|
|
//// ////
|
|
//// ////
|
|
//// D/L from: http://www.opencores.org/cores/generic_fifos/ ////
|
|
//// ////
|
|
/////////////////////////////////////////////////////////////////////
|
|
//// ////
|
|
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
|
//// www.asics.ws ////
|
|
//// rudi@asics.ws ////
|
|
//// ////
|
|
//// This source file may be used and distributed without ////
|
|
//// restriction provided that this copyright statement is not ////
|
|
//// removed from the file and that any derivative work contains ////
|
|
//// the original copyright notice and the associated disclaimer.////
|
|
//// ////
|
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
|
//// ////
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
// CVS Log
|
|
//
|
|
// __Id: generic_fifo_sc_a.v,v 1.1.1.1 2002-09-25 05:42:06 rudi Exp __
|
|
//
|
|
// __Date: 2002-09-25 05:42:06 __
|
|
// __Revision: 1.1.1.1 __
|
|
// __Author: rudi __
|
|
// __Locker: __
|
|
// __State: Exp __
|
|
//
|
|
// Change History:
|
|
// __Log: not supported by cvs2svn __
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
/*
|
|
|
|
Description
|
|
===========
|
|
|
|
I/Os
|
|
----
|
|
rst low active, either sync. or async. master reset (see below how to select)
|
|
clr synchronous clear (just like reset but always synchronous), high active
|
|
re read enable, synchronous, high active
|
|
we read enable, synchronous, high active
|
|
din Data Input
|
|
dout Data Output
|
|
|
|
full Indicates the FIFO is full (combinatorial output)
|
|
full_r same as above, but registered output (see note below)
|
|
empty Indicates the FIFO is empty
|
|
empty_r same as above, but registered output (see note below)
|
|
|
|
full_n Indicates if the FIFO has space for N entries (combinatorial output)
|
|
full_n_r same as above, but registered output (see note below)
|
|
empty_n Indicates the FIFO has at least N entries (combinatorial output)
|
|
empty_n_r same as above, but registered output (see note below)
|
|
|
|
level indicates the FIFO level:
|
|
2'b00 0-25% full
|
|
2'b01 25-50% full
|
|
2'b10 50-75% full
|
|
2'b11 %75-100% full
|
|
|
|
combinatorial vs. registered status outputs
|
|
-------------------------------------------
|
|
Both the combinatorial and registered status outputs have exactly the same
|
|
synchronous timing. Meaning they are being asserted immediately at the clock
|
|
edge after the last read or write. The combinatorial outputs however, pass
|
|
through several levels of logic before they are output. The registered status
|
|
outputs are direct outputs of a flip-flop. The reason both are provided, is
|
|
that the registered outputs require quite a bit of additional logic inside
|
|
the FIFO. If you can meet timing of your device with the combinatorial
|
|
outputs, use them ! The FIFO will be smaller. If the status signals are
|
|
in the critical pass, use the registered outputs, they have a much smaller
|
|
output delay (actually only Tcq).
|
|
|
|
Parameters
|
|
----------
|
|
The FIFO takes 3 parameters:
|
|
dw Data bus width
|
|
aw Address bus width (Determines the FIFO size by evaluating 2^aw)
|
|
n N is a second status threshold constant for full_n and empty_n
|
|
If you have no need for the second status threshold, do not
|
|
connect the outputs and the logic should be removed by your
|
|
synthesis tool.
|
|
|
|
Synthesis Results
|
|
-----------------
|
|
In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 85 LUTs and runs
|
|
at about 116 MHz (IO insertion disabled). The registered status outputs
|
|
are valid after 2.1NS, the combinatorial once take out to 6.5 NS to be
|
|
available.
|
|
|
|
|
|
Misc
|
|
----
|
|
This design assumes you will do appropriate status checking externally.
|
|
|
|
IMPORTANT ! writing while the FIFO is full or reading while the FIFO is
|
|
empty will place the FIFO in an undefined state.
|
|
|
|
*/
|
|
|
|
|
|
// Selecting Sync. or Async Reset
|
|
// ------------------------------
|
|
// Uncomment one of the two lines below. The first line for
|
|
// synchronous reset, the second for asynchronous reset
|
|
|
|
//`define SC_FIFO_ASYNC_RESET // Uncomment for Syncr. reset
|
|
//`define SC_FIFO_ASYNC_RESET or negedge rst // Uncomment for Async. reset
|
|
`define dw 153
|
|
`define aw 4
|
|
`define n 32
|
|
`define max_size 30
|
|
|
|
/*
|
|
parameter dw=8;
|
|
parameter aw=8;
|
|
parameter n=32;
|
|
parameter max_size = 1<<aw;
|
|
*/
|
|
|
|
module generic_fifo_sc_a(clk, rst, clr, din, we, dout, re,
|
|
full_r, empty_r,
|
|
full_n_r, empty_n_r);
|
|
/*
|
|
parameter dw=8;
|
|
parameter aw=8;
|
|
parameter n=32;
|
|
parameter max_size = 1<<aw;
|
|
*/
|
|
input clk, rst, clr;
|
|
input [`dw-1:0] din;
|
|
input we;
|
|
output [`dw-1:0] dout;
|
|
input re;
|
|
output full, full_r;
|
|
output empty, empty_r;
|
|
output full_n, full_n_r;
|
|
output empty_n, empty_n_r;
|
|
output [1:0] level;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Local Wires
|
|
//
|
|
|
|
reg [`aw-1:0] wp;
|
|
wire [`aw-1:0] wp_pl1;
|
|
wire [`aw-1:0] wp_pl2;
|
|
reg [`aw-1:0] rp;
|
|
wire [`aw-1:0] rp_pl1;
|
|
reg full_r;
|
|
reg empty_r;
|
|
reg gb;
|
|
reg gb2;
|
|
reg [`aw:0] cnt;
|
|
wire full_n, empty_n;
|
|
reg full_n_r, empty_n_r;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Memory Block
|
|
//
|
|
wire always_zero;
|
|
assign always_zero = 1'b0;
|
|
wire [`dw-1:0] junk_out;
|
|
|
|
wire [`dw-1:0] junk_in;
|
|
|
|
// manually assign
|
|
assign junk_in = 0;
|
|
|
|
dual_port_ram ram1(
|
|
.clk( clk ),
|
|
.addr1( rp ),
|
|
.addr2( wp ),
|
|
.we1( we ),
|
|
.we2( always_zero ),
|
|
.out1( doutz ),
|
|
.out2( junk_out ),
|
|
.data1( din ),
|
|
.data2 ( junk_in)
|
|
);
|
|
|
|
wire [`dw-1:0] doutz;
|
|
assign dout = (1'b1) ? doutz: junk_out;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Misc Logic
|
|
//
|
|
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) wp <= {4'b0000};
|
|
else
|
|
if(clr) wp <= {4'b0000};
|
|
else
|
|
if(we) wp <= wp_pl1;
|
|
end
|
|
assign wp_pl1 = wp + { {3'b000}, 1'b1};
|
|
assign wp_pl2 = wp + { {2'b00}, 2'b10};
|
|
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) rp <= {4'b0000};
|
|
else
|
|
if(clr) rp <= {4'b0000};
|
|
else
|
|
if(re) rp <= rp_pl1;
|
|
end
|
|
assign rp_pl1 = rp + { {3'b000}, 1'b1};
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Combinatorial Full & Empty Flags
|
|
//
|
|
|
|
assign empty = ((wp == rp) && !gb);
|
|
assign full = ((wp == rp) && gb);
|
|
|
|
// Guard Bit ...
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) gb <= 1'b0;
|
|
else
|
|
if(clr) gb <= 1'b0;
|
|
else
|
|
if((wp_pl1 == rp) && we) gb <= 1'b1;
|
|
else
|
|
if(re) gb <= 1'b0;
|
|
end
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Registered Full & Empty Flags
|
|
//
|
|
|
|
// Guard Bit ...
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) gb2 <= 1'b0;
|
|
else
|
|
if(clr) gb2 <= 1'b0;
|
|
else
|
|
if((wp_pl2 == rp) && we) gb2 <= 1'b1;
|
|
else
|
|
if((wp != rp) && re) gb2 <= 1'b0;
|
|
end
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) full_r <= 1'b0;
|
|
else
|
|
if(clr) full_r <= 1'b0;
|
|
else
|
|
if(we && ((wp_pl1 == rp) && gb2) && !re) full_r <= 1'b1;
|
|
else
|
|
if(re && ((wp_pl1 != rp) | !gb2) && !we) full_r <= 1'b0;
|
|
end
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) empty_r <= 1'b1;
|
|
else
|
|
if(clr) empty_r <= 1'b1;
|
|
else
|
|
if(we && ((wp != rp_pl1) | gb2) && !re) empty_r <= 1'b0;
|
|
else
|
|
if(re && ((wp == rp_pl1) && !gb2) && !we) empty_r <= 1'b1;
|
|
end
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Combinatorial Full_n && Empty_n Flags
|
|
//
|
|
|
|
assign empty_n = cnt < `n;
|
|
assign full_n = !(cnt < (`max_size-`n+1));
|
|
assign level = {{cnt[`aw]}, {cnt[`aw]}} | cnt[`aw-1:`aw-2];
|
|
|
|
// N entries status
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) cnt <= {4'b0000};
|
|
else
|
|
if(clr) cnt <= {4'b0000};
|
|
else
|
|
if( re && !we) cnt <= cnt + { 5'b11111};
|
|
else
|
|
if(!re && we) cnt <= cnt + { {4'b0000}, 1'b1};
|
|
end
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Registered Full_n && Empty_n Flags
|
|
//
|
|
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) empty_n_r <= 1'b1;
|
|
else
|
|
if(clr) empty_n_r <= 1'b1;
|
|
else
|
|
if(we && (cnt >= (`n-1) ) && !re) empty_n_r <= 1'b0;
|
|
else
|
|
if(re && (cnt <= `n ) && !we) empty_n_r <= 1'b1;
|
|
end
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) full_n_r <= 1'b0;
|
|
else
|
|
if(clr) full_n_r <= 1'b0;
|
|
else
|
|
if(we && (cnt >= (`max_size-`n) ) && !re) full_n_r <= 1'b1;
|
|
else
|
|
if(re && (cnt <= (`max_size-`n+1)) && !we) full_n_r <= 1'b0;
|
|
end
|
|
endmodule
|
|
|
|
|
|
module arSRLFIFO_b (CLK, RST_N, D_IN,ENQ,DEQ,CLR,D_OUT,EMPTY_N,FULL_N);
|
|
|
|
input CLK;
|
|
input RST_N;
|
|
input [152:0] D_IN;
|
|
input ENQ;
|
|
input DEQ;
|
|
input CLR;
|
|
output [152:0] D_OUT;
|
|
output EMPTY_N;
|
|
output FULL_N;
|
|
|
|
|
|
|
|
wire fulln;
|
|
wire emptyn;
|
|
|
|
wire always_one;
|
|
wire always_zero;
|
|
|
|
assign always_one = 1'b1;
|
|
assign always_zero = 1'b0;
|
|
|
|
generic_fifo_sc_b fifo_1
|
|
(.clk(CLK),
|
|
.rst(RST_N),
|
|
.clr (CLR),
|
|
.din (D_IN),
|
|
.we (ENQ),
|
|
.dout (D_OUT),
|
|
.re (DEQ),
|
|
.full_r (FULL_N),
|
|
.empty_r(EMPTY_N),
|
|
.full_n_r (fulln),
|
|
.empty_n_r (emptyn)
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//// ////
|
|
//// Universal FIFO Single Clock ////
|
|
//// ////
|
|
//// ////
|
|
//// Author: Rudolf Usselmann ////
|
|
//// rudi@asics.ws ////
|
|
//// ////
|
|
//// ////
|
|
//// D/L from: http://www.opencores.org/cores/generic_fifos/ ////
|
|
//// ////
|
|
/////////////////////////////////////////////////////////////////////
|
|
//// ////
|
|
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
|
//// www.asics.ws ////
|
|
//// rudi@asics.ws ////
|
|
//// ////
|
|
//// This source file may be used and distributed without ////
|
|
//// restriction provided that this copyright statement is not ////
|
|
//// removed from the file and that any derivative work contains ////
|
|
//// the original copyright notice and the associated disclaimer.////
|
|
//// ////
|
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
|
//// ////
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
// CVS Log
|
|
//
|
|
// __Id: generic_fifo_sc_a.v,v 1.1.1.1 2002-09-25 05:42:06 rudi Exp __
|
|
//
|
|
// __Date: 2002-09-25 05:42:06 __
|
|
// __Revision: 1.1.1.1 __
|
|
// __Author: rudi __
|
|
// __Locker: __
|
|
// __State: Exp __
|
|
//
|
|
// Change History:
|
|
// __Log: not supported by cvs2svn __
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
/*
|
|
|
|
Description
|
|
===========
|
|
|
|
I/Os
|
|
----
|
|
rst low active, either sync. or async. master reset (see below how to select)
|
|
clr synchronous clear (just like reset but always synchronous), high active
|
|
re read enable, synchronous, high active
|
|
we read enable, synchronous, high active
|
|
din Data Input
|
|
dout Data Output
|
|
|
|
full Indicates the FIFO is full (combinatorial output)
|
|
full_r same as above, but registered output (see note below)
|
|
empty Indicates the FIFO is empty
|
|
empty_r same as above, but registered output (see note below)
|
|
|
|
full_n Indicates if the FIFO has space for N entries (combinatorial output)
|
|
full_n_r same as above, but registered output (see note below)
|
|
empty_n Indicates the FIFO has at least N entries (combinatorial output)
|
|
empty_n_r same as above, but registered output (see note below)
|
|
|
|
level indicates the FIFO level:
|
|
2'b00 0-25% full
|
|
2'b01 25-50% full
|
|
2'b10 50-75% full
|
|
2'b11 %75-100% full
|
|
|
|
combinatorial vs. registered status outputs
|
|
-------------------------------------------
|
|
Both the combinatorial and registered status outputs have exactly the same
|
|
synchronous timing. Meaning they are being asserted immediately at the clock
|
|
edge after the last read or write. The combinatorial outputs however, pass
|
|
through several levels of logic before they are output. The registered status
|
|
outputs are direct outputs of a flip-flop. The reason both are provided, is
|
|
that the registered outputs require quite a bit of additional logic inside
|
|
the FIFO. If you can meet timing of your device with the combinatorial
|
|
outputs, use them ! The FIFO will be smaller. If the status signals are
|
|
in the critical pass, use the registered outputs, they have a much smaller
|
|
output delay (actually only Tcq).
|
|
|
|
Parameters
|
|
----------
|
|
The FIFO takes 3 parameters:
|
|
dw Data bus width
|
|
aw Address bus width (Determines the FIFO size by evaluating 2^aw)
|
|
n N is a second status threshold constant for full_n and empty_n
|
|
If you have no need for the second status threshold, do not
|
|
connect the outputs and the logic should be removed by your
|
|
synthesis tool.
|
|
|
|
Synthesis Results
|
|
-----------------
|
|
In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 85 LUTs and runs
|
|
at about 116 MHz (IO insertion disabled). The registered status outputs
|
|
are valid after 2.1NS, the combinatorial once take out to 6.5 NS to be
|
|
available.
|
|
|
|
|
|
Misc
|
|
----
|
|
This design assumes you will do appropriate status checking externally.
|
|
|
|
IMPORTANT ! writing while the FIFO is full or reading while the FIFO is
|
|
empty will place the FIFO in an undefined state.
|
|
|
|
*/
|
|
|
|
|
|
// Selecting Sync. or Async Reset
|
|
// ------------------------------
|
|
// Uncomment one of the two lines below. The first line for
|
|
// synchronous reset, the second for asynchronous reset
|
|
|
|
//`define SC_FIFO_ASYNC_RESET // Uncomment for Syncr. reset
|
|
//`define SC_FIFO_ASYNC_RESET or negedge rst // Uncomment for Async. reset
|
|
|
|
|
|
/*
|
|
parameter dw=8;
|
|
parameter aw=8;
|
|
parameter n=32;
|
|
parameter max_size = 1<<aw;
|
|
*/
|
|
|
|
module generic_fifo_sc_b(clk, rst, clr, din, we, dout, re,
|
|
full_r, empty_r,
|
|
full_n_r, empty_n_r);
|
|
/*
|
|
parameter dw=8;
|
|
parameter aw=8;
|
|
parameter n=32;
|
|
parameter max_size = 1<<aw;
|
|
*/
|
|
input clk, rst, clr;
|
|
input [`dw-1:0] din;
|
|
input we;
|
|
output [`dw-1:0] dout;
|
|
input re;
|
|
output full, full_r;
|
|
output empty, empty_r;
|
|
output full_n, full_n_r;
|
|
output empty_n, empty_n_r;
|
|
output [1:0] level;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Local Wires
|
|
//
|
|
|
|
reg [`aw-1:0] wp;
|
|
wire [`aw-1:0] wp_pl1;
|
|
wire [`aw-1:0] wp_pl2;
|
|
reg [`aw-1:0] rp;
|
|
wire [`aw-1:0] rp_pl1;
|
|
reg full_r;
|
|
reg empty_r;
|
|
reg gb;
|
|
reg gb2;
|
|
reg [`aw:0] cnt;
|
|
wire full_n, empty_n;
|
|
reg full_n_r, empty_n_r;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Memory Block
|
|
//
|
|
wire always_zero;
|
|
assign always_zero = 1'b0;
|
|
wire [`dw-1:0] junk_out;
|
|
|
|
wire [`dw-1:0] junk_in;
|
|
|
|
// manually assign
|
|
assign junk_in = 0;
|
|
|
|
dual_port_ram ram1(
|
|
.clk( clk ),
|
|
.addr1( rp ),
|
|
.addr2( wp ),
|
|
.we1( we ),
|
|
.we2( always_zero ),
|
|
.out1( doutz ),
|
|
.out2( junk_out ),
|
|
.data1( din ),
|
|
.data2 ( junk_in)
|
|
);
|
|
|
|
wire [`dw-1:0] doutz;
|
|
assign dout = (1'b1) ? doutz: junk_out;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Misc Logic
|
|
//
|
|
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) wp <= {4'b0000};
|
|
else
|
|
if(clr) wp <= {4'b0000};
|
|
else
|
|
if(we) wp <= wp_pl1;
|
|
end
|
|
assign wp_pl1 = wp + { {3'b000}, 1'b1};
|
|
assign wp_pl2 = wp + { {2'b00}, 2'b10};
|
|
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) rp <= {4'b0000};
|
|
else
|
|
if(clr) rp <= {4'b0000};
|
|
else
|
|
if(re) rp <= rp_pl1;
|
|
end
|
|
assign rp_pl1 = rp + { {3'b000}, 1'b1};
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Combinatorial Full & Empty Flags
|
|
//
|
|
|
|
assign empty = ((wp == rp) && !gb);
|
|
assign full = ((wp == rp) && gb);
|
|
|
|
// Guard Bit ...
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) gb <= 1'b0;
|
|
else
|
|
if(clr) gb <= 1'b0;
|
|
else
|
|
if((wp_pl1 == rp) && we) gb <= 1'b1;
|
|
else
|
|
if(re) gb <= 1'b0;
|
|
end
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Registered Full & Empty Flags
|
|
//
|
|
|
|
// Guard Bit ...
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) gb2 <= 1'b0;
|
|
else
|
|
if(clr) gb2 <= 1'b0;
|
|
else
|
|
if((wp_pl2 == rp) && we) gb2 <= 1'b1;
|
|
else
|
|
if((wp != rp) && re) gb2 <= 1'b0;
|
|
end
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) full_r <= 1'b0;
|
|
else
|
|
if(clr) full_r <= 1'b0;
|
|
else
|
|
if(we && ((wp_pl1 == rp) && gb2) && !re) full_r <= 1'b1;
|
|
else
|
|
if(re && ((wp_pl1 != rp) | !gb2) && !we) full_r <= 1'b0;
|
|
end
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) empty_r <= 1'b1;
|
|
else
|
|
if(clr) empty_r <= 1'b1;
|
|
else
|
|
if(we && ((wp != rp_pl1) | gb2) && !re) empty_r <= 1'b0;
|
|
else
|
|
if(re && ((wp == rp_pl1) && !gb2) && !we) empty_r <= 1'b1;
|
|
end
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Combinatorial Full_n && Empty_n Flags
|
|
//
|
|
|
|
assign empty_n = cnt < `n;
|
|
assign full_n = !(cnt < (`max_size-`n+1));
|
|
assign level = {{cnt[`aw]}, {cnt[`aw]}} | cnt[`aw-1:`aw-2];
|
|
|
|
// N entries status
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) cnt <= {4'b0000};
|
|
else
|
|
if(clr) cnt <= {4'b0000};
|
|
else
|
|
if( re && !we) cnt <= cnt + { 5'b11111};
|
|
else
|
|
if(!re && we) cnt <= cnt + { {4'b0000}, 1'b1};
|
|
end
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Registered Full_n && Empty_n Flags
|
|
//
|
|
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) empty_n_r <= 1'b1;
|
|
else
|
|
if(clr) empty_n_r <= 1'b1;
|
|
else
|
|
if(we && (cnt >= (`n-1) ) && !re) empty_n_r <= 1'b0;
|
|
else
|
|
if(re && (cnt <= `n ) && !we) empty_n_r <= 1'b1;
|
|
end
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) full_n_r <= 1'b0;
|
|
else
|
|
if(clr) full_n_r <= 1'b0;
|
|
else
|
|
if(we && (cnt >= (`max_size-`n) ) && !re) full_n_r <= 1'b1;
|
|
else
|
|
if(re && (cnt <= (`max_size-`n+1)) && !we) full_n_r <= 1'b0;
|
|
end
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
module arSRLFIFO_c (CLK, RST_N, D_IN,ENQ,DEQ,CLR,D_OUT,EMPTY_N,FULL_N);
|
|
|
|
input CLK;
|
|
input RST_N;
|
|
input [152:0] D_IN;
|
|
input ENQ;
|
|
input DEQ;
|
|
input CLR;
|
|
output [152:0] D_OUT;
|
|
output EMPTY_N;
|
|
output FULL_N;
|
|
|
|
|
|
|
|
wire fulln;
|
|
wire emptyn;
|
|
|
|
wire always_one;
|
|
wire always_zero;
|
|
|
|
assign always_one = 1'b1;
|
|
assign always_zero = 1'b0;
|
|
|
|
generic_fifo_sc_c fifo_1
|
|
(.clk(CLK),
|
|
.rst(RST_N),
|
|
.clr (CLR),
|
|
.din (D_IN),
|
|
.we (ENQ),
|
|
.dout (D_OUT),
|
|
.re (DEQ),
|
|
.full_r (FULL_N),
|
|
.empty_r(EMPTY_N),
|
|
.full_n_r (fulln),
|
|
.empty_n_r (emptyn)
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//// ////
|
|
//// Universal FIFO Single Clock ////
|
|
//// ////
|
|
//// ////
|
|
//// Author: Rudolf Usselmann ////
|
|
//// rudi@asics.ws ////
|
|
//// ////
|
|
//// ////
|
|
//// D/L from: http://www.opencores.org/cores/generic_fifos/ ////
|
|
//// ////
|
|
/////////////////////////////////////////////////////////////////////
|
|
//// ////
|
|
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
|
//// www.asics.ws ////
|
|
//// rudi@asics.ws ////
|
|
//// ////
|
|
//// This source file may be used and distributed without ////
|
|
//// restriction provided that this copyright statement is not ////
|
|
//// removed from the file and that any derivative work contains ////
|
|
//// the original copyright notice and the associated disclaimer.////
|
|
//// ////
|
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
|
//// ////
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
// CVS Log
|
|
//
|
|
// __Id: generic_fifo_sc_a.v,v 1.1.1.1 2002-09-25 05:42:06 rudi Exp __
|
|
//
|
|
// __Date: 2002-09-25 05:42:06 __
|
|
// __Revision: 1.1.1.1 __
|
|
// __Author: rudi __
|
|
// __Locker: __
|
|
// __State: Exp __
|
|
//
|
|
// Change History:
|
|
// __Log: not supported by cvs2svn __
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
/*
|
|
|
|
Description
|
|
===========
|
|
|
|
I/Os
|
|
----
|
|
rst low active, either sync. or async. master reset (see below how to select)
|
|
clr synchronous clear (just like reset but always synchronous), high active
|
|
re read enable, synchronous, high active
|
|
we read enable, synchronous, high active
|
|
din Data Input
|
|
dout Data Output
|
|
|
|
full Indicates the FIFO is full (combinatorial output)
|
|
full_r same as above, but registered output (see note below)
|
|
empty Indicates the FIFO is empty
|
|
empty_r same as above, but registered output (see note below)
|
|
|
|
full_n Indicates if the FIFO has space for N entries (combinatorial output)
|
|
full_n_r same as above, but registered output (see note below)
|
|
empty_n Indicates the FIFO has at least N entries (combinatorial output)
|
|
empty_n_r same as above, but registered output (see note below)
|
|
|
|
level indicates the FIFO level:
|
|
2'b00 0-25% full
|
|
2'b01 25-50% full
|
|
2'b10 50-75% full
|
|
2'b11 %75-100% full
|
|
|
|
combinatorial vs. registered status outputs
|
|
-------------------------------------------
|
|
Both the combinatorial and registered status outputs have exactly the same
|
|
synchronous timing. Meaning they are being asserted immediately at the clock
|
|
edge after the last read or write. The combinatorial outputs however, pass
|
|
through several levels of logic before they are output. The registered status
|
|
outputs are direct outputs of a flip-flop. The reason both are provided, is
|
|
that the registered outputs require quite a bit of additional logic inside
|
|
the FIFO. If you can meet timing of your device with the combinatorial
|
|
outputs, use them ! The FIFO will be smaller. If the status signals are
|
|
in the critical pass, use the registered outputs, they have a much smaller
|
|
output delay (actually only Tcq).
|
|
|
|
Parameters
|
|
----------
|
|
The FIFO takes 3 parameters:
|
|
dw Data bus width
|
|
aw Address bus width (Determines the FIFO size by evaluating 2^aw)
|
|
n N is a second status threshold constant for full_n and empty_n
|
|
If you have no need for the second status threshold, do not
|
|
connect the outputs and the logic should be removed by your
|
|
synthesis tool.
|
|
|
|
Synthesis Results
|
|
-----------------
|
|
In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 85 LUTs and runs
|
|
at about 116 MHz (IO insertion disabled). The registered status outputs
|
|
are valid after 2.1NS, the combinatorial once take out to 6.5 NS to be
|
|
available.
|
|
|
|
|
|
Misc
|
|
----
|
|
This design assumes you will do appropriate status checking externally.
|
|
|
|
IMPORTANT ! writing while the FIFO is full or reading while the FIFO is
|
|
empty will place the FIFO in an undefined state.
|
|
|
|
*/
|
|
|
|
|
|
// Selecting Sync. or Async Reset
|
|
// ------------------------------
|
|
// Uncomment one of the two lines below. The first line for
|
|
// synchronous reset, the second for asynchronous reset
|
|
|
|
//`define SC_FIFO_ASYNC_RESET // Uncomment for Syncr. reset
|
|
//`define SC_FIFO_ASYNC_RESET or negedge rst // Uncomment for Async. reset
|
|
|
|
/*
|
|
parameter dw=8;
|
|
parameter aw=8;
|
|
parameter n=32;
|
|
parameter max_size = 1<<aw;
|
|
*/
|
|
|
|
module generic_fifo_sc_c(clk, rst, clr, din, we, dout, re,
|
|
full_r, empty_r,
|
|
full_n_r, empty_n_r);
|
|
/*
|
|
parameter dw=8;
|
|
parameter aw=8;
|
|
parameter n=32;
|
|
parameter max_size = 1<<aw;
|
|
*/
|
|
input clk, rst, clr;
|
|
input [`dw-1:0] din;
|
|
input we;
|
|
output [`dw-1:0] dout;
|
|
input re;
|
|
output full, full_r;
|
|
output empty, empty_r;
|
|
output full_n, full_n_r;
|
|
output empty_n, empty_n_r;
|
|
output [1:0] level;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Local Wires
|
|
//
|
|
|
|
reg [`aw-1:0] wp;
|
|
wire [`aw-1:0] wp_pl1;
|
|
wire [`aw-1:0] wp_pl2;
|
|
reg [`aw-1:0] rp;
|
|
wire [`aw-1:0] rp_pl1;
|
|
reg full_r;
|
|
reg empty_r;
|
|
reg gb;
|
|
reg gb2;
|
|
reg [`aw:0] cnt;
|
|
wire full_n, empty_n;
|
|
reg full_n_r, empty_n_r;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Memory Block
|
|
//
|
|
wire always_zero;
|
|
assign always_zero = 1'b0;
|
|
wire [`dw-1:0] junk_out;
|
|
|
|
wire [`dw-1:0] junk_in;
|
|
|
|
// manually assign
|
|
assign junk_in = 0;
|
|
|
|
dual_port_ram ram1(
|
|
.clk( clk ),
|
|
.addr1( rp ),
|
|
.addr2( wp ),
|
|
.we1( we ),
|
|
.we2( always_zero ),
|
|
.out1( doutz ),
|
|
.out2( junk_out ),
|
|
.data1( din ),
|
|
.data2 ( junk_in)
|
|
);
|
|
|
|
wire [`dw-1:0] doutz;
|
|
assign dout = (1'b1) ? doutz: junk_out;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Misc Logic
|
|
//
|
|
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) wp <= {4'b0000};
|
|
else
|
|
if(clr) wp <= {4'b0000};
|
|
else
|
|
if(we) wp <= wp_pl1;
|
|
end
|
|
assign wp_pl1 = wp + { {3'b000}, 1'b1};
|
|
assign wp_pl2 = wp + { {2'b00}, 2'b10};
|
|
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) rp <= {4'b0000};
|
|
else
|
|
if(clr) rp <= {4'b0000};
|
|
else
|
|
if(re) rp <= rp_pl1;
|
|
end
|
|
assign rp_pl1 = rp + { {3'b000}, 1'b1};
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Combinatorial Full & Empty Flags
|
|
//
|
|
|
|
assign empty = ((wp == rp) && !gb);
|
|
assign full = ((wp == rp) && gb);
|
|
|
|
// Guard Bit ...
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) gb <= 1'b0;
|
|
else
|
|
if(clr) gb <= 1'b0;
|
|
else
|
|
if((wp_pl1 == rp) && we) gb <= 1'b1;
|
|
else
|
|
if(re) gb <= 1'b0;
|
|
end
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Registered Full & Empty Flags
|
|
//
|
|
|
|
// Guard Bit ...
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) gb2 <= 1'b0;
|
|
else
|
|
if(clr) gb2 <= 1'b0;
|
|
else
|
|
if((wp_pl2 == rp) && we) gb2 <= 1'b1;
|
|
else
|
|
if((wp != rp) && re) gb2 <= 1'b0;
|
|
end
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) full_r <= 1'b0;
|
|
else
|
|
if(clr) full_r <= 1'b0;
|
|
else
|
|
if(we && ((wp_pl1 == rp) && gb2) && !re) full_r <= 1'b1;
|
|
else
|
|
if(re && ((wp_pl1 != rp) | !gb2) && !we) full_r <= 1'b0;
|
|
end
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) empty_r <= 1'b1;
|
|
else
|
|
if(clr) empty_r <= 1'b1;
|
|
else
|
|
if(we && ((wp != rp_pl1) | gb2) && !re) empty_r <= 1'b0;
|
|
else
|
|
if(re && ((wp == rp_pl1) && !gb2) && !we) empty_r <= 1'b1;
|
|
end
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Combinatorial Full_n && Empty_n Flags
|
|
//
|
|
|
|
assign empty_n = cnt < `n;
|
|
assign full_n = !(cnt < (`max_size-`n+1));
|
|
assign level = {{cnt[`aw]}, {cnt[`aw]}} | cnt[`aw-1:`aw-2];
|
|
|
|
// N entries status
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) cnt <= {4'b0000};
|
|
else
|
|
if(clr) cnt <= {4'b0000};
|
|
else
|
|
if( re && !we) cnt <= cnt + { 5'b11111};
|
|
else
|
|
if(!re && we) cnt <= cnt + { {4'b0000}, 1'b1};
|
|
end
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Registered Full_n && Empty_n Flags
|
|
//
|
|
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) empty_n_r <= 1'b1;
|
|
else
|
|
if(clr) empty_n_r <= 1'b1;
|
|
else
|
|
if(we && (cnt >= (`n-1) ) && !re) empty_n_r <= 1'b0;
|
|
else
|
|
if(re && (cnt <= `n ) && !we) empty_n_r <= 1'b1;
|
|
end
|
|
always @(posedge clk )
|
|
begin
|
|
if(!rst) full_n_r <= 1'b0;
|
|
else
|
|
if(clr) full_n_r <= 1'b0;
|
|
else
|
|
if(we && (cnt >= (`max_size-`n) ) && !re) full_n_r <= 1'b1;
|
|
else
|
|
if(re && (cnt <= (`max_size-`n+1)) && !we) full_n_r <= 1'b0;
|
|
end
|
|
endmodule
|
|
|
|
|