summaryrefslogtreecommitdiff
path: root/rtl/gfx
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-11-13 15:41:25 -0600
committerAlejandro Soto <alejandro@34project.org>2023-11-14 07:48:53 -0600
commitc8c488d4ef05300a2f8dfd6618fe9176a82a78ff (patch)
tree20554bb17e4c34dbffd02c100dcb0b9a76963c3a /rtl/gfx
parentb556c46542f1c6c51220eb51c961a2d2fd9fb687 (diff)
rtl/gfx: implement ROP render
Diffstat (limited to 'rtl/gfx')
-rw-r--r--rtl/gfx/gfx.sv23
-rw-r--r--rtl/gfx/gfx_rop.sv83
2 files changed, 103 insertions, 3 deletions
diff --git a/rtl/gfx/gfx.sv b/rtl/gfx/gfx.sv
index f2a9990..b127607 100644
--- a/rtl/gfx/gfx.sv
+++ b/rtl/gfx/gfx.sv
@@ -68,8 +68,6 @@ module gfx
gfx_clear clear
(
- .rop_mask_addr(),
- .rop_mask_assert(0),
.*
);
@@ -97,11 +95,30 @@ module gfx
.bary(frag_bary),
.in_ready(frag_ready),
.in_valid(funnel_valid),
- .out_ready(1), //TODO
+ .out_ready(rop_ready),
.out_valid(frag_valid),
.*
);
+ logic rop_mask_assert, rop_ready;
+ linear_coord rop_mask_addr;
+
+ gfx_rop rop
+ (
+ .in(frag_out),
+ .in_ready(rop_ready),
+ .in_valid(frag_valid),
+ .mask_addr(rop_mask_addr),
+ .mask_assert(rop_mask_assert),
+
+ .rop_write(),
+ .rop_address(),
+ .rop_writedata(),
+ .rop_waitrequest(0),
+
+ .*
+ );
+
logic scanout_read_tmp, vsync;
linear_coord scan_mask_addr;
diff --git a/rtl/gfx/gfx_rop.sv b/rtl/gfx/gfx_rop.sv
new file mode 100644
index 0000000..e055278
--- /dev/null
+++ b/rtl/gfx/gfx_rop.sv
@@ -0,0 +1,83 @@
+`include "gfx/gfx_defs.sv"
+
+module gfx_rop
+(
+ input logic clk,
+ rst_n,
+
+ input frag_paint in,
+ input logic in_valid,
+ output logic in_ready,
+
+ input logic rop_waitrequest,
+ output logic rop_write,
+ output logic[15:0] rop_writedata,
+ output half_coord rop_address,
+
+ output linear_coord mask_addr,
+ output logic mask_assert
+);
+
+ enum int unsigned
+ {
+ IDLE,
+ WRITE_LO,
+ WRITE_HI
+ } state;
+
+ logic hi;
+ frag_paint hold;
+ logic[15:0] color_hi, color_lo;
+
+ assign {color_hi, color_lo} = hold.color;
+
+ assign mask_addr = hold.addr;
+ assign rop_address = {hold.addr, hi};
+ assign rop_writedata = hi ? color_hi : color_lo;
+
+ always_comb begin
+ hi = 1'bx;
+ in_ready = 0;
+ rop_write = 0;
+ mask_assert = 0;
+
+ unique case (state)
+ IDLE:
+ in_ready = 1;
+
+ WRITE_LO: begin
+ hi = 0;
+ rop_write = 1;
+ mask_assert = 1;
+ end
+
+ WRITE_HI: begin
+ hi = 1;
+ in_ready = !rop_waitrequest;
+ rop_write = 1;
+ end
+ endcase
+ end
+
+ always_ff @(posedge clk or negedge rst_n)
+ if (!rst_n)
+ state <= IDLE;
+ else unique case (state)
+ IDLE:
+ if (in_valid)
+ state <= WRITE_LO;
+
+ WRITE_LO:
+ if (!rop_waitrequest)
+ state <= WRITE_HI;
+
+ WRITE_HI:
+ if (!rop_waitrequest)
+ state <= in_valid ? WRITE_LO : IDLE;
+ endcase
+
+ always_ff @(posedge clk)
+ if (in_ready)
+ hold <= in;
+
+endmodule