blob: ced1e278ff42ae0181a5b17774dee4dd1d9d2134 [file] [log] [blame]
/*
* Copyright (c) 2021, Marcos Medeiros
* Licensed under BSD 3-clause.
*/
`include "fixedpt.vh"
module TriRasterEngine #(parameter XLEN=`FIXPT_REAL_BITS - 1)
(
input i_clk,
input i_reset,
input i_draw,
input `FIXPT i_v1_x,
input `FIXPT i_v1_y,
input `FIXPT i_v1_z,
input signed [15:0] i_v1_u,
input signed [15:0] i_v1_v,
input [7:0] i_v1_r,
input [7:0] i_v1_g,
input [7:0] i_v1_b,
input `FIXPT i_v2_x,
input `FIXPT i_v2_y,
input `FIXPT i_v2_z,
input signed [15:0] i_v2_u,
input signed [15:0] i_v2_v,
input [7:0] i_v2_r,
input [7:0] i_v2_g,
input [7:0] i_v2_b,
input `FIXPT i_v3_x,
input `FIXPT i_v3_y,
input `FIXPT i_v3_z,
input signed [15:0] i_v3_u,
input signed [15:0] i_v3_v,
input [7:0] i_v3_r,
input [7:0] i_v3_g,
input [7:0] i_v3_b,
output o_busy,
output reg o_done,
output reg o_write_pixel,
output reg signed [15:0] o_x,
output reg signed [15:0] o_y,
output reg [7:0] o_color_r,
output reg [7:0] o_color_g,
output reg [7:0] o_color_b
);
localparam ST_IDLE = 0;
localparam ST_DRAWING = 1;
localparam ST_CLIP_0 = 2;
localparam ST_CLIP_1 = 3;
localparam ST_CLIP_3 = 4;
localparam TILE_X = 0;
localparam TILE_Y = 0;
localparam TILE_W = 320;
localparam TILE_H = 240;
reg `FIXPT v1_x;
reg `FIXPT v1_y;
reg `FIXPT v1_z;
reg `FIXPT v1_u;
reg `FIXPT v1_v;
reg signed [7:0] v1_r;
reg signed [7:0] v1_g;
reg signed [7:0] v1_b;
reg `FIXPT v2_x;
reg `FIXPT v2_y;
reg `FIXPT v2_z;
reg `FIXPT v2_u;
reg `FIXPT v2_v;
reg signed [7:0] v2_r;
reg signed [7:0] v2_g;
reg signed [7:0] v2_b;
reg `FIXPT v3_x;
reg `FIXPT v3_y;
reg `FIXPT v3_z;
reg `FIXPT v3_u;
reg `FIXPT v3_v;
reg signed [7:0] v3_r;
reg signed [7:0] v3_g;
reg signed [7:0] v3_b;
reg signed [15:0] x_min;
reg signed [15:0] x_max;
reg signed [15:0] y_min;
reg signed [15:0] y_max;
reg req_next_pixel;
initial begin
v1_x <= 0; v1_y <= 0; v1_z <= 0; v1_u <= 0; v1_v <= 0; v1_r <= 0; v1_g <= 0; v1_b <= 0;
v2_x <= 0; v2_y <= 0; v2_z <= 0; v2_u <= 0; v2_v <= 0; v2_r <= 0; v2_g <= 0; v2_b <= 0;
v3_x <= 0; v3_y <= 0; v3_z <= 0; v3_u <= 0; v3_v <= 0; v3_r <= 0; v3_g <= 0; v3_b <= 0;
x_min <= 0; x_max <= 0;
y_min <= 0; y_max <= 0;
end
reg [2:0] state = 0;
assign o_busy = state != ST_IDLE;
wire bounding_box_end;
wire signed [15:0] x_pos;
wire signed [15:0] y_pos;
reg signed [15:0] x_pixel;
reg signed [15:0] y_pixel;
wire `FIXPT vp_x = `FIXPT_INT(x_pixel);
wire `FIXPT vp_y = `FIXPT_INT(y_pixel);
reg wr_bounding_box = 0;
BoundingBoxIterator bbox_iterator(
.i_clk (i_clk),
.i_reset (i_reset),
.i_enable (req_next_pixel),
.i_write (wr_bounding_box),
.i_bbx0 (x_min),
.i_bbx1 (x_max),
.i_bby0 (y_min),
.i_bby1 (y_max),
.o_done (bounding_box_end),
.o_x (x_pos),
.o_y (y_pos)
);
always @(posedge i_clk)
begin
if (i_reset)
begin
v1_x <= 0; v1_y <= 0; v1_z <= 0;
v1_r <= 0; v1_g <= 0; v1_b <= 0;
v2_x <= 0; v2_y <= 0; v2_z <= 0;
v2_r <= 0; v2_g <= 0; v2_b <= 0;
v3_x <= 0; v3_y <= 0; v3_z <= 0;
v3_r <= 0; v3_g <= 0; v3_b <= 0;
req_next_pixel <= 0;
state <= ST_IDLE;
end
else
begin
case (state)
ST_IDLE: begin
if (i_draw)
begin
o_done <= 0;
// Latch inputs...
v1_x <= i_v1_x; v1_y <= i_v1_y; v1_z <= i_v1_z;
v1_r <= i_v1_r; v1_g <= i_v1_g; v1_b <= i_v1_b;
v2_x <= i_v2_x; v2_y <= i_v2_y; v2_z <= i_v2_z;
v2_r <= i_v2_r; v2_g <= i_v2_g; v2_b <= i_v2_b;
v3_x <= i_v3_x; v3_y <= i_v3_y; v3_z <= i_v3_z;
v3_r <= i_v3_r; v3_g <= i_v3_g; v3_b <= i_v3_b;
state <= ST_CLIP_0;
end
end
ST_CLIP_0: begin
x_min <= `MIN(`MIN(`FIXPT_TO_INT(v1_x), `FIXPT_TO_INT(v2_x)), `FIXPT_TO_INT(v3_x));
y_min <= `MIN(`MIN(`FIXPT_TO_INT(v1_y), `FIXPT_TO_INT(v2_y)), `FIXPT_TO_INT(v3_y));
x_max <= `MAX(`MAX(`FIXPT_TO_INT(v1_x), `FIXPT_TO_INT(v2_x)), `FIXPT_TO_INT(v3_x));
y_max <= `MAX(`MAX(`FIXPT_TO_INT(v1_y), `FIXPT_TO_INT(v2_y)), `FIXPT_TO_INT(v3_y));
state <= ST_CLIP_1;
end
ST_CLIP_1: begin
x_min <= `MAX(TILE_X, x_min);
y_min <= `MAX(TILE_Y, y_min);
x_max <= `MIN(TILE_W, x_max);
y_max <= `MIN(TILE_H, y_max);
wr_bounding_box <= 1;
state <= ST_CLIP_3;
end
ST_CLIP_3: begin
wr_bounding_box <= 0;
state <= ST_DRAWING;
end
ST_DRAWING: begin
if (bounding_box_end)
begin
state <= ST_IDLE;
o_done <= 1;
req_next_pixel <= 0;
end
else
begin
req_next_pixel <= 1;
x_pixel <= x_pos;
y_pixel <= y_pos;
end
end
default: state <= ST_IDLE;
endcase
end
end
wire `FIXPT area;
wire `FIXPT e1;
wire `FIXPT e2;
wire `FIXPT e3;
wire e1_inside;
wire e2_inside;
wire e3_inside;
wire signed [15:0] edge_x_pos;
wire signed [15:0] edge_y_pos;
wire edge_pixel_enable;
EdgeFunctionEvaluator edge_evaluator(
.i_clk (i_clk),
.i_write_enable (req_next_pixel),
.i_x_pos (x_pixel),
.i_y_pos (y_pixel),
.i_vp_x (vp_x),
.i_vp_y (vp_y),
.i_v1_x (v1_x),
.i_v1_y (v1_y),
.i_v2_x (v2_x),
.i_v2_y (v2_y),
.i_v3_x (v3_x),
.i_v3_y (v3_y),
.o_x_pos (edge_x_pos),
.o_y_pos (edge_y_pos),
.o_area (area),
.o_e1 (e1),
.o_e2 (e2),
.o_e3 (e3),
.o_write_pixel (edge_pixel_enable)
);
wire ex1_write_enable;
wire signed [15:0] ex1_x;
wire signed [15:0] ex1_y;
wire `FIXPT ex1_w1;
wire `FIXPT ex1_w2;
wire `FIXPT ex1_w3;
wire [7:0] ex1_v1_r;
wire [7:0] ex1_v1_g;
wire [7:0] ex1_v1_b;
wire [7:0] ex1_v2_r;
wire [7:0] ex1_v2_g;
wire [7:0] ex1_v2_b;
wire [7:0] ex1_v3_r;
wire [7:0] ex1_v3_g;
wire [7:0] ex1_v3_b;
RasterPipelineEX1 raster_pipe_ex1(
.i_clk (i_clk),
.i_write_enable (edge_pixel_enable),
.i_x_pos (edge_x_pos),
.i_y_pos (edge_y_pos),
.i_area (area),
.i_e1 (e1),
.i_e2 (e2),
.i_e3 (e3),
.i_v1_r (v1_r),
.i_v1_g (v1_g),
.i_v1_b (v1_b),
.i_v2_r (v2_r),
.i_v2_g (v2_g),
.i_v2_b (v2_b),
.i_v3_r (v3_r),
.i_v3_g (v3_g),
.i_v3_b (v3_b),
.o_write_pixel (ex1_write_enable),
.o_x (ex1_x),
.o_y (ex1_y),
.o_w1 (ex1_w1),
.o_w2 (ex1_w2),
.o_w3 (ex1_w3),
.o_v1_r (ex1_v1_r),
.o_v1_g (ex1_v1_g),
.o_v1_b (ex1_v1_b),
.o_v2_r (ex1_v2_r),
.o_v2_g (ex1_v2_g),
.o_v2_b (ex1_v2_b),
.o_v3_r (ex1_v3_r),
.o_v3_g (ex1_v3_g),
.o_v3_b (ex1_v3_b)
);
wire ex2_write_pixel;
wire [7:0] ex2_r;
wire [7:0] ex2_g;
wire [7:0] ex2_b;
wire signed [15:0] ex2_x;
wire signed [15:0] ex2_y;
wire `FIXPT ex2_v1_u;
wire `FIXPT ex2_v1_v;
wire `FIXPT ex2_v2_u;
wire `FIXPT ex2_v2_v;
wire `FIXPT ex2_v3_u;
wire `FIXPT ex2_v3_v;
wire `FIXPT ex2_w1;
wire `FIXPT ex2_w2;
wire `FIXPT ex2_w3;
RasterPipelineEX2 raster_pipe_ex2(
.i_clk (i_clk),
.i_write_enable (ex1_write_enable),
.i_x_pos (ex1_x),
.i_y_pos (ex1_y),
.i_w1 (ex1_w1),
.i_w2 (ex1_w2),
.i_w3 (ex1_w3),
.i_v1_r (ex1_v1_r),
.i_v1_g (ex1_v1_g),
.i_v1_b (ex1_v1_b),
.i_v2_r (ex1_v2_r),
.i_v2_g (ex1_v2_g),
.i_v2_b (ex1_v2_b),
.i_v3_r (ex1_v3_r),
.i_v3_g (ex1_v3_g),
.i_v3_b (ex1_v3_b),
.o_write_pixel (ex2_write_pixel),
.o_x (ex2_x),
.o_y (ex2_y),
.o_r (ex2_r),
.o_g (ex2_g),
.o_b (ex2_b)
);
wire ex3_write_pixel;
wire [7:0] ex3_r;
wire [7:0] ex3_g;
wire [7:0] ex3_b;
wire signed [15:0] ex3_x;
wire signed [15:0] ex3_y;
always @(posedge i_clk) begin
o_write_pixel <= ex3_write_pixel;
if (ex3_write_pixel)
begin
o_color_r <= ex3_r;
o_color_g <= ex3_g;
o_color_b <= ex3_b;
o_x <= ex3_x;
o_y <= ex3_y;
//$display("%d,%d,%d,%d,%d", ex3_y,ex3_x,ex3_r,ex3_g,ex3_b);
end
end
RasterPipelineEX3 raster_pipe_ex3(
.i_clk (i_clk),
.i_write_enable (ex2_write_pixel),
.i_x_pos (ex2_x),
.i_y_pos (ex2_y),
.i_r (ex2_r),
.i_g (ex2_g),
.i_b (ex2_b),
.o_write_pixel (ex3_write_pixel),
.o_x (ex3_x),
.o_y (ex3_y),
.o_r (ex3_r),
.o_g (ex3_g),
.o_b (ex3_b)
);
endmodule