summaryrefslogtreecommitdiff
path: root/rtl/gfx
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-10-29 18:59:33 -0600
committerAlejandro Soto <alejandro@34project.org>2023-10-29 19:48:23 -0600
commiteed877444f9af85d6e4596853d8f188e61f6c4ed (patch)
tree53f54a96b006f4a3d0fa952292408e7d63f81a61 /rtl/gfx
parentadabbf5f30729092a64fa1059bbc7d7b09d6b24e (diff)
rtl/gfx: implement scanout command interface
Diffstat (limited to 'rtl/gfx')
-rw-r--r--rtl/gfx/gfx.sv94
-rw-r--r--rtl/gfx/gfx_cmd.sv68
-rw-r--r--rtl/gfx/gfx_scanout.sv19
3 files changed, 85 insertions, 96 deletions
diff --git a/rtl/gfx/gfx.sv b/rtl/gfx/gfx.sv
index 7749c50..fcaaffb 100644
--- a/rtl/gfx/gfx.sv
+++ b/rtl/gfx/gfx.sv
@@ -26,43 +26,11 @@ module gfx
output rgb30 scan_data
);
- fp readdata, writedata;
- mat4 a, b, q, hold_q;
- logic start, done;
-
- assign mem_read = 1;
- assign mem_write = 0;
-
- assign readdata = hold_q[cmd_address[3:2]][cmd_address[1:0]];
- assign writedata = cmd_writedata[`FLOAT_BITS - 1:0];
-
- always_comb begin
- if (!cmd_address[5])
- cmd_readdata = {{($bits(cmd_readdata) - `FLOAT_BITS){1'b0}}, readdata};
- else if (cmd_address[4])
- cmd_readdata = cmd_address[0] ? cnt_done : cnt_start;
- else
- unique case (cmd_address[1:0])
- 2'b00:
- cmd_readdata = snp_trans[31:0];
-
- 2'b01:
- cmd_readdata = snp_trans[63:32];
-
- 2'b10:
- cmd_readdata = snp_cycles[31:0];
-
- 2'b11:
- cmd_readdata = snp_cycles[63:32];
- endcase
- end
+ logic enable_clear, swap_buffers;
+ rgb24 clear_color;
- mat_mat_mul mul
+ gfx_cmd cmd
(
- .in_ready(),
- .in_valid(start),
- .out_ready(1),
- .out_valid(done),
.*
);
@@ -77,18 +45,9 @@ module gfx
.*
);
- logic swap_buffers;
- rgb24 clear_color;
-
- assign swap_buffers = 0;
- assign clear_color.r = 255;
- assign clear_color.g = 0;
- assign clear_color.b = 0;
-
+ logic scanout_read_tmp, vsync;
linear_coord scan_mask_addr;
- logic scanout_read_tmp;
-
gfx_scanout scanout
(
.mask(scan_mask),
@@ -103,49 +62,4 @@ module gfx
.*
);
- logic[63:0] cnt_cycles, cnt_trans, snp_cycles, snp_trans;
- logic[24:0] cnt_addr;
- logic[31:0] cnt_done, cnt_start;
- assign mem_address = {cnt_addr, 1'b0};
-
- always_ff @(posedge clk) begin
- if (cmd_write) begin
- if (cmd_address[4])
- b[cmd_address[3:2]][cmd_address[1:0]] <= writedata;
- else
- a[cmd_address[3:2]][cmd_address[1:0]] <= writedata;
-
- snp_trans <= cnt_trans;
- snp_cycles <= cnt_cycles;
- end
-
- if (done)
- hold_q <= q;
- end
-
- always_ff @(posedge clk or negedge rst_n)
- if (!rst_n) begin
- start <= 0;
- cnt_addr <= 0;
- cnt_trans <= 0;
- cnt_cycles <= 0;
- cnt_done <= 0;
- cnt_start <= 0;
- end else begin
- start <= cmd_write;
- cnt_cycles <= cnt_cycles + 1;
-
- if (start)
- cnt_start <= cnt_start + 1;
-
- if (done)
- cnt_done <= cnt_done + 1;
-
- if (!mem_waitrequest)
- cnt_addr <= cnt_addr + 1;
-
- if (mem_readdatavalid)
- cnt_trans <= cnt_trans + 1;
- end
-
endmodule
diff --git a/rtl/gfx/gfx_cmd.sv b/rtl/gfx/gfx_cmd.sv
new file mode 100644
index 0000000..424cf5d
--- /dev/null
+++ b/rtl/gfx/gfx_cmd.sv
@@ -0,0 +1,68 @@
+`include "gfx/gfx_defs.sv"
+
+module gfx_cmd
+(
+ input logic clk,
+ rst_n,
+
+ input logic[5:0] cmd_address,
+ input logic cmd_read,
+ cmd_write,
+ input logic[31:0] cmd_writedata,
+ output logic[31:0] cmd_readdata,
+
+ input logic vsync,
+
+ output logic swap_buffers,
+ enable_clear,
+ output rgb24 clear_color
+);
+
+ struct packed
+ {
+ logic[5:0] mbz;
+ logic enable_clear,
+ swap_buffers;
+ rgb24 clear_color;
+ } readdata_scan, writedata_scan;
+
+ assign readdata_scan.clear_color = clear_color;
+ assign readdata_scan.mbz = 0;
+ assign readdata_scan.enable_clear = enable_clear;
+ assign readdata_scan.swap_buffers = swap_buffers;
+
+ assign writedata_scan = cmd_writedata;
+
+ assign cmd_readdata = readdata_scan;
+
+ rgb24 next_clear_color;
+ logic next_enable_clear, next_swap_buffers;
+
+ always_ff @(posedge clk or negedge rst_n)
+ if (!rst_n) begin
+ enable_clear <= 0;
+ swap_buffers <= 0;
+
+ next_enable_clear <= 0;
+ next_swap_buffers <= 0;
+ end else begin
+ if (vsync) begin
+ enable_clear <= next_enable_clear;
+ swap_buffers <= next_swap_buffers;
+ end
+
+ if (cmd_write) begin
+ next_enable_clear <= writedata_scan.enable_clear;
+ next_swap_buffers <= writedata_scan.swap_buffers;
+ end
+ end
+
+ always_ff @(posedge clk) begin
+ if (vsync)
+ clear_color <= next_clear_color;
+
+ if (cmd_write)
+ next_clear_color <= writedata_scan.clear_color;
+ end
+
+endmodule
diff --git a/rtl/gfx/gfx_scanout.sv b/rtl/gfx/gfx_scanout.sv
index 7d2346b..c549782 100644
--- a/rtl/gfx/gfx_scanout.sv
+++ b/rtl/gfx/gfx_scanout.sv
@@ -5,6 +5,7 @@ module gfx_scanout
input logic clk,
rst_n,
+ input logic enable_clear,
input rgb24 clear_color,
input logic mask,
@@ -20,7 +21,9 @@ module gfx_scanout
output logic scan_valid,
scan_endofpacket,
scan_startofpacket,
- output rgb30 scan_data
+ output rgb30 scan_data,
+
+ output logic vsync
);
logic[`GFX_SCAN_STAGES:0] fb_ready, fb_valid, src_ready, src_valid, src_pipes;
@@ -28,7 +31,7 @@ module gfx_scanout
logic[`GFX_MASK_STAGES - 1:0] request_valid;
logic[$clog2(`GFX_SCAN_STAGES) - 1:0] queued;
- logic foreground, foreground_valid, partial, put_fb_valid, put_src_valid,
+ logic effective_mask, foreground, foreground_valid, partial, put_fb_valid, put_src_valid,
queued_dec, queued_inc, read_half, read_valid, request_flush;
rgb24 fb_pipes[`GFX_SCAN_STAGES + 1], scan_pixel;
@@ -61,10 +64,11 @@ module gfx_scanout
assign read_half = request_pos[`GFX_MASK_STAGES - 1][0];
assign read_valid = request_valid[`GFX_MASK_STAGES - 1];
- assign request_flush = (fb_read && fb_waitrequest) || (src_valid[0] && !src_ready[0]) || queued == `GFX_SCAN_STAGES;
+ assign request_flush = (fb_read && fb_waitrequest) || (src_valid[0] && !src_ready[0]) || queued == `GFX_SCAN_STAGES || vsync;
- assign queued_inc = !request_flush && read_valid && read_half && mask;
+ assign queued_inc = !request_flush && read_valid && read_half && effective_mask;
assign queued_dec = fb_ready[`GFX_SCAN_STAGES - 1] && fb_valid[`GFX_SCAN_STAGES - 1];
+ assign effective_mask = mask || !enable_clear;
genvar i;
generate
@@ -109,6 +113,7 @@ module gfx_scanout
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) begin
+ vsync <= 0;
queued <= 0;
read_pos <= 0;
@@ -146,12 +151,14 @@ module gfx_scanout
put_src_valid <= 0;
if (!request_flush) begin
- fb_read <= read_valid && mask;
+ fb_read <= read_valid && effective_mask;
put_src_valid <= read_valid && read_half;
if (read_valid)
commit_pos <= request_pos[`GFX_MASK_STAGES - 1];
end
+
+ vsync <= !vsync && !request_flush && read_valid && request_pos[`GFX_MASK_STAGES - 1] == {last_pos, 1'b1};
end
always_ff @(posedge clk) begin
@@ -159,7 +166,7 @@ module gfx_scanout
if (!request_flush) begin
fb_address <= request_pos[`GFX_MASK_STAGES - 1];
- src_pipes[0] <= mask;
+ src_pipes[0] <= effective_mask;
end
if (fb_readdatavalid) begin