data/full_repos/permissive/204736068/SoM/RTL/misc/fifo_sync_shift.v
data/verilator_xmls/5883a7d0-8dd0-4615-a9cb-e735fb642fd6.xml
module fifo_sync_shift #(
	parameter integer DEPTH =  4,
	parameter integer WIDTH = 16
)(
	input  wire [WIDTH-1:0] wr_data,
	input  wire wr_ena,
	output wire wr_full,

	output wire [WIDTH-1:0] rd_data,
	input  wire rd_ena,
	output wire rd_empty,

	input  wire clk,
	input  wire rst
);




	wire  [DEPTH+1:0] ce;
	wire  [DEPTH+1:0] valid;
	wire  [WIDTH-1:0] data [DEPTH+1:0];






	genvar i;

	generate
		for (i=1; i<=DEPTH; i=i+1)
		begin : stage

			reg [WIDTH-1:0] l_data;
			reg l_valid;


			always @(posedge clk)
				if (ce[i])
					l_data <= valid[i+1] ? data[i+1] : wr_data;


			always @(posedge clk or posedge rst)
				if (rst)
					l_valid <= 1'b0;
				else if (ce[i])
					l_valid <= ~rd_ena | valid[i+1] | (wr_ena & valid[i]);


			assign ce[i] = rd_ena | (wr_ena & ~valid[i] & valid[i-1]);


			assign data[i]  = l_data;
			assign valid[i] = l_valid;
		end
	endgenerate


	assign data[DEPTH+1] = wr_data;
	assign data[0] = { WIDTH{1'bx} };

	assign valid[DEPTH+1] = 1'b0;
	assign valid[0] = 1'b1;

	assign ce[DEPTH+1] = 1'bx;
	assign ce[0] = 1'bx;





	assign wr_full = valid[DEPTH];

	assign rd_empty = ~valid[1];
	assign rd_data  = data[1];

endmodule
module fifo_sync_shift #(
	parameter integer DEPTH =  4,
	parameter integer WIDTH = 16
)(
	input  wire [WIDTH-1:0] wr_data,
	input  wire wr_ena,
	output wire wr_full,

	output wire [WIDTH-1:0] rd_data,
	input  wire rd_ena,
	output wire rd_empty,

	input  wire clk,
	input  wire rst
);





	wire  [DEPTH+1:0] ce;
	wire  [DEPTH+1:0] valid;
	wire  [WIDTH-1:0] data [DEPTH+1:0];






	genvar i;

	generate
		for (i=1; i<=DEPTH; i=i+1)
		begin : stage

			reg [WIDTH-1:0] l_data;
			reg l_valid;


			always @(posedge clk)
				if (ce[i])
					l_data <= valid[i+1] ? data[i+1] : wr_data;


			always @(posedge clk or posedge rst)
				if (rst)
					l_valid <= 1'b0;
				else if (ce[i])
					l_valid <= ~rd_ena | valid[i+1] | (wr_ena & valid[i]);


			assign ce[i] = rd_ena | (wr_ena & ~valid[i] & valid[i-1]);


			assign data[i]  = l_data;
			assign valid[i] = l_valid;
		end
	endgenerate


	assign data[DEPTH+1] = wr_data;
	assign data[0] = { WIDTH{1'bx} };

	assign valid[DEPTH+1] = 1'b0;
	assign valid[0] = 1'b1;

	assign ce[DEPTH+1] = 1'bx;
	assign ce[0] = 1'bx;





	assign wr_full = valid[DEPTH];

	assign rd_empty = ~valid[1];
	assign rd_data  = data[1];

endmodule