`timescale 1ns / 1ps
module modexpa7_simple_fifo #
(
parameter BUS_WIDTH = 128,
parameter DEPTH_BITS = 2
)
(
input clk,
input rst,
input wr_en,
input rd_en,
input [BUS_WIDTH-1:0] d_in,
output [BUS_WIDTH-1:0] d_out
);
//
// Locals
//
localparam NUM_WORDS = 2 ** DEPTH_BITS;
localparam [DEPTH_BITS:0] PTR_ZERO = {DEPTH_BITS{1'b0}};
localparam [DEPTH_BITS:0] PTR_LAST = {DEPTH_BITS{1'b1}};
//
// Memory
//
reg [BUS_WIDTH-1:0] fifo[0:NUM_WORDS-1];
//
// Pointers
//
reg [DEPTH_BITS-1:0] ptr_wr;
reg [DEPTH_BITS-1:0] ptr_rd;
//
// Output
//
reg [BUS_WIDTH-1:0] d_out_reg;
assign d_out = d_out_reg;
//
// Write Pointer
//
always @(posedge clk)
//
if (rst) ptr_wr <= PTR_ZERO;
else if (wr_en) ptr_wr <= ptr_wr + 1'b1;
//
// Read Pointer
//
always @(posedge clk)
//
if (rst) ptr_rd <= PTR_ZERO;
else if (rd_en) ptr_rd <= ptr_rd + 1'b1;
//
// Read Logic
//
always @(posedge clk)
//
if (rst) d_out_reg <= {BUS_WIDTH{1'b0}};
else if (rd_en) d_out_reg <= fifo[ptr_rd];
//
// Write Logic
//
always @(posedge clk)
//
if (!rst && wr_en) fifo[ptr_wr] <= d_in;
/*
generic_dpram #(aw,dw) u0(
.rclk( clk ),
.rrst( !rst ),
.rce( 1'b1 ),
.oe( 1'b1 ),
.raddr( rp ),
.do( dout ),
.wclk( clk ),
.wrst( !rst ),
.wce( 1'b1 ),
.we( we ),
.waddr( wp ),
.di( din )
);
////////////////////////////////////////////////////////////////////
//
// Misc Logic
//
always @(posedge clk `SC_FIFO_ASYNC_RESET)
if(!rst) wp <= #1 {aw{1'b0}};
else
if(clr) wp <= #1 {aw{1'b0}};
else
if(we) wp <= #1 wp_pl1;
assign wp_pl1 = wp + { {aw-1{1'b0}}, 1'b1};
assign wp_pl2 = wp + { {aw-2{1'b0}}, 2'b10};
always @(posedge clk `SC_FIFO_ASYNC_RESET)
if(!rst) rp <= #1 {aw{1'b0}};
else
if(clr) rp <= #1 {aw{1'b0}};
else
if(re) rp <= #1 rp_pl1;
assign rp_pl1 = rp + { {aw-1{1'b0}}, 1'b1};
////////////////////////////////////////////////////////////////////
//
// Combinatorial Full & Empty Flags
//
assign empty = ((wp == rp) & !gb);
assign full = ((wp == rp) & gb);
// Guard Bit ...
always @(posedge clk `SC_FIFO_ASYNC_RESET)
if(!rst) gb <= #1 1'b0;
else
if(clr) gb <= #1 1'b0;
else
if((wp_pl1 == rp) & we) gb <= #1 1'b1;
else
if(re) gb <= #1 1'b0;
////////////////////////////////////////////////////////////////////
//
// Registered Full & Empty Flags
//
// Guard Bit ...
always @(posedge clk `SC_FIFO_ASYNC_RESET)
if(!rst) gb2 <= #1 1'b0;
else
if(clr) gb2 <= #1 1'b0;
else
if((wp_pl2 == rp) & we) gb2 <= #1 1'b1;
else
if((wp != rp) & re) gb2 <= #1 1'b0;
always @(posedge clk `SC_FIFO_ASYNC_RESET)
if(!rst) full_r <= #1 1'b0;
else
if(clr) full_r <= #1 1'b0;
else
if(we & ((wp_pl1 == rp) & gb2) & !re) full_r <= #1 1'b1;
else
if(re & ((wp_pl1 != rp) | !gb2) & !we) full_r <= #1 1'b0;
always @(posedge clk `SC_FIFO_ASYNC_RESET)
if(!rst) empty_r <= #1 1'b1;
else
if(clr) empty_r <= #1 1'b1;
else
if(we & ((wp != rp_pl1) | gb2) & !re) empty_r <= #1 1'b0;
else
if(re & ((wp == rp_pl1) & !gb2) & !we) empty_r <= #1 1'b1;
////////////////////////////////////////////////////////////////////
//
// Combinatorial Full_n & Empty_n Flags
//
assign empty_n = cnt < n;
assign full_n = !(cnt < (max_size-n+1));
assign level = {2{cnt[aw]}} | cnt[aw-1:aw-2];
// N entries status
always @(posedge clk `SC_FIFO_ASYNC_RESET)
if(!rst) cnt <= #1 {aw+1{1'b0}};
else
if(clr) cnt <= #1 {aw+1{1'b0}};
else
if( re & !we) cnt <= #1 cnt + { {aw{1'b1}}, 1'b1};
else
if(!re & we) cnt <= #1 cnt + { {aw{1'b0}}, 1'b1};
////////////////////////////////////////////////////////////////////
//
// Registered Full_n & Empty_n Flags
//
always @(posedge clk `SC_FIFO_ASYNC_RESET)
if(!rst) empty_n_r <= #1 1'b1;
else
if(clr) empty_n_r <= #1 1'b1;
else
if(we & (cnt >= (n-1) ) & !re) empty_n_r <= #1 1'b0;
else
if(re & (cnt <= n ) & !we) empty_n_r <= #1 1'b1;
always @(posedge clk `SC_FIFO_ASYNC_RESET)
if(!rst) full_n_r <= #1 1'b0;
else
if(clr) full_n_r <= #1 1'b0;
else
if(we & (cnt >= (max_size-n) ) & !re) full_n_r <= #1 1'b1;
else
if(re & (cnt <= (max_size-n+1)) & !we) full_n_r <= #1 1'b0;
*/
endmodule