data/full_repos/permissive/450072296/verilog/rtl/audiodac_fifo.v
data/verilator_xmls/c23d7ab2-aca1-4a65-8954-ffbcba7f7ff4.xml
module audiodac_fifo
	#(parameter AUDIO_WIDTH=16, FIFO_SIZE=9, FIFO_ASYNC=1) (


	input 		[AUDIO_WIDTH-1:0]	fifo_data_i,
	input					fifo_rdy_i,



	output reg				fifo_ack_o,
	output wire				fifo_full_o,
	output wire				fifo_empty_o,

	output wire	[AUDIO_WIDTH-1:0]	audio_data_o,
	input					audio_rd_i,
	
	input					rst_n_i,
	input					clk_i,

	input					tst_fifo_loop_i
);

	reg		[FIFO_SIZE-1:0]		read_ptr, write_ptr;
	wire		[FIFO_SIZE-1:0]		next_write;
	reg		[AUDIO_WIDTH-1:0]	fifo_reg[0:(1<<FIFO_SIZE)-1];


	reg     				fifo_rdy_del1, fifo_rdy_del2;
	reg		[AUDIO_WIDTH-1:0]	fifo_data_del1, fifo_data_del2;


	assign fifo_full_o = (next_write === read_ptr);
	assign fifo_empty_o = (write_ptr === read_ptr);

	assign audio_data_o = fifo_reg[read_ptr];
	assign next_write = write_ptr + 1'b1;

	wire _fifo_rdy = FIFO_ASYNC ? fifo_rdy_del2 : fifo_rdy_i;
	wire [AUDIO_WIDTH-1:0] _fifo_data = FIFO_ASYNC ? fifo_data_del2 : fifo_data_i;

	always @(posedge clk_i) begin
		if (!rst_n_i) begin

			fifo_ack_o <= 1'b0;
			read_ptr <= {FIFO_SIZE{1'b0}};
			write_ptr <= {FIFO_SIZE{1'b0}};




              		fifo_reg[0] <= {1'b1,{(AUDIO_WIDTH-1){1'b0}}};

			fifo_rdy_del1 <= 1'b0;
			fifo_rdy_del2 <= 1'b0;
			fifo_data_del1 <= {AUDIO_WIDTH{1'b0}};
			fifo_data_del2 <= {AUDIO_WIDTH{1'b0}};
		end else begin

                       	fifo_rdy_del2 <= fifo_rdy_del1;
                       	fifo_rdy_del1 <= fifo_rdy_i;

                       	fifo_data_del2 <= fifo_data_del1;
                       	fifo_data_del1 <= fifo_data_i;




			if (audio_rd_i && (!fifo_empty_o || tst_fifo_loop_i))
				read_ptr <= read_ptr + 1'b1;
		




			if (_fifo_rdy && !fifo_ack_o && !fifo_full_o) begin
				write_ptr <= next_write;
				fifo_reg[next_write] <= _fifo_data;
				fifo_ack_o <= 1'b1;
			end

			if (!_fifo_rdy)
				fifo_ack_o <= 1'b0;
		end
	end

endmodule
module audiodac_fifo
	#(parameter AUDIO_WIDTH=16, FIFO_SIZE=9, FIFO_ASYNC=1) (


	input 		[AUDIO_WIDTH-1:0]	fifo_data_i,
	input					fifo_rdy_i,



	output reg				fifo_ack_o,
	output wire				fifo_full_o,
	output wire				fifo_empty_o,

	output wire	[AUDIO_WIDTH-1:0]	audio_data_o,
	input					audio_rd_i,
	
	input					rst_n_i,
	input					clk_i,

	input					tst_fifo_loop_i
);


	reg		[FIFO_SIZE-1:0]		read_ptr, write_ptr;
	wire		[FIFO_SIZE-1:0]		next_write;
	reg		[AUDIO_WIDTH-1:0]	fifo_reg[0:(1<<FIFO_SIZE)-1];


	reg     				fifo_rdy_del1, fifo_rdy_del2;
	reg		[AUDIO_WIDTH-1:0]	fifo_data_del1, fifo_data_del2;


	assign fifo_full_o = (next_write === read_ptr);
	assign fifo_empty_o = (write_ptr === read_ptr);

	assign audio_data_o = fifo_reg[read_ptr];
	assign next_write = write_ptr + 1'b1;

	wire _fifo_rdy = FIFO_ASYNC ? fifo_rdy_del2 : fifo_rdy_i;
	wire [AUDIO_WIDTH-1:0] _fifo_data = FIFO_ASYNC ? fifo_data_del2 : fifo_data_i;

	always @(posedge clk_i) begin
		if (!rst_n_i) begin

			fifo_ack_o <= 1'b0;
			read_ptr <= {FIFO_SIZE{1'b0}};
			write_ptr <= {FIFO_SIZE{1'b0}};




              		fifo_reg[0] <= {1'b1,{(AUDIO_WIDTH-1){1'b0}}};

			fifo_rdy_del1 <= 1'b0;
			fifo_rdy_del2 <= 1'b0;
			fifo_data_del1 <= {AUDIO_WIDTH{1'b0}};
			fifo_data_del2 <= {AUDIO_WIDTH{1'b0}};
		end else begin

                       	fifo_rdy_del2 <= fifo_rdy_del1;
                       	fifo_rdy_del1 <= fifo_rdy_i;

                       	fifo_data_del2 <= fifo_data_del1;
                       	fifo_data_del1 <= fifo_data_i;




			if (audio_rd_i && (!fifo_empty_o || tst_fifo_loop_i))
				read_ptr <= read_ptr + 1'b1;
		




			if (_fifo_rdy && !fifo_ack_o && !fifo_full_o) begin
				write_ptr <= next_write;
				fifo_reg[next_write] <= _fifo_data;
				fifo_ack_o <= 1'b1;
			end

			if (!_fifo_rdy)
				fifo_ack_o <= 1'b0;
		end
	end

endmodule