📄 rasterizer.v
字号:
/*
Computes barycentric coordinates for each pixel and determines if for each pixel within the bounding box
it is within a triangle.
*/
module Rasterizer(
clk,
reset,
x1,
y1,
x2,
y2,
x3,
y3,
pixelOut,
out_pixel_x,
out_pixel_y,
stall,
done,
f12,
f23,
f31,
alpha,
beta,
gamma
);
input clk;
input reset;
input stall;
input wire signed [8:0] x1, x2, x3, y1, y2, y3;
input wire [17:0] f12, f23, f31;
output wire [17:0] alpha, beta, gamma;
fpmult fu1(alpha, sfp22r, f23);
fpmult fu2(beta, sfp33r, f31);
fpmult fu3(gamma, sfp11r, f12);
output wire pixelOut;
//pixel has a value if alpha,beta,gamma are greater than or equal to 0.
assign pixelOut = (
(state == 5'd4) &&
((alpha[17] == 1'b0) || (alpha[8:0] == 9'b0)) &&
((beta[17] == 1'b0) || (beta[8:0] == 9'b0)) &&
((gamma[17] == 1'b0) || (gamma[8:0] == 9'b0))
);
reg [17:0] sfp22r, sfp11r, sfp33r;
output [9:0] out_pixel_x;
output [9:0] out_pixel_y;
reg [4:0] state;
output reg done;
reg signed [17:0] c1, c2, c3;
reg [8:0] i,j;
reg signed [17:0] p1, p2, p3;
parameter exit = 5'd15;
wire signed [17:0] wire1, wire2, wire3, wire4, wire5, wire6, wire7, wire8,
wire9, wire10, wire11, wire12;
wire signed [17:0] sub1, sub2, sub3, sub4, sub5, sub6;
wire [8:0] xmin, ymin, xmax, ymax;
//determine bounding box
assign xmin = (x1 <= x2 & x1 <= x3) ? x1 : (x2 <= x1 & x2 <= x3) ? x2 : x3;
assign ymin = (y1 <= y2 & y1 <= y3) ? y1 : (y2 <= y1 & y2 <= y3) ? y2 : y3;
assign xmax = (x1 >= x2 & x1 >= x3) ? x1 : (x2 >= x1 & x2 >= x3) ? x2 : x3;
assign ymax = (y1 >= y2 & y1 >= y3) ? y1 : (y2 >= y1 & y2 >= y3) ? y2 : y3;
wire signed [9:0] dy1, dy2, dy3, dx1, dx2, dx3;
wire signed [9:0] x1norm, x2norm, x3norm, y1norm, y2norm, y3norm, inorm, jnorm;
//assign variables that will be used
assign dy1 = y1norm - y2norm; //used for system of equations
assign dy2 = y2norm - y3norm; //to determine alpha, beta, gamma
assign dy3 = y3norm - y1norm;
assign dx1 = x2norm - x1norm;
assign dx2 = x3norm - x2norm;
assign dx3 = x1norm - x3norm;
assign x1norm = x1 - xmin; //normalizing vertices and pixel coordinates
assign x2norm = x2 - xmin; //to bounding box
assign x3norm = x3 - xmin;
assign y1norm = y1 - ymin;
assign y2norm = y2 - ymin;
assign y3norm = y3 - ymin;
assign inorm = i - xmin;
assign jnorm = j - ymin;
wire [17:0] fpx1, fpx2, fpx3, fpy1, fpy2, fpy3, fpi, fpj, fpdy1, fpdy2, fpdy3, fpdx1, fpdx2, fpdx3;
//convert to floating point
int2fp inst1( .fp_out(fpx1), .int_in(x1norm), .scale_in(8'b0) );
int2fp inst2( .fp_out(fpx2), .int_in(x2norm), .scale_in(8'b0) );
int2fp inst3( .fp_out(fpx3), .int_in(x3norm), .scale_in(8'b0) );
int2fp inst4( .fp_out(fpy1), .int_in(y1norm), .scale_in(8'b0) );
int2fp inst5( .fp_out(fpy2), .int_in(y2norm), .scale_in(8'b0) );
int2fp inst6( .fp_out(fpy3), .int_in(y3norm), .scale_in(8'b0) );
int2fp inst7( .fp_out(fpi), .int_in(inorm), .scale_in(8'b0) );
int2fp inst8( .fp_out(fpj), .int_in(jnorm), .scale_in(8'b0) );
int2fp inst9( .fp_out(fpdy1), .int_in(dy1), .scale_in(8'b0) );
int2fp insta( .fp_out(fpdy2), .int_in(dy2), .scale_in(8'b0) );
int2fp instb( .fp_out(fpdy3), .int_in(dy3), .scale_in(8'b0) );
int2fp instc( .fp_out(fpdx1), .int_in(dx1), .scale_in(8'b0) );
int2fp instd( .fp_out(fpdx2), .int_in(dx2), .scale_in(8'b0) );
int2fp inste( .fp_out(fpdx3), .int_in(dx3), .scale_in(8'b0) );
wire [17:0] mult1, mult2, mult3, mult4, mult5, mult6, mult7, mult8, mult9, multa, multb, multc;
wire [17:0] sfp1, sfp2, sfp3, sfp4, sfp5, sfp6;
//compute components of each equation
fpmult instf2( .fout(mult1), .f1(fpx1), .f2(fpy2) ); //x1*y2
fpmult instf3( .fout(mult2), .f1(fpx2), .f2(fpy3) ); //x2*y3
fpmult instf4( .fout(mult3), .f1(fpx3), .f2(fpy1) ); //x3*y1
fpmult instf5( .fout(mult4), .f1(fpi), .f2(fpdy1) ); //(y1-y2)*i
fpmult instf6( .fout(mult5), .f1(fpi), .f2(fpdy2) ); //(y2-y3)*i
fpmult instf7( .fout(mult6), .f1(fpi), .f2(fpdy3) ); //(y3-y1)*i
fpmult instf8( .fout(mult7), .f1(fpy1), .f2(fpx2) ); //x2*y1
fpmult instf9( .fout(mult8), .f1(fpy2), .f2(fpx3) ); //x3*y2
fpmult instfa( .fout(mult9), .f1(fpy3), .f2(fpx1) ); //x1*y3
fpmult instfb( .fout(multa), .f1(fpj), .f2(fpdx1) ); //(x2-x1)*j
fpmult instfc( .fout(multb), .f1(fpj), .f2(fpdx2) ); //(x3-x2)*j
fpmult instfd( .fout(multc), .f1(fpj), .f2(fpdx3) ); //(x1-x3)*j
//in next cycle start adding components of equation together
fpadd insta1( .fout(sfp1), .f1(d1), .f2({1'b1,d7[16:0]})); //x1*y2 - x2*y1
fpadd insta2( .fout(sfp2), .f1(d2), .f2({1'b1,d8[16:0]})); //x2*y3 - x3*y2
fpadd insta3( .fout(sfp3), .f1(d3), .f2({1'b1,d9[16:0]})); //x3*y1 - x1*y3
fpadd insta4( .fout(sfp4), .f1(d10), .f2(d4)); //dy1*i + dx1*j
fpadd insta5( .fout(sfp5), .f1(d11), .f2(d5)); //dy2*i + dx2*j
fpadd insta6( .fout(sfp6), .f1(d12), .f2(d6)); //dy3*i + dx3*j
reg [17:0] d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12;
reg [17:0] e1, e2, e3, e4,e5,e6;
wire [17:0] sfp11, sfp22, sfp33;
//add remaining components of equation together
fpadd c1p1(.fout(sfp11), .f1(e1), .f2(e4));
fpadd c2p2(.fout(sfp22), .f1(e2), .f2(e5));
fpadd c3p3(.fout(sfp33), .f1(e3), .f2(e6));
assign out_pixel_x = i;
assign out_pixel_y = 240 - j;
/* Note: vertice inputs are normalized to bounding box based upon x,y min,max; where (0,0) is
bottom left corner*/
always@(posedge clk) begin
if(reset) begin //reset registers and state machine
state <= 5'd9;
i <= xmin;
j <= ymin;
done <= 1'b0;
c1 <= 18'b0;
c2 <= 18'b0;
c3 <= 18'b0;
p1 <= 18'b0;
p2 <= 18'b0;
p3 <= 18'b0;
d1 <= 18'b0;
d2 <= 18'b0;
d3 <= 18'b0;
d4 <= 18'b0;
d5 <= 18'b0;
d6 <= 18'b0;
d7 <= 18'b0;
d8 <= 18'b0;
d9 <= 18'b0;
d10 <= 18'b0;
d11 <= 18'b0; d12 <= 18'b0;
e1 <= 18'b0;
e2 <= 18'b0;
e3 <= 18'b0;
e4 <= 18'b0;
e5 <= 18'b0;
e6 <= 18'b0;
end
else if (stall) begin //keep values constant
i <= i;
j <= j;
c1 <= c1; c2 <= c2; c3 <= c3;
p1 <= p1; p2 <= p2; p3 <= p3;
d1 <= d1; d2 <= d2; d3 <= d3; d4 <= d4; d5 <= d5; d6 <= d6; d7 <= d7;
d8 <= d8; d9 <= d9; d10 <= d10; d11 <= d11; d12 <= d12;
e1 <= e1; e2 <= e2; e3 <= e3; e4 <= e4; e5 <= e5; e6 <= e6;
state <= state;
done <= done;
end
else begin
/* Go through each pixel and compare to the three equations */
case(state)
9:
begin
state <= 5'd11;
end
11: begin
state <= 5'd0;
end
0: //reset variables
begin
i <= xmin;
j <= ymin;
c1 <= 18'b0;
c2 <= 18'b0;
c3 <= 18'b0;
p1 <= 18'b0;
p2 <= 18'b0;
p3 <= 18'b0;
d1 <= 18'b0;
d2 <= 18'b0;
d3 <= 18'b0;
d4 <= 18'b0;
d5 <= 18'b0;
d6 <= 18'b0;
d7 <= 18'b0;
d8 <= 18'b0;
d9 <= 18'b0;
d10 <= 18'b0;
d11 <= 18'b0;
d12 <= 18'b0;
e1 <= 18'b0;
e2 <= 18'b0;
e3 <= 18'b0;
e4 <= 18'b0;
e5 <= 18'b0;
e6 <= 18'b0;
done <= 1'b0;
state <= 5'd1;
end
1: //store 1st set of computations
begin
d1 <= mult1;
d2 <= mult2;
d3 <= mult3;
d4 <= mult4;
d5 <= mult5;
d6 <= mult6;
d7 <= mult7;
d8 <= mult8;
d9 <= mult9;
d10 <= multa;
d11 <= multb;
d12 <= multc;
state <= 5'd2;
end
2: //store 2nd set of computations
begin
e1 <= sfp1;
e2 <= sfp2;
e3 <= sfp3;
e4 <= sfp4;
e5 <= sfp5;
e6 <= sfp6;
state <= 5'd3;
end
3: //store final computations
begin
sfp11r <= sfp11;
sfp22r <= sfp22;
sfp33r <= sfp33;
state <= 5'd4;
end
4: //put in delay to steady values
begin
state <= 5'd5;
end
5:
begin
state <= 5'd6;
end
6:
begin
state <= 5'd8;
end
8: begin state <= 5'd10; end
10: begin state <= 5'd7; end
7:
begin //determine if checked every pixel within the bounding box
if(i == xmax && j == ymax) //go to exit if so
state <= exit;
else begin
if(i < xmax) //update i and/or j otherwise
i <= i + 9'd1;
else begin
j <= j + 9'd1;
i <= xmin;
end
state <= 5'd1;
end
end
exit: //done with bounding box
begin
done <= 1'b1;
end
endcase
end //else
end //always
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -