diff options
| author | Alejandro Soto <alejandro@34project.org> | 2023-11-17 14:18:29 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2023-11-17 15:46:12 -0600 |
| commit | 7275f342f2b8d97ae02e0e51011442f063660b5d (patch) | |
| tree | 068070bb7cbcd6b4084fd9235b78c62494c60827 /rtl/gfx/gfx_scanout_dac.sv | |
| parent | b11e2758446ac82328a8c410d38b80174dc3a1ed (diff) | |
rtl/gfx; rewrite scanout
Diffstat (limited to 'rtl/gfx/gfx_scanout_dac.sv')
| -rw-r--r-- | rtl/gfx/gfx_scanout_dac.sv | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/rtl/gfx/gfx_scanout_dac.sv b/rtl/gfx/gfx_scanout_dac.sv new file mode 100644 index 0000000..c8fe218 --- /dev/null +++ b/rtl/gfx/gfx_scanout_dac.sv @@ -0,0 +1,116 @@ +`include "gfx/gfx_defs.sv" + +module gfx_scanout_dac +( + input logic clk, + rst_n, + + input logic enable_clear, + input rgb24 clear_color, + + input logic mask_fifo_out, + input mem_word fb_fifo_out, + input logic in_valid, + output logic in_ready, + + input logic scan_ready, + output logic scan_valid, + scan_endofpacket, + scan_startofpacket, + output rgb30 scan_data, + + output logic vsync +); + + logic dac_valid, half, half_mask, stall, endofpacket, startofpacket; + rgb24 pixel; + rgb32 fifo_pixel; + mem_word msw, lsw; + half_coord next_addr; + linear_coord max_addr, pixel_addr; + + struct packed + { + logic endofpacket, + startofpacket; + rgb30 pixel; + } skid_in, skid_out; + + assign scan_data = skid_out.pixel; + assign scan_endofpacket = skid_out.endofpacket; + assign scan_startofpacket = skid_out.startofpacket; + + assign max_addr = `GFX_X_RES * `GFX_Y_RES - 1; + + function color10 dac_color(color8 in); + dac_color = {in, {2{in[0]}}}; + endfunction + + assign fifo_pixel = {msw, lsw}; + assign skid_in.pixel.r = dac_color(pixel.r); + assign skid_in.pixel.g = dac_color(pixel.g); + assign skid_in.pixel.b = dac_color(pixel.b); + assign skid_in.endofpacket = endofpacket; + assign skid_in.startofpacket = startofpacket; + + always_comb begin + // Descarta fifo_pixel.a + pixel.r = fifo_pixel.r; + pixel.g = fifo_pixel.g; + pixel.b = fifo_pixel.b; + + if (!half_mask) + pixel = clear_color; + end + + gfx_skid_flow flow + ( + .in_valid(dac_valid), + .out_ready(scan_ready), + .out_valid(scan_valid), + .* + ); + + gfx_skid_buf #(.WIDTH($bits(skid_in))) skid + ( + .in(skid_in), + .out(skid_out), + .* + ); + + always_ff @(posedge clk or negedge rst_n) + if (!rst_n) begin + half <= 0; + vsync <= 0; + dac_valid <= 0; + pixel_addr <= 0; + end else begin + vsync <= 0; + if (in_ready && dac_valid) begin + vsync <= scan_endofpacket; + dac_valid <= 0; + end + + if (in_ready && in_valid) begin + half <= !half; + dac_valid <= half; + + if (half) begin + pixel_addr <= pixel_addr + 1; + if (pixel_addr == max_addr) + pixel_addr <= 0; + end + end + end + + always_ff @(posedge clk) + if (in_ready && in_valid) begin + lsw <= msw; + msw <= fb_fifo_out; + half_mask <= mask_fifo_out; + + endofpacket <= pixel_addr == max_addr; + startofpacket <= pixel_addr == 0; + end + +endmodule |
