summaryrefslogtreecommitdiff
path: root/rtl/legacy_gfx/gfx_cmd.sv
blob: 29b6e2177631e19477c5149f1577aedd48658279 (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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
`include "gfx/gfx_defs.sv"

module gfx_cmd
(
	input  logic    clk,
	                rst_n,

	input  cmd_addr cmd_address,
	input  logic    cmd_read,
	                cmd_write,
	input  cmd_word cmd_writedata,
	output cmd_word cmd_readdata,

	input  logic    vsync,

	output logic    swap_buffers,
	                enable_clear,
	                start_clear,
	output rgb24    clear_color,

	output logic    program_start,
	output cmd_word program_header_base,
	                program_header_size,

	output cmd_word fb_base_a,
	                fb_base_b
);

	rgb24 next_clear_color;
	logic do_start_clear, next_start_clear, next_enable_clear, next_swap_buffers;

	struct packed
	{
		logic[4:0] mbz;
		logic      start_frame,
		           enable_clear,
		           swap_buffers;
		rgb24      clear_color;
	} readdata_scan, writedata_scan;

	assign cmd_readdata = readdata_scan;

	assign writedata_scan = cmd_writedata;
	assign readdata_scan.mbz = 0;
	assign readdata_scan.clear_color = clear_color;
	assign readdata_scan.enable_clear = enable_clear;
	assign readdata_scan.swap_buffers = swap_buffers;

	assign do_start_clear = writedata_scan.start_frame && writedata_scan.enable_clear;

	always_ff @(posedge clk or negedge rst_n)
		if (!rst_n) begin
			start_clear <= 0;
			enable_clear <= 0;
			swap_buffers <= 0;

			next_start_clear <= 0;
			next_enable_clear <= 0;
			next_swap_buffers <= 0;

			program_start <= 0;

			fb_base_a <= 0;
			fb_base_b <= 0;
		end else begin
			start_clear <= 0;
			program_start <= 0;

			if (vsync) begin
				start_clear <= next_start_clear;
				enable_clear <= next_enable_clear;
				swap_buffers <= next_swap_buffers;

				next_start_clear <= 0;
			end

			if (cmd_write)
				unique case (cmd_address[2:0])
					`GFX_CMD_REG_ID: ;

					`GFX_CMD_REG_SCAN: begin
						next_enable_clear <= writedata_scan.enable_clear;
						next_swap_buffers <= writedata_scan.swap_buffers;

						if (!next_start_clear)
							next_start_clear <= do_start_clear;
					end

					`GFX_CMD_REG_HEADER_BASE: ;

					`GFX_CMD_REG_HEADER_SIZE:
						program_start <= 1;

					`GFX_CMD_REG_FB_BASE_A:
						fb_base_a <= cmd_writedata;
	
					`GFX_CMD_REG_FB_BASE_B:
						fb_base_b <= cmd_writedata;

					default: ;
				endcase
		end

	always_ff @(posedge clk) begin
		if (vsync)
			clear_color <= next_clear_color;

		if (cmd_write)
			unique case (cmd_address[2:0])
				`GFX_CMD_REG_ID: ;

				`GFX_CMD_REG_SCAN:
					next_clear_color <= writedata_scan.clear_color;

				`GFX_CMD_REG_HEADER_BASE:
					program_header_base <= cmd_writedata;

				`GFX_CMD_REG_HEADER_SIZE:
					program_header_size <= cmd_writedata;

				default: ;
			endcase
	end

endmodule