data/full_repos/permissive/48602886/synth/de0-cv/src/sdramc/sdram_sync_fifo.v
data/verilator_xmls/c2921542-b239-47ab-901e-86fd6b1d4b41.xml
module sdram_sync_fifo
	#(
		parameter N = 16,
		parameter DEPTH = 4,
		parameter D_N = 2
	)	
	(

		input iCLOCK,
		input inRESET,
		input iREMOVE,

		output [D_N-1:0] oCOUNT,

		input iWR_EN,
		input [N-1:0] iWR_DATA,
		output oWR_FULL,
		output oWR_ALMOST_FULL,

		input iRD_EN,
		output [N-1:0] oRD_DATA,
		output oRD_EMPTY,
		output oRD_ALMOST_EMPTY
	);
	

	wire [D_N:0] count, almost_full_count;
	
	wire full = count[D_N];
	wire empty = (count == {D_N+1{1'b0}})? 1'b1 : 1'b0;
	wire almost_full = full || (count[D_N-1:0] == {D_N{1'b1}});
	wire almost_empty = empty || (count[D_N:0] == {{D_N{1'b0}}, 1'b1});
	

	reg [D_N:0] b_write_pointer;
	reg [D_N:0] b_read_pointer;
	reg [N-1:0] b_memory [0 : DEPTH-1];
	
	assign count = b_write_pointer - b_read_pointer;
	assign almost_full_count = (b_write_pointer + {{D_N{1'b0}}, 1'b1}) - b_read_pointer;
	
	always@(posedge iCLOCK or negedge inRESET)begin
		if(!inRESET)begin
			b_write_pointer <= {D_N+1{1'b0}};
			b_read_pointer <= {D_N+1{1'b0}};
		end
		else if(iREMOVE)begin
			b_write_pointer <= {D_N+1{1'b0}};
			b_read_pointer <= {D_N+1{1'b0}};
		end
		else begin
			if(iWR_EN)begin
				b_write_pointer <= b_write_pointer + {{D_N-1{1'b0}}, 1'b1};
				b_memory [b_write_pointer[D_N-1:0]] <= iWR_DATA;
			end
			if(iRD_EN)begin
				b_read_pointer <= b_read_pointer + {{D_N-1{1'b0}}, 1'b1};
			end
		end
	end
	

	assign oRD_DATA = b_memory	[b_read_pointer[D_N-1:0]];
	assign oRD_EMPTY = (count == {D_N+1{1'b0}})? 1'b1 : 1'b0;
	assign oRD_ALMOST_EMPTY = (count == {D_N+1{1'b0}} || count == {{D_N{1'b0}}, 1'b1})? 1'b1 : 1'b0;
	
	assign oWR_FULL = count[D_N];
	assign oWR_ALMOST_FULL = almost_full_count[D_N] || count[D_N];
	assign oCOUNT = count [D_N-1:0];
	
endmodule
module sdram_sync_fifo
	#(
		parameter N = 16,
		parameter DEPTH = 4,
		parameter D_N = 2
	)	
	(

		input iCLOCK,
		input inRESET,
		input iREMOVE,

		output [D_N-1:0] oCOUNT,

		input iWR_EN,
		input [N-1:0] iWR_DATA,
		output oWR_FULL,
		output oWR_ALMOST_FULL,

		input iRD_EN,
		output [N-1:0] oRD_DATA,
		output oRD_EMPTY,
		output oRD_ALMOST_EMPTY
	);

	

	wire [D_N:0] count, almost_full_count;
	
	wire full = count[D_N];
	wire empty = (count == {D_N+1{1'b0}})? 1'b1 : 1'b0;
	wire almost_full = full || (count[D_N-1:0] == {D_N{1'b1}});
	wire almost_empty = empty || (count[D_N:0] == {{D_N{1'b0}}, 1'b1});
	

	reg [D_N:0] b_write_pointer;
	reg [D_N:0] b_read_pointer;
	reg [N-1:0] b_memory [0 : DEPTH-1];
	
	assign count = b_write_pointer - b_read_pointer;
	assign almost_full_count = (b_write_pointer + {{D_N{1'b0}}, 1'b1}) - b_read_pointer;
	
	always@(posedge iCLOCK or negedge inRESET)begin
		if(!inRESET)begin
			b_write_pointer <= {D_N+1{1'b0}};
			b_read_pointer <= {D_N+1{1'b0}};
		end
		else if(iREMOVE)begin
			b_write_pointer <= {D_N+1{1'b0}};
			b_read_pointer <= {D_N+1{1'b0}};
		end
		else begin
			if(iWR_EN)begin
				b_write_pointer <= b_write_pointer + {{D_N-1{1'b0}}, 1'b1};
				b_memory [b_write_pointer[D_N-1:0]] <= iWR_DATA;
			end
			if(iRD_EN)begin
				b_read_pointer <= b_read_pointer + {{D_N-1{1'b0}}, 1'b1};
			end
		end
	end
	

	assign oRD_DATA = b_memory	[b_read_pointer[D_N-1:0]];
	assign oRD_EMPTY = (count == {D_N+1{1'b0}})? 1'b1 : 1'b0;
	assign oRD_ALMOST_EMPTY = (count == {D_N+1{1'b0}} || count == {{D_N{1'b0}}, 1'b1})? 1'b1 : 1'b0;
	
	assign oWR_FULL = count[D_N];
	assign oWR_ALMOST_FULL = almost_full_count[D_N] || count[D_N];
	assign oCOUNT = count [D_N-1:0];
	
endmodule