// gpuv2.v // This file was auto-generated as a prototype implementation of a module // created in component editor. It ties off all outputs to ground and // ignores all inputs. It needs to be edited to make it do something // useful. // // This file will not be automatically regenerated. You should check it in // to your version control system if you want to keep it. `timescale 1 ps / 1 ps module gpuv2 #( parameter AUTO_CLOCK_CLOCK_RATE = "-1" ) ( input wire clk, // clock.clk input wire rst_n, // reset.reset_n input wire vga_clk, // vga_out.export output reg [2: 0] vga_red, // .export output reg [2: 0] vga_green, // .export output reg [2: 0] vga_blue, // .export output reg vga_hs, // .export output reg vga_vs, // .export input wire [31: 0] data, // avalon_slave.writedata input wire wr_n, // .write_n input wire cs_n, // .chipselect_n input wire [6: 0] address // .address ); localparam [4: 0] GPU_REG_BLANK = 4'h0, GPU_REG_SPRITE_X = 4'h1, GPU_REG_SPRITE_Y = 4'h2, GPU_REG_BAT0_Y = 4'h3, GPU_REG_BAT1_Y = 4'h4, GPU_REG_SPRITE_COLOUR = 4'h5, GPU_REG_SPRITE_BASE = 4'h10; /* // 640x480 60Hz 25MHz localparam [13: 0] GPU_ZERO = 14'd0, GPU_H_ACTIVE = 14'd640, GPU_H_SYNC_START = 14'd656, GPU_H_SYNC_END = 14'd752, GPU_H_TOTAL = 14'd799, GPU_V_ACTIVE = 14'd480, GPU_V_SYNC_START = 14'd490, GPU_V_SYNC_END = 14'd492, GPU_V_TOTAL = 14'd524; reg pixel_clk; always @ (posedge vga_clk) begin if (!rst_n) pixel_clk <= 1'b0; else pixel_clk <= ~pixel_clk; end */ // 800x600 75Hz 49.5MHz localparam [13: 0] GPU_ZERO = 14'd0, GPU_H_ACTIVE = 14'd800, GPU_H_SYNC_START = 14'd816, GPU_H_SYNC_END = 14'd896, GPU_H_TOTAL = 14'd1055, GPU_V_ACTIVE = 14'd600, GPU_V_SYNC_START = 14'd601, GPU_V_SYNC_END = 14'd604, GPU_V_TOTAL = 14'd625; wire pixel_clk=vga_clk; localparam [13: 0] GPU_OFFSET=14'h80, BAT_WIDTH=14'd4, NET_WIDTH=14'd4; reg blanking; reg [13: 0] sprite_x, sprite_y, bat0_y, bat1_y; reg [2: 0] sprite_red, sprite_green, sprite_blue; reg [15: 0] sprite[0: 15]; assign reg_addr = address[6: 2]; wire [4: 0] reg_addr; always @(posedge clk or negedge rst_n) begin if (rst_n == 0) begin blanking <= 1; sprite_x <= GPU_ZERO; sprite_y <= GPU_ZERO; bat0_y <= GPU_ZERO; bat1_y <= GPU_ZERO; sprite[0] = 16'b1111111111111111; sprite[1] = 16'b1000000000000001; sprite[2] = 16'b1000000000000001; sprite[3] = 16'b1000000000000001; sprite[4] = 16'b1000000000000001; sprite[5] = 16'b1000000000000001; sprite[6] = 16'b1000000000000001; sprite[7] = 16'b1000000000000001; sprite[8] = 16'b1000000000000001; sprite[9] = 16'b1000000000000001; sprite[10] = 16'b1000000000000001; sprite[11] = 16'b1000000000000001; sprite[12] = 16'b1000000000000001; sprite[13] = 16'b1000000000000001; sprite[14] = 16'b1000000000000001; sprite[15] = 16'b1111111111111111; sprite_red[2: 0] = 3'b111; sprite_green[2: 0] = 3'b000; sprite_blue[2: 0] = 3'b111; end else if (~cs_n && ~wr_n) begin if (reg_addr[4]) begin sprite[reg_addr[3: 0]] <= data[15: 0]; end else begin case (reg_addr[4: 0]) GPU_REG_BLANK: blanking <= data[0]; GPU_REG_SPRITE_X: sprite_x <= data[13: 0]; GPU_REG_SPRITE_Y: sprite_y <= data[13: 0]; GPU_REG_BAT0_Y: bat0_y <= data[13: 0]; GPU_REG_BAT1_Y: bat1_y <= data[13: 0]; GPU_REG_SPRITE_COLOUR: begin sprite_red <= data[8: 6]; sprite_green <= data[5: 3]; sprite_blue <= data[2: 0]; end endcase end end end reg [13: 0] vector_x; always @ (posedge pixel_clk or negedge rst_n) begin if (!rst_n) vector_x <= GPU_OFFSET; else begin if (vector_x != (GPU_H_TOTAL + GPU_OFFSET)) vector_x <= vector_x + 1'b1; else vector_x <= GPU_OFFSET; end end reg [13: 0] vector_y; always @ (posedge pixel_clk or negedge rst_n) begin if (!rst_n) vector_y <= GPU_OFFSET; else begin if (vector_x == (GPU_H_TOTAL + GPU_OFFSET )) begin if (vector_y != (GPU_V_TOTAL + GPU_OFFSET)) vector_y <= vector_y + 1'b1; else vector_y <= GPU_OFFSET; end end end always @ (posedge pixel_clk or negedge rst_n) begin if (!rst_n) vga_hs <= 1'b0; else begin if (vector_x >= (GPU_H_SYNC_START + GPU_OFFSET) && vector_x < (GPU_H_SYNC_END + GPU_OFFSET)) vga_hs <= 1'b0; else vga_hs <= 1'b1; end end always @ (posedge pixel_clk or negedge rst_n) begin if (!rst_n) vga_vs <= 1'b0; else begin if (vector_y >= (GPU_V_SYNC_START + GPU_OFFSET) && vector_y < (GPU_V_SYNC_END + GPU_OFFSET)) vga_vs <= 1'b0; else vga_vs <= 1'b1; end end reg px_blank; always @ (posedge pixel_clk or negedge rst_n) begin if (!rst_n) px_blank <= 1; else begin if (vector_x >= GPU_OFFSET && vector_x < (GPU_H_ACTIVE + GPU_OFFSET) && vector_y >= GPU_OFFSET && vector_y < (GPU_V_ACTIVE + GPU_OFFSET)) px_blank <= blanking; else px_blank <= 1; end end reg px_bat; always @ (posedge pixel_clk or negedge rst_n) begin if (!rst_n) begin px_bat <= 0; end else begin if (vector_x < (BAT_WIDTH + GPU_OFFSET) && vector_y >= ( bat0_y - 20 ) && vector_y <= (bat0_y + 20) ) px_bat <= 1; else if (vector_x >= (GPU_OFFSET + GPU_H_ACTIVE - BAT_WIDTH) && vector_y >= ( bat1_y - 20 ) && vector_y <= (bat1_y + 20) ) px_bat <= 1 ; else px_bat <= 0; end end reg px_net; always @ (posedge pixel_clk or negedge rst_n) begin if (!rst_n) px_net <= 0; else begin if (vector_x >= (GPU_OFFSET + ( (GPU_H_ACTIVE - NET_WIDTH) / 2) ) && vector_x < ( GPU_OFFSET + ((GPU_H_ACTIVE + NET_WIDTH) / 2))) px_net <= {3{vector_y[3]}}; else px_net <= 0; end end reg px_sprite; always @ (posedge pixel_clk or negedge rst_n) begin if (!rst_n) px_sprite <= 0; else begin if (vector_x >= (sprite_x - 8 ) && vector_x <= ( sprite_x + 7 ) && vector_y >= (sprite_y - 8) && vector_y <= (sprite_y + 7)) px_sprite <= sprite[(vector_y - (sprite_y - 8)) & 15 ][(vector_x - (sprite_x - 8)) & 15 ]; else px_sprite <= 0; end end always begin if (px_blank) begin vga_red = 3'b000; vga_green = 3'b000; vga_blue = 3'b000; end else if (px_bat) begin vga_red = 3'b111; vga_green = 3'b111; vga_blue = 3'b111; end else if (px_sprite) begin vga_red = sprite_red; vga_green = sprite_green; vga_blue = sprite_blue; end else if (px_net) begin vga_red = 3'b111; vga_green = 3'b111; vga_blue = 3'b111; end else begin vga_red = 3'b000; vga_green = 3'b000; vga_blue = 3'b000; end end endmodule