summaryrefslogtreecommitdiff
path: root/rtl/legacy_gfx/gfx_fifo.sv
blob: e9fa8f5c0ec5a61dccdd774cdc627318d9b9d46f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
module gfx_fifo
#(parameter WIDTH=0, DEPTH=0)
(
	input  logic              clk,
	                          rst_n,

	input  logic[WIDTH - 1:0] in,
	input  logic              in_valid,
	output logic              in_ready,

	input  logic              out_ready,
	output logic              out_valid,
	output logic[WIDTH - 1:0] out
);

	logic do_read, do_write, full_if_eq, in_stall, out_stall,
	      may_read, may_write, read, read_ok, write;

	logic[WIDTH - 1:0] fifo[DEPTH], read_data, write_data;
	logic[$clog2(DEPTH) - 1:0] read_ptr, write_ptr;

	assign do_read = read && may_read;
	assign do_write = write && may_write;

	always_comb begin
		may_read = full_if_eq;
		may_write = !full_if_eq;

		if (read)
			may_write = 1;

		if (read_ptr != write_ptr) begin
			may_read = 1;
			may_write = 1;
		end
	end

	gfx_skid_flow in_flow
	(
		.stall(in_stall),
		.out_ready(may_write),
		.out_valid(write),
		.*
	);

	gfx_skid_flow out_flow
	(
		.stall(out_stall),
		.in_ready(read),
		.in_valid(read_ok),
		.*
	);

	gfx_skid_buf #(.WIDTH(WIDTH)) in_skid
	(
		.out(write_data),
		.stall(in_stall),
		.*
	);

	gfx_skid_buf #(.WIDTH(WIDTH)) out_skid
	(
		.in(read_data),
		.stall(out_stall),
		.*
	);

	always_ff @(posedge clk or negedge rst_n)
		if (!rst_n) begin
			read_ok <= 0;
			read_ptr <= 0;
			write_ptr <= 0;
			full_if_eq <= 0;
		end else begin
			if (!out_stall)
				read_ok <= read && may_read;

			if (do_read)
				read_ptr <= read_ptr + 1;

			if (do_write)
				write_ptr <= write_ptr + 1;

			if (do_read && !do_write)
				full_if_eq <= 0;
			else if (!do_read && do_write)
				full_if_eq <= 1;
		end

	always_ff @(posedge clk) begin
		if (!out_stall)
			read_data <= fifo[read_ptr];

		if (may_write)
			fifo[write_ptr] <= write_data;
	end

endmodule