diff options
Diffstat (limited to 'rtl')
| -rw-r--r-- | rtl/gfx/gfx.sv | 28 | ||||
| -rw-r--r-- | rtl/gfx/gfx_assembly.sv | 89 |
2 files changed, 109 insertions, 8 deletions
diff --git a/rtl/gfx/gfx.sv b/rtl/gfx/gfx.sv index 32364b3..10f4473 100644 --- a/rtl/gfx/gfx.sv +++ b/rtl/gfx/gfx.sv @@ -50,15 +50,19 @@ module gfx gfx_sp sp ( - .send_ready(1), //TODO .* ); - logic frag_mask, scan_mask; + logic send_ready, assembly_valid; + fp_xyzw assembly_vertex_a, assembly_vertex_b, assembly_vertex_c; - gfx_masks masks + gfx_assembly assembly ( - .frag_mask_read_addr(), + .out_ready(fix_ready), + .out_valid(assembly_valid), + .out_vertex_a(assembly_vertex_a), + .out_vertex_b(assembly_vertex_b), + .out_vertex_c(assembly_vertex_c), .* ); @@ -68,12 +72,12 @@ module gfx gfx_fix_floats fix ( .in_ready(fix_ready), - .in_valid(0), //TODO + .in_valid(assembly_valid), .out_ready(persp_ready), .out_valid(fix_valid), - .in_vertex_a(), //TODO - .in_vertex_b(), //TODO - .in_vertex_c(), //TODO + .in_vertex_a(assembly_vertex_a), + .in_vertex_b(assembly_vertex_b), + .in_vertex_c(assembly_vertex_c), .out_vertex_a(fix_vertex_a), .out_vertex_b(fix_vertex_b), .out_vertex_c(fix_vertex_c), @@ -119,6 +123,14 @@ module gfx .* ); + logic frag_mask, scan_mask; + + gfx_masks masks + ( + .frag_mask_read_addr(), + .* + ); + logic frag_mask_set, frag_mask_write, frag_wait; linear_coord frag_mask_write_addr; diff --git a/rtl/gfx/gfx_assembly.sv b/rtl/gfx/gfx_assembly.sv new file mode 100644 index 0000000..1a909be --- /dev/null +++ b/rtl/gfx/gfx_assembly.sv @@ -0,0 +1,89 @@ +`include "gfx/gfx_defs.sv" + +module gfx_assembly +( + input logic clk, + rst_n, + + input lane_word send_data, + input lane_mask send_mask, + input logic send_valid, + output logic send_ready, + + input logic out_ready, + output logic out_valid, + output fp_xyzw out_vertex_a, + out_vertex_b, + out_vertex_c +); + + localparam SETS_PER_TRI = 6; + + mat4 sets[SETS_PER_TRI]; + logic assemble_next, permit_out; + lane_mask current_mask, next_mask; + logic[1:0] out_lane; + logic[2:0] set_num; + + enum int unsigned + { + GET_LANES, + ASSEMBLE + } state; + + assign out_valid = permit_out && current_mask[out_lane]; + assign out_vertex_a = sets[0][out_lane]; + assign out_vertex_b = sets[2][out_lane]; + assign out_vertex_c = sets[4][out_lane]; + + assign next_mask = current_mask & send_mask; + assign assemble_next = !current_mask[out_lane] || out_ready; + + always_ff @(posedge clk or negedge rst_n) + if (!rst_n) begin + state <= GET_LANES; + set_num <= 0; + out_lane <= 0; + permit_out <= 0; + send_ready <= 1; + current_mask <= {($bits(current_mask)){1'b1}}; + end else unique case (state) + GET_LANES: + if (send_valid) begin + set_num <= set_num + 1; + current_mask <= next_mask; + + if (set_num == SETS_PER_TRI - 1) begin + state <= ASSEMBLE; + permit_out <= 1; + send_ready <= 0; + end + + if (!(|next_mask)) begin + state <= GET_LANES; + set_num <= 0; + current_mask <= {($bits(current_mask)){1'b1}}; + end + end + + ASSEMBLE: + if (assemble_next) begin + out_lane <= out_lane + 1; + if (&out_lane) begin + state <= GET_LANES; + permit_out <= 0; + send_ready <= 1; + end + end + endcase + + always_ff @(posedge clk) + unique case (state) + GET_LANES: + if (send_valid) + sets[set_num] <= send_data; + + ASSEMBLE: ; + endcase + +endmodule |
