diff options
| author | Alejandro Soto <alejandro@34project.org> | 2023-10-29 18:59:33 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2023-10-29 19:48:23 -0600 |
| commit | eed877444f9af85d6e4596853d8f188e61f6c4ed (patch) | |
| tree | 53f54a96b006f4a3d0fa952292408e7d63f81a61 /rtl | |
| parent | adabbf5f30729092a64fa1059bbc7d7b09d6b24e (diff) | |
rtl/gfx: implement scanout command interface
Diffstat (limited to '')
| -rw-r--r-- | rtl/gfx/gfx.sv | 94 | ||||
| -rw-r--r-- | rtl/gfx/gfx_cmd.sv | 68 | ||||
| -rw-r--r-- | rtl/gfx/gfx_scanout.sv | 19 |
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 |
