📄 graphics_pipeline.v
字号:
// TOP LEVEL MODULE
module graphics_pipeline
(
//////////////////// Clock Input ////////////////////
CLOCK_27, // 27 MHz
TD_RESET, // TD Reset, used for allowing 27 MHz CLK
CLOCK_50, // 50 MHz
//////////////////// Push Button ////////////////////
KEY, // Pushbutton[3:0]
//////////////////// DPDT Switch ////////////////////
SW, // Toggle Switch[17:0]
//////////////////////// LED ////////////////////////
LEDG, // LED Green[8:0]
LEDR, // LED Red[17:0]
//////////////////// SRAM Interface ////////////////
SRAM_DQ, // SRAM Data bus 16 Bits
SRAM_ADDR, // SRAM Address bus 18 Bits
SRAM_UB_N, // SRAM High-byte Data Mask
SRAM_LB_N, // SRAM Low-byte Data Mask
SRAM_WE_N, // SRAM Write Enable
SRAM_CE_N, // SRAM Chip Enable
SRAM_OE_N, // SRAM Output Enable
//////////////////// VGA ////////////////////////////
VGA_CLK, // VGA Clock
VGA_HS, // VGA H_SYNC
VGA_VS, // VGA V_SYNC
VGA_BLANK, // VGA BLANK
VGA_SYNC, // VGA SYNC
VGA_R, // VGA Red[9:0]
VGA_G, // VGA Green[9:0]
VGA_B // VGA Blue[9:0]
);
//////////////////////// Clock Input ////////////////////////
input CLOCK_27; // 27 MHz
input CLOCK_50; // 50 MHz
//////////////////////// Push Button ////////////////////////
input [3:0] KEY; // Pushbutton[3:0]
//////////////////////// DPDT Switch ////////////////////////
input [17:0] SW; // Toggle Switch[17:0]
//////////////////////////// LED ////////////////////////////
output [8:0] LEDG; // LED Green[8:0]
output [17:0] LEDR; // LED Red[17:0]
//////////////////////// SRAM Interface ////////////////////////
inout [15:0] SRAM_DQ; // SRAM Data bus 16 Bits
output [17:0] SRAM_ADDR; // SRAM Address bus 18 Bits
output SRAM_UB_N; // SRAM High-byte Data Mask
output SRAM_LB_N; // SRAM Low-byte Data Mask
output SRAM_WE_N; // SRAM Write Enable
output SRAM_CE_N; // SRAM Chip Enable
output SRAM_OE_N; // SRAM Output Enable
//////////////////////// VGA ////////////////////////////
output VGA_CLK; // VGA Clock
output VGA_HS; // VGA H_SYNC
output VGA_VS; // VGA V_SYNC
output VGA_BLANK; // VGA BLANK
output VGA_SYNC; // VGA SYNC
output [9:0] VGA_R; // VGA Red[9:0]
output [9:0] VGA_G; // VGA Green[9:0]
output [9:0] VGA_B; // VGA Blue[9:0]
output TD_RESET; // TV Decoder Reset
assign TD_RESET = 1'b1; // Allow 27 MHz input
/// VGA control wires ////////////
wire VGA_CTRL_CLK;
wire DLY_RST;
wire [9:0] mVGA_R;
wire [9:0] mVGA_G;
wire [9:0] mVGA_B;
wire [19:0] mVGA_ADDR; //video memory address
wire [9:0] Coord_X, Coord_Y; //display coods
//// STATE VARIABLES ////////////////
reg [11:0] program_counter;
reg stall;
wire reset;
wire cull;
// stored off ROM values from the face and vertex ROMs
wire [11:0] vertex_index[3];
wire [17:0] normal_vertex1[3];
wire [17:0] normal_vertex2[3];
wire [17:0] normal_vertex3[3];
wire [17:0] normal_out1[3];
wire [17:0] normal_out2[3];
wire [17:0] normal_out3[3];
wire [13:0] color_vertex1;
wire [13:0] color_vertex2;
wire [13:0] color_vertex3;
wire [17:0] vertex1[3];
wire [17:0] vertex2[3];
wire [17:0] vertex3[3];
reg [17:0] vertex1r[3];
reg [17:0] vertex2r[3];
reg [17:0] vertex3r[3];
wire [17:0] vertex1_out[3];
wire [17:0] vertex2_out[3];
wire [17:0] vertex3_out[3];
// constants for alpha, beta, gamma calculations
wire [17:0] f01, f12, f20;
// u,v,w coordinate basis for this camera position
wire [17:0] u[3], v[3], w[3], e[3];
// determinant for inverse of matrix for normal calculations
wire [17:0] det;
// done transforming?
wire mv_done;
//from screen transform
wire [9:0] vertex1_x;
wire [9:0] vertex1_y;
wire [9:0] vertex1_z;
wire [9:0] vertex2_x;
wire [9:0] vertex2_y;
wire [9:0] vertex2_z;
wire [9:0] vertex3_x;
wire [9:0] vertex3_y;
wire [9:0] vertex3_z;
// from raster
wire [9:0] pixel_raster_x;
wire [9:0] pixel_raster_y;
//rasterize, light, and output
wire [9:0] pixel_raster [2];
reg [9:0] pixel_buffer [2];
//barycentric coordinates
wire [17:0] alpha, beta, gamma;
//rasterizer currently outputting a fragment
//that can be written back to the SRAM if closest
wire valid_fragment;
//colors
wire [13:0] color_light;
wire [13:0] color_sram;
//the light
wire [17:0] light[3];
wire [17:0] light_out[3];
assign light[0] = 18'b0;
assign light[1] = 18'b0;
assign light[2] = 18'b010000001100000000;
// position for the camera
reg [2:0] position;
//assign position = 3'b111;
// change the camera angle
reg pushed;
wire changed_position;
assign changed_position = ~KEY[3] | ~KEY[0];
//rasterizer done with this triangle
wire r_done;
//global reset signal for the system//
assign reset = ~KEY[2] | ~KEY[1];
//an assortment of wires and registers to do shading and z-buffer
wire [17:0] floatR1alpha, floatG1alpha, floatB1alpha,
floatR2beta, floatG2beta, floatB2beta,
floatR3gamma, floatG3gamma, floatB3gamma;
reg [17:0] floatR1alpha1, floatG1alpha1, floatB1alpha1,
floatR2beta1, floatG2beta1, floatB2beta1,
floatR3gamma1, floatG3gamma1, floatB3gamma1;
wire [17:0] floatR1, floatG1, floatB1, floatR2, floatG2, floatB2, floatR3, floatG3, floatB3;
wire [17:0] floatRpresum, floatGpresum, floatBpresum, floatRsum, floatGsum, floatBsum;
reg [17:0] floatRpresum1, floatGpresum1, floatBpresum1;
wire [9:0] intRsum, intGsum, intBsum;
reg [17:0] alpha1, beta1, gamma1;
wire [17:0] nl1, nl2, nl3, nla, nlresult, finalR, finalG, finalB;
reg [17:0] nl1r, nl2r, nl3r, nlar, nlresultr;
reg [17:0] floatRsumr, floatGsumr, floatBsumr;
wire [17:0] nv1a, nv2a, nv3a, nv1b, nv2b, nv3b, nv1g, nv2g, nv3g;
reg [17:0] nv1ar, nv2ar, nv3ar, nv1br, nv2br, nv3br, nv1gr, nv2gr, nv3gr;
wire [17:0] nv1, nv2, nv3;
reg [17:0] nv1r, nv2r, nv3r;
wire [17:0] normal1, normal2, normal3;
reg [17:0] normal[3];
reg [3:0] z_state;
reg [6:0] z_value;
reg z_we;
wire [6:0] current_z;
//assign output color from z-buffer or black on reset/////
assign color_sram = ((reset && ~KEY[2]) | changed_position) ? 14'b11111111111111 : (reset && ~KEY[1]) ? 14'b0 : color_light;
// SRAM SETUP ///////////////////////////////////////////////////////////
assign SRAM_ADDR = (stall | reset | changed_position) ? {Coord_X[9:1], Coord_Y[9:1]} : {pixel_buffer[0][8:0], pixel_buffer[1][8:0]};
assign SRAM_UB_N = 0; // hi byte select enabled
assign SRAM_LB_N = 0; // lo byte select enabled
assign SRAM_CE_N = 0; // chip is enabled
assign SRAM_OE_N = 0; // output enable is overidden by WE
assign SRAM_WE_N = (!reset & !changed_position) & (stall | z_we); // write enable (active low)
assign SRAM_DQ = (reset | changed_position) | (!(stall | z_we)) ? {(reset | changed_position) ? 2'b10 : z_value[6:5], color_sram} : 16'hzzzz;// drive SRAM with data if WE
/////////////////////////////////////////////////////////////////////////
// VGA COLORS ///////////////////////////
assign mVGA_R = {SRAM_DQ[13:9], 5'b0};
assign mVGA_G = {SRAM_DQ[8:5], 6'b0};
assign mVGA_B = {SRAM_DQ[4:0], 5'b0};
/////////////////////////////////////////
//state machine logic to control stalling pipe for VGA
always @(posedge VGA_CTRL_CLK)
begin
// system reset
if (reset)
begin
program_counter <= 12'b0;
position <= 3'b0;
stall <= 1'b0;
pushed <= 1'b0;
vertex1r[0] <= 18'b0;
vertex1r[1] <= 18'b0;
vertex1r[2] <= 18'b0;
vertex2r[0] <= 18'b0;
vertex2r[1] <= 18'b0;
vertex2r[2] <= 18'b0;
vertex3r[0] <= 18'b0;
vertex3r[1] <= 18'b0;
vertex3r[2] <= 18'b0;
end
// pushed the button to change camera
else if (changed_position)
begin
pushed <= 1'b1;
if (~KEY[3] && ~pushed) position <= position - 3'b001;
else if (~pushed) position <= position + 3'b001;
end
// not syncing
else if ((~VGA_HS | ~VGA_VS))
begin
if (/*cull | */r_done) program_counter <= program_counter + 12'b1;
else program_counter <= program_counter;
stall <= 1'b0;
position <= position;
pushed <= 1'b0;
vertex1r[0] <= vertex1[0];
vertex1r[1] <= vertex1[1];
vertex1r[2] <= vertex1[2];
vertex2r[0] <= vertex2[0];
vertex2r[1] <= vertex2[1];
vertex2r[2] <= vertex2[2];
vertex3r[0] <= vertex3[0];
vertex3r[1] <= vertex3[1];
vertex3r[2] <= vertex3[2];
end
// syncing
else
begin
program_counter <= program_counter;
position <= position;
pushed <= pushed;
stall <= 1'b1;
vertex1r[0] <= vertex1r[0];
vertex1r[1] <= vertex1r[1];
vertex1r[2] <= vertex1r[2];
vertex2r[0] <= vertex2r[0];
vertex2r[1] <= vertex2r[1];
vertex2r[2] <= vertex2r[2];
vertex3r[0] <= vertex3r[0];
vertex3r[1] <= vertex3r[1];
vertex3r[2] <= vertex3r[2];
end
end
///////////////////////////////////////////////////
//declare our pipeline modules here
///////////////////////////////////////////////////
//face and triangle roms//
//stage 1//
Face_ROM f1 (
.address(program_counter),
.position(position),
.constants( {
f12,
f20,
f01
} ),
.triangle_indices({ vertex_index[0],
vertex_index[1],
vertex_index[2]
})
);
Vertex_ROM v1 (
.vertex_index_0(vertex_index[0]),
.vertex_index_1(vertex_index[1]),
.vertex_index_2(vertex_index[2]),
.vertex1( {vertex1_out[0],
vertex1_out[1],
vertex1_out[2]} ),
.vertex2( {vertex2_out[0],
vertex2_out[1],
vertex2_out[2]} ),
.vertex3( {vertex3_out[0],
vertex3_out[1],
vertex3_out[2]} ),
.color1(color_vertex1),
.color2(color_vertex2),
.color3(color_vertex3),
.normal1({normal_vertex1[0], normal_vertex1[1], normal_vertex1[2]}),
.normal2({normal_vertex2[0], normal_vertex2[1], normal_vertex2[2]}),
.normal3({normal_vertex3[0], normal_vertex3[1], normal_vertex3[2]})
);
//transform/raster
//stage 2
// light
calcMv mvlight1 (
.clk(VGA_CTRL_CLK),
.reset(reset | changed_position | r_done),
.xu(u[0]),
.yu(u[1]),
.zu(u[2]),
.xv(v[0]),
.yv(v[1]),
.zv(v[2]),
.xw(w[0]),
.yw(w[1]),
.zw(w[2]),
.xe(e[0]),
.ye(e[1]),
.ze(e[2]),
.x(light[0]),
.y(light[1]),
.z(light[2]),
.Out0(light_out[0]),
.Out1(light_out[1]),
.Out2(light_out[2]),
//.det(det)
);
// normal 1
calcMvNormal mvnormal1 (
.clk(VGA_CTRL_CLK),
.reset(reset | changed_position | r_done),
.xu(u[0]),
.yu(u[1]),
.zu(u[2]),
.xv(v[0]),
.yv(v[1]),
.zv(v[2]),
.xw(w[0]),
.yw(w[1]),
.zw(w[2]),
.x(normal_vertex1[0]),
.y(normal_vertex1[1]),
.z(normal_vertex1[2]),
.Out0(normal_out1[0]),
.Out1(normal_out1[1]),
.Out2(normal_out1[2]),
.done(mv_done),
.det(det)
);
// normal 2
calcMvNormal mvnormal2 (
.clk(VGA_CTRL_CLK),
.reset(reset | changed_position | r_done),
.xu(u[0]),
.yu(u[1]),
.zu(u[2]),
.xv(v[0]),
.yv(v[1]),
.zv(v[2]),
.xw(w[0]),
.yw(w[1]),
.zw(w[2]),
.x(normal_vertex2[0]),
.y(normal_vertex2[1]),
.z(normal_vertex2[2]),
.Out0(normal_out2[0]),
.Out1(normal_out2[1]),
.Out2(normal_out2[2]),
.det(det)
);
// normal 3
calcMvNormal mvnormal3 (
.clk(VGA_CTRL_CLK),
.reset(reset | changed_position | r_done),
.xu(u[0]),
.yu(u[1]),
.zu(u[2]),
.xv(v[0]),
.yv(v[1]),
.zv(v[2]),
.xw(w[0]),
.yw(w[1]),
.zw(w[2]),
.x(normal_vertex3[0]),
.y(normal_vertex3[1]),
.z(normal_vertex3[2]),
.Out0(normal_out3[0]),
.Out1(normal_out3[1]),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -