aboutsummaryrefslogblamecommitdiff
path: root/src/rtl/modexpa7_simple_fifo.v
blob: 1580e38b686b152386557e15ea6f616eb8b4df7c (plain) (tree)


























                                                                                            
                                     





















































































































































































                                                                                       
`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
		//
	(* RAM_STYLE="DISTRIBUTED" *)
	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